diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index cc625f95ff69e..658058d846bb9 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -87,3 +87,6 @@ e2c2ffbe7a1b5d9e32a2ce64279475b50c4cba5b # [lldb][nfc] Deindent ProcessGDBRemote::SetThreadStopInfo by two levels b32931c5b32eb0d2cf37d688b34f8548c9674c19 + +# [libc++][NFC] Fix inconsistent quoting and spacing in our CSV files +64946fdaf9864d8279da1c30e4d7214fe13d1427 diff --git a/.github/workflows/issue-write.yml b/.github/workflows/issue-write.yml index 5e4f3b536d10d..ef0d7e986fda7 100644 --- a/.github/workflows/issue-write.yml +++ b/.github/workflows/issue-write.yml @@ -24,14 +24,21 @@ jobs: github.event.workflow_run.conclusion == 'failure' ) steps: + - name: Fetch Sources + uses: actions/checkout@v4 + with: + sparse-checkout: | + .github/workflows/unprivileged-download-artifact/action.yml + sparse-checkout-cone-mode: false - name: 'Download artifact' - uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1 + uses: ./.github/workflows/unprivileged-download-artifact + id: download-artifact with: - github-token: ${{ secrets.ISSUE_WRITE_DOWNLOAD_ARTIFACT }} run-id: ${{ github.event.workflow_run.id }} - name: workflow-args + artifact-name: workflow-args - name: 'Comment on PR' + if: steps.download-artifact.outputs.artifact-id != '' uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} @@ -144,5 +151,7 @@ jobs: }); - name: Dump comments file - if: always() + if: >- + always() && + steps.download-artifact.outputs.artifact-id != '' run: cat comments diff --git a/.github/workflows/llvm-project-tests.yml b/.github/workflows/llvm-project-tests.yml index 0a228c41f354e..17a54be16badc 100644 --- a/.github/workflows/llvm-project-tests.yml +++ b/.github/workflows/llvm-project-tests.yml @@ -131,6 +131,7 @@ jobs: -DCMAKE_BUILD_TYPE=Release \ -DLLVM_ENABLE_ASSERTIONS=ON \ -DLLDB_INCLUDE_TESTS=OFF \ + -DLIBCLC_TARGETS_TO_BUILD="amdgcn--;amdgcn--amdhsa;r600--;nvptx--;nvptx64--;nvptx--nvidiacl;nvptx64--nvidiacl" \ -DCMAKE_C_COMPILER_LAUNCHER=sccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=sccache \ $extra_cmake_args \ @@ -142,8 +143,6 @@ jobs: env: LLVM_BUILDDIR: ${{ steps.build-llvm.outputs.llvm-builddir }} run: | - # Make sure all of LLVM libraries that llvm-config needs are built. + # The libclc tests don't have a generated check target so all we can + # do is build it. ninja -C "$LLVM_BUILDDIR" - cmake -G Ninja -S libclc -B libclc-build -DLLVM_DIR="$LLVM_BUILDDIR"/lib/cmake/llvm -DLIBCLC_TARGETS_TO_BUILD="amdgcn--;amdgcn--amdhsa;r600--;nvptx--;nvptx64--;nvptx--nvidiacl;nvptx64--nvidiacl" - ninja -C libclc-build - ninja -C libclc-build test diff --git a/.github/workflows/release-asset-audit.py b/.github/workflows/release-asset-audit.py new file mode 100644 index 0000000000000..355e7fee1dae0 --- /dev/null +++ b/.github/workflows/release-asset-audit.py @@ -0,0 +1,51 @@ +import github +import sys + +def main(): + token = sys.argv[1] + + gh = github.Github(login_or_token=token) + repo = gh.get_repo("llvm/llvm-project") + + uploaders = set( + [ + "DimitryAndric", + "stefanp-ibm", + "lei137", + "omjavaid", + "nicolerabjohn", + "amy-kwan", + "mandlebug", + "zmodem", + "androm3da", + "tru", + "rovka", + "rorth", + "quinnlp", + "kamaub", + "abrisco", + "jakeegan", + "maryammo", + "tstellar", + "github-actions[bot]", + ] + ) + + for release in repo.get_releases(): + print("Release:", release.title) + for asset in release.get_assets(): + created_at = asset.created_at + updated_at = ( + "" if asset.created_at == asset.updated_at else asset.updated_at + ) + print( + f"{asset.name} : {asset.uploader.login} [{created_at} {updated_at}] ( {asset.download_count} )" + ) + if asset.uploader.login not in uploaders: + with open('comment', 'w') as file: + file.write(f'@{asset.uploader.login} is not a valid uploader.') + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/.github/workflows/release-asset-audit.yml b/.github/workflows/release-asset-audit.yml new file mode 100644 index 0000000000000..018c5d542f32e --- /dev/null +++ b/.github/workflows/release-asset-audit.yml @@ -0,0 +1,54 @@ +name: Release Asset Audit + +on: + workflow_dispatch: + release: + schedule: + # * is a special character in YAML so you have to quote this string + # Run once an hour + - cron: '5 * * * *' + + pull_request: + paths: + - ".github/workflows/release-asset-audit.py" + - ".github/workflows/release-asset-audit.yml" + +permissions: + contents: read # Default everything to read-only + +jobs: + audit: + name: "Release Asset Audit" + runs-on: ubuntu-22.04 + if: github.repository == 'llvm/llvm-project' + steps: + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 + - name: "Run Audit Script" + env: + GITHUB_TOKEN: ${{ github.token }} + run: | + pip install --require-hashes -r ./llvm/utils/git/requirements.txt + python3 ./.github/workflows/release-asset-audit.py $GITHUB_TOKEN + - name: "File Issue" + if: >- + github.event_name != 'pull_request' && + failure() + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea #v7.0.1 + with: + github-token: ${{ secrets.ISSUE_SUBSCRIBER_TOKEN }} + script: | + var fs = require('fs'); + var body = '' + if (fs.existsSync('./comment')) { + body = fs.readFileSync('./comment') + "\n\n"; + } + body = body + `\n\nhttps://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}` + + const issue = await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: "Release Asset Audit Failed", + labels: ['infrastructure'], + body: body + }); + console.log(issue); diff --git a/.github/workflows/release-binaries-all.yml b/.github/workflows/release-binaries-all.yml new file mode 100644 index 0000000000000..73c9d96946e33 --- /dev/null +++ b/.github/workflows/release-binaries-all.yml @@ -0,0 +1,94 @@ +name: Release Binaries All + +permissions: + contents: read # Default everything to read-only + +on: + workflow_dispatch: + inputs: + release-version: + description: 'Release Version' + required: true + type: string + upload: + description: 'Upload binaries to the release page' + required: true + default: false + type: boolean + + workflow_call: + inputs: + release-version: + description: 'Release Version' + required: true + type: string + upload: + description: 'Upload binaries to the release page' + required: true + default: false + type: boolean + + pull_request: + types: + - opened + - synchronize + - reopened + # When a PR is closed, we still start this workflow, but then skip + # all the jobs, which makes it effectively a no-op. The reason to + # do this is that it allows us to take advantage of concurrency groups + # to cancel in progress CI jobs whenever the PR is closed. + - closed + paths: + - '.github/workflows/release-binaries-all.yml' + - '.github/workflows/release-binaries.yml' + - '.github/workflows/release-binaries-setup-stage/*' + - '.github/workflows/release-binaries-save-stage/*' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || 'dispatch' }} + cancel-in-progress: True + +jobs: + setup-variables: + if: >- + (github.event_name != 'pull_request' || github.event.action != 'closed') + runs-on: ubuntu-22.04 + outputs: + release-version: ${{ steps.vars.outputs.release-version }} + upload: ${{ steps.vars.outputs.upload }} + steps: + - shell: bash + id: vars + run: | + upload="${{ inputs.upload }}" + release_version="${{ inputs.release-version }}" + if [ "${{ github.event_name }}" = "pull_request" ]; then + upload="false" + release_version="" + fi + echo "release-version=$release_version" >> "$GITHUB_OUTPUT" + echo "upload=$upload" >> "$GITHUB_OUTPUT" + + release-binaries-all: + name: Build Release Binaries + needs: + - setup-variables + permissions: + contents: write # For release uploads + id-token: write # For artifact attestations + attestations: write # For artifact attestations + strategy: + fail-fast: false + matrix: + runs-on: + - ubuntu-22.04 + - windows-2022 + - macos-13 + - macos-14 + + uses: ./.github/workflows/release-binaries.yml + with: + release-version: "${{ needs.setup-variables.outputs.release-version }}" + upload: ${{ needs.setup-variables.outputs.upload == 'true'}} + runs-on: "${{ matrix.runs-on }}" + diff --git a/.github/workflows/release-binaries-save-stage/action.yml b/.github/workflows/release-binaries-save-stage/action.yml new file mode 100644 index 0000000000000..e2f3eeadd15be --- /dev/null +++ b/.github/workflows/release-binaries-save-stage/action.yml @@ -0,0 +1,38 @@ +name: Save Stage +description: >- + Upload the source and binary directories from a build stage so that they + can be re-used in the next stage. This action is used to the release + binaries workflow into multiple stages to avoid the 6 hour timeout on + the GitHub hosted runners. +inputs: + build-prefix: + description: "Directory containing the build directory." + required: true + type: 'string' + +runs: + using: "composite" + steps: + # We need to create an archive of the build directory, because it has too + # many files to upload. + - name: Package Build and Source Directories + shell: bash + run: | + # Windows does not support symlinks, so we need to dereference them. + tar --exclude build/ ${{ (runner.os == 'Windows' && '-h') || '' }} -c . | zstd -T0 -c > ../llvm-project.tar.zst + mv ../llvm-project.tar.zst . + tar -C ${{ inputs.build-prefix }} -c build/ | zstd -T0 -c > build.tar.zst + + - name: Upload Stage 1 Source + uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 #v4.3.0 + with: + name: ${{ runner.os }}-${{ runner.arch }}-${{ github.job }}-source + path: llvm-project.tar.zst + retention-days: 2 + + - name: Upload Stage 1 Build Dir + uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 #v4.3.0 + with: + name: ${{ runner.os}}-${{ runner.arch }}-${{ github.job }}-build + path: build.tar.zst + retention-days: 2 diff --git a/.github/workflows/release-binaries-setup-stage/action.yml b/.github/workflows/release-binaries-setup-stage/action.yml new file mode 100644 index 0000000000000..f5e5db27e6595 --- /dev/null +++ b/.github/workflows/release-binaries-setup-stage/action.yml @@ -0,0 +1,59 @@ +name: Setup Stage +description: >- + Setup the next stage of the release binaries workflow. This sets up the + environment correctly for a new stage of the release binaries workflow + and also restores the source and build directory from the previous stage. + +inputs: + previous-artifact: + description: >- + A unique descriptor for the artifact from the previous stage. This will + be used to construct the final artifact pattern, which is: + $RUNNER_OS-$RUNNER_ARCH-$PREVIOUS_ARTIFACT-* + required: false + type: 'string' + +outputs: + build-prefix: + description: "Directory containing the build directory." + value: ${{ steps.build-prefix.outputs.build-prefix }} + +runs: + using: "composite" + steps: + - name: Install Ninja + uses: llvm/actions/install-ninja@22e9f909d35b50bd1181709564bfe816eaeaae81 # main + + - name: Setup Windows + if: startsWith(runner.os, 'Windows') + uses: llvm/actions/setup-windows@main + with: + arch: amd64 + + - name: Set Build Prefix + id: build-prefix + shell: bash + run: | + build_prefix=`pwd` + if [ "${{ runner.os }}" = "Linux" ]; then + sudo chown $USER:$USER /mnt/ + build_prefix=/mnt/ + fi + echo "build-prefix=$build_prefix" >> $GITHUB_OUTPUT + + - name: Download Previous Stage Artifact + if: ${{ inputs.previous-artifact }} + id: download + uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1 + with: + pattern: ${{ runner.os }}-${{ runner.arch }}-${{ inputs.previous-artifact }}-* + merge-multiple: true + + - name: Unpack Artifact + if: ${{ steps.download.outputs.download-path }} + shell: bash + run: | + tar --zstd -xf llvm-project.tar.zst + rm llvm-project.tar.zst + tar --zstd -C ${{ steps.build-prefix.outputs.build-prefix}} -xf build.tar.zst + rm build.tar.zst diff --git a/.github/workflows/release-binaries.yml b/.github/workflows/release-binaries.yml index 7de4d00334d14..b1b046dbad5f8 100644 --- a/.github/workflows/release-binaries.yml +++ b/.github/workflows/release-binaries.yml @@ -5,28 +5,38 @@ on: inputs: release-version: description: 'Release Version' - required: true + required: false type: string upload: description: 'Upload binaries to the release page' required: true default: false type: boolean + runs-on: + description: "Runner to use for the build" + required: true + type: choice + options: + - ubuntu-22.04 + - windows-2022 + - macos-13 + - macos-14 workflow_call: inputs: release-version: description: 'Release Version' - required: true + required: false type: string upload: description: 'Upload binaries to the release page' required: true default: false type: boolean - schedule: - # * is a special character in YAML so you have to quote this string - - cron: '0 8 1 * *' + runs-on: + description: "Runner to use for the build" + required: true + type: string permissions: contents: read # Default everything to read-only @@ -34,30 +44,39 @@ permissions: jobs: prepare: name: Prepare to build binaries - runs-on: ubuntu-22.04 + runs-on: ${{ inputs.runs-on }} if: github.repository == 'llvm/llvm-project' outputs: release-version: ${{ steps.vars.outputs.release-version }} ref: ${{ steps.vars.outputs.ref }} upload: ${{ steps.vars.outputs.upload }} + target-cmake-flags: ${{ steps.vars.outputs.target-cmake-flags }} + build-flang: ${{ steps.vars.outputs.build-flang }} + enable-pgo: ${{ steps.vars.outputs.enable-pgo }} + release-binary-basename: ${{ steps.vars.outputs.release-binary-basename }} + release-binary-filename: ${{ steps.vars.outputs.release-binary-filename }} steps: - name: Checkout LLVM uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Install Dependencies + shell: bash run: | pip install --require-hashes -r ./llvm/utils/git/requirements.txt - name: Check Permissions + if: github.event_name != 'pull_request' env: GITHUB_TOKEN: ${{ github.token }} USER_TOKEN: ${{ secrets.RELEASE_TASKS_USER_TOKEN }} + shell: bash run: | ./llvm/utils/release/./github-upload-release.py --token "$GITHUB_TOKEN" --user ${{ github.actor }} --user-token "$USER_TOKEN" check-permissions - name: Collect Variables id: vars + shell: bash # In order for the test-release.sh script to run correctly, the LLVM # source needs to be at the following location relative to the build dir: # | X.Y.Z-rcN | ./rcN/llvm-project @@ -67,242 +86,393 @@ jobs: # | X.Y.Z-rcN | -rc N -test-asserts # | X.Y.Z | -final run: | - tag="${{ github.ref_name }}" trimmed=$(echo ${{ inputs.release-version }} | xargs) - [[ "$trimmed" != "" ]] && tag="llvmorg-$trimmed" - if [ "$tag" = "main" ]; then - # If tag is main, then we've been triggered by a scheduled so pass so - # use the head commit as the tag. - tag=`git rev-parse HEAD` + if [ -n "$trimmed" ]; then + release_version="$trimmed" + ref="llvmorg-$release_version" + else + release_version="${{ (github.event_name == 'pull_request' && format('PR{0}', github.event.pull_request.number)) || 'CI'}}-${{ github.sha }}" + ref=${{ github.sha }} fi if [ -n "${{ inputs.upload }}" ]; then upload="${{ inputs.upload }}" else upload="false" fi - bash .github/workflows/set-release-binary-outputs.sh "$tag" "$upload" + echo "release-version=$release_version">> $GITHUB_OUTPUT + echo "ref=$ref" >> $GITHUB_OUTPUT + echo "upload=$upload" >> $GITHUB_OUTPUT + + release_binary_basename="LLVM-$release_version-${{ runner.os }}-${{ runner.arch }}" + echo "release-binary-basename=$release_binary_basename" >> $GITHUB_OUTPUT + echo "release-binary-filename=$release_binary_basename.tar.xz" >> $GITHUB_OUTPUT + + # Detect necessary CMake flags + target="${{ runner.os }}-${{ runner.arch }}" + echo "enable-pgo=false" >> $GITHUB_OUTPUT + target_cmake_flags="-DLLVM_RELEASE_ENABLE_PGO=OFF" + # The macOS builds try to cross compile some libraries so we need to + # add extra CMake args to disable them. + # See https://github.com/llvm/llvm-project/issues/99767 + if [ "${{ runner.os }}" = "macOS" ]; then + target_cmake_flags="$target_cmake_flags -DBOOTSTRAP_COMPILER_RT_ENABLE_IOS=OFF" + if [ "${{ runner.arch }}" = "ARM64" ]; then + arches=arm64 + else + arches=x86_64 + fi + target_cmake_flags="$target_cmake_flags -DBOOTSTRAP_DARWIN_osx_ARCHS=$arches -DBOOTSTRAP_DARWIN_osx_BUILTIN_ARCHS=$arches" + fi + + # x86 macOS and x86 Windows have trouble building flang, so disable it. + # Windows: https://github.com/llvm/llvm-project/issues/100202 + # macOS: 'rebase opcodes terminated early at offset 1 of 80016' when building __fortran_builtins.mod + build_flang="true" + + if [ "$target" = "Windows-X64" ]; then + target_cmake_flags="$target_cmake_flags -DLLVM_RELEASE_ENABLE_PROJECTS=\"clang;lld;lldb;clang-tools-extra;bolt;polly;mlir\"" + build_flang="false" + fi + + if [ "${{ runner.os }}" = "Windows" ]; then + # The build times out on Windows, so we need to disable LTO. + target_cmake_flags="$target_cmake_flags -DLLVM_RELEASE_ENABLE_LTO=OFF" + fi - build-stage1-linux: - name: "Build Stage 1 Linux" + echo "target-cmake-flags=$target_cmake_flags" >> $GITHUB_OUTPUT + echo "build-flang=$build_flang" >> $GITHUB_OUTPUT + + build-stage1: + name: "Build Stage 1" needs: prepare - runs-on: ubuntu-22.04 if: github.repository == 'llvm/llvm-project' + runs-on: ${{ inputs.runs-on }} steps: + + - name: Checkout Actions + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + ref: ${{ (github.event_name == 'pull_request' && github.sha) || 'main' }} + sparse-checkout: | + .github/workflows/ + sparse-checkout-cone-mode: false + # Check out outside of working directory so the source checkout doesn't + # remove it. + path: workflows + + # actions/checkout does not support paths outside of the GITHUB_WORKSPACE. + # Also, anything that we put inside of GITHUB_WORKSPACE will be overwritten + # by future actions/checkout steps. Therefore, in order to checkout the + # latest actions from main, we need to first checkout out the actions inside of + # GITHUB_WORKSPACE (see previous step), then use actions/checkout to checkout + # the code being built and the move the actions from main back into GITHUB_WORKSPACE, + # becasue the uses on composite actions only reads workflows from inside GITHUB_WORKSPACE. + - shell: bash + run: mv workflows ../workflows-main + - name: Checkout LLVM uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: ref: ${{ needs.prepare.outputs.ref }} - - name: Install Ninja - uses: llvm/actions/install-ninja@22e9f909d35b50bd1181709564bfe816eaeaae81 # main + - name: Copy main workflows + shell: bash + run: | + mv ../workflows-main . + + - name: Setup Stage + id: setup-stage + uses: ./workflows-main/.github/workflows/release-binaries-setup-stage - name: Setup sccache uses: hendrikmuhs/ccache-action@ca3acd2731eef11f1572ccb126356c2f9298d35e # v1.2.9 with: - max-size: 250M - key: sccache-${{ runner.os }}-release + # Default to 2G to workaround: https://github.com/hendrikmuhs/ccache-action/issues/174 + max-size: 2G + key: sccache-${{ runner.os }}-${{ runner.arch }}-release variant: sccache - name: Build Stage 1 Clang + id: build + shell: bash run: | - sudo chown $USER:$USER /mnt/ - cmake -G Ninja -C clang/cmake/caches/Release.cmake -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache -S llvm -B /mnt/build - ninja -v -C /mnt/build - - # We need to create an archive of the build directory, because it has too - # many files to upload. - - name: Package Build and Source Directories - run: | - tar -c . | zstd -T0 -c > llvm-project.tar.zst - tar -C /mnt/ -c build/ | zstd -T0 -c > build.tar.zst - - - name: Upload Stage 1 Source - uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 #v4.3.0 - with: - name: stage1-source - path: llvm-project.tar.zst - retention-days: 2 - - - name: Upload Stage 1 Build Dir - uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 #v4.3.0 + # There were some issues on the ARM64 MacOS runners with trying to build x86 object, + # so we need to set some extra cmake flags to disable this. + cmake -G Ninja -S llvm -B ${{ steps.setup-stage.outputs.build-prefix }}/build \ + ${{ needs.prepare.outputs.target-cmake-flags }} \ + -C clang/cmake/caches/Release.cmake \ + -DBOOTSTRAP_LLVM_PARALLEL_LINK_JOBS=1 \ + -DBOOTSTRAP_CPACK_PACKAGE_FILE_NAME="${{ needs.prepare.outputs.release-binary-basename }}" \ + -DCMAKE_C_COMPILER_LAUNCHER=sccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=sccache + ninja -v -C ${{ steps.setup-stage.outputs.build-prefix }}/build + # There is a race condition on the MacOS builders and this command is here + # to help debug that when it happens. + ls -ltr ${{ steps.setup-stage.outputs.build-prefix }}/build + + - name: Save Stage + uses: ./workflows-main/.github/workflows/release-binaries-save-stage with: - name: stage1-build - path: build.tar.zst - retention-days: 2 + build-prefix: ${{ steps.setup-stage.outputs.build-prefix }} - build-stage2-linux: - name: "Build Stage 2 Linux" + build-stage2: + name: "Build Stage 2" needs: - prepare - - build-stage1-linux - runs-on: ubuntu-22.04 + - build-stage1 if: github.repository == 'llvm/llvm-project' + runs-on: ${{ inputs.runs-on }} steps: - - name: Install Ninja - uses: llvm/actions/install-ninja@22e9f909d35b50bd1181709564bfe816eaeaae81 # main - - - name: Download Stage 1 Artifacts - uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1 + - name: Checkout Actions + uses: actions/checkout@v4 with: - pattern: stage1-* - merge-multiple: true - - - name: Unpack Artifacts - run: | - tar --zstd -xf llvm-project.tar.zst - rm llvm-project.tar.zst - sudo chown $USER:$USER /mnt/ - tar --zstd -C /mnt -xf build.tar.zst - rm build.tar.zst + ref: ${{ (github.event_name == 'pull_request' && github.sha) || 'main' }} + sparse-checkout: | + .github/workflows/ + sparse-checkout-cone-mode: false + path: workflows + - name: Setup Stage + id: setup-stage + uses: ./workflows/.github/workflows/release-binaries-setup-stage + with: + previous-artifact: build-stage1 - name: Build Stage 2 # Re-enable once PGO builds are supported. - if: false - run: | - ninja -C /mnt/build stage2-instrumented - - # We need to create an archive of the build directory, because it has too - # many files to upload. - - name: Save Build and Source Directories + if: needs.prepare.outputs.enable-pgo == 'true' + shell: bash run: | - tar -c . | zstd -T0 -c > llvm-project.tar.zst - tar -C /mnt/ -c build/ | zstd -T0 -c > build.tar.zst + ninja -C ${{ steps.setup-stage.outputs.build-prefix}}/build stage2-instrumented - - name: Upload Stage 2 Source - uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 #v4.3.0 + - name: Save Stage + uses: ./workflows/.github/workflows/release-binaries-save-stage with: - name: stage2-source - path: ${{ github.workspace }}/llvm-project.tar.zst - retention-days: 2 + build-prefix: ${{ steps.setup-stage.outputs.build-prefix }} - - name: Upload Stage 2 Build Dir - uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 #v4.3.0 + build-stage3-clang: + name: "Build Stage 3 LLVM/Clang" + needs: + - prepare + - build-stage2 + if: github.repository == 'llvm/llvm-project' + runs-on: ${{ inputs.runs-on }} + steps: + - name: Checkout Actions + uses: actions/checkout@v4 + with: + ref: ${{ (github.event_name == 'pull_request' && github.sha) || 'main' }} + sparse-checkout: | + .github/workflows/ + sparse-checkout-cone-mode: false + path: workflows + - name: Setup Stage + id: setup-stage + uses: ./workflows/.github/workflows/release-binaries-setup-stage with: - name: stage2-build - path: ${{ github.workspace }}/build.tar.zst - retention-days: 2 + previous-artifact: build-stage2 + - name: Build LLVM/Clang + shell: bash + run: | + # There is a race condition on the MacOS builders and this command is here + # to help debug that when it happens. + ls -ltr ${{ steps.setup-stage.outputs.build-prefix }}/build + ninja -C ${{ steps.setup-stage.outputs.build-prefix }}/build stage2-clang + # Build some of the larger binaries here too. + ninja -C ${{ steps.setup-stage.outputs.build-prefix }}/build/tools/clang/stage2-bins/ \ + clang-scan-deps \ + modularize clangd \ + clangd-indexer \ + clang-check \ + ${{ (runner.os == 'Linux' && 'clangd-fuzzer') || '' }} \ + clang-tidy \ + llc \ + lli \ + llvm-exegesis \ + llvm-opt-fuzzer \ + llvm-reduce \ + llvm-lto \ + dsymutil + + - name: Save Stage + uses: ./workflows/.github/workflows/release-binaries-save-stage + with: + build-prefix: ${{ steps.setup-stage.outputs.build-prefix }} - build-stage3-linux: - name: "Build Stage 3 Linux" + build-stage3-flang: + name: "Build Stage 3 Flang/MLIR/Bolt" needs: - prepare - - build-stage2-linux - outputs: - filename: ${{ steps.package-info.outputs.release-filename }} - runs-on: ubuntu-22.04-16x64 - if: github.repository == 'llvm/llvm-project' + - build-stage3-clang + runs-on: ${{ inputs.runs-on }} steps: - - name: Install Ninja - uses: llvm/actions/install-ninja@22e9f909d35b50bd1181709564bfe816eaeaae81 # main - - - name: 'Download artifact' - uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1 + - name: Checkout Actions + uses: actions/checkout@v4 with: - pattern: stage2-* - merge-multiple: true + ref: ${{ (github.event_name == 'pull_request' && github.sha) || 'main' }} + sparse-checkout: | + .github/workflows/ + sparse-checkout-cone-mode: false + path: workflows + - name: Setup Stage + id: setup-stage + uses: ./workflows/.github/workflows/release-binaries-setup-stage + with: + previous-artifact: build-stage3-clang - - name: Unpack Artifact + - name: Build Flang / MLIR / Bolt + shell: bash run: | - tar --zstd -xf llvm-project.tar.zst - rm llvm-project.tar.zst - sudo chown $USER:$USER /mnt/ - tar --zstd -C /mnt -xf build.tar.zst - rm build.tar.zst + # Build some of the mlir tools that take a long time to link + if [ "${{ needs.prepare.outputs.build-flang }}" = "true" ]; then + ninja -C ${{ steps.setup-stage.outputs.build-prefix }}/build/tools/clang/stage2-bins/ -j2 flang-new bbc + fi + ninja -C ${{ steps.setup-stage.outputs.build-prefix }}/build/tools/clang/stage2-bins/ \ + mlir-bytecode-parser-fuzzer \ + mlir-cpu-runner \ + mlir-lsp-server \ + mlir-opt \ + mlir-query \ + mlir-reduce \ + mlir-text-parser-fuzzer \ + mlir-translate \ + mlir-transform-opt \ + mlir-cat \ + mlir-minimal-opt \ + mlir-minimal-opt-canonicalize \ + mlir-pdll-lsp-server \ + llvm-bolt \ + llvm-bolt-heatmap + + - name: Save Stage + uses: ./workflows/.github/workflows/release-binaries-save-stage + with: + build-prefix: ${{ steps.setup-stage.outputs.build-prefix }} - - name: Build Release Package - run: | - ninja -C /mnt/build stage2-package + build-stage3-all: + name: "Build Stage 3" + needs: + - prepare + - build-stage3-flang + runs-on: ${{ inputs.runs-on }} + steps: + - name: Checkout Actions + uses: actions/checkout@v4 + with: + ref: ${{ (github.event_name == 'pull_request' && github.sha) || 'main' }} + sparse-checkout: | + .github/workflows/ + sparse-checkout-cone-mode: false + path: workflows + - name: Setup Stage + id: setup-stage + uses: ./workflows/.github/workflows/release-binaries-setup-stage + with: + previous-artifact: build-stage3-flang - - id: package-info + - name: Build Release Package + shell: bash run: | - filename="LLVM-${{ needs.prepare.outputs.release-version }}-Linux.tar.xz" - echo "filename=$filename" >> $GITHUB_OUTPUT - echo "path=/mnt/build/tools/clang/stage2-bins/$filename" >> $GITHUB_OUTPUT + which cmake + ninja -C ${{ steps.setup-stage.outputs.build-prefix }}/build stage2-package + # Copy Release artifact to the workspace so it is easier to upload. + # This is necessary, because on Windows, the build-prefix path can + # only be used on bash steps, because it uses the form of /d/files/ + # and other steps expect D:\files. + mv ${{ steps.setup-stage.outputs.build-prefix }}/build/tools/clang/stage2-bins/${{ needs.prepare.outputs.release-binary-filename }} . - uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 #v4.3.0 - if: always() with: - name: release-binary - path: ${{ steps.package-info.outputs.path }} + name: ${{ runner.os }}-${{ runner.arch }}-release-binary + # Due to path differences on Windows when running in bash vs running on node, + # we need to search for files in the current workspace. + path: | + ${{ needs.prepare.outputs.release-binary-filename }} # Clean up some build files to reduce size of artifact. - name: Clean Up Build Directory + shell: bash run: | - find /mnt/build -iname ${{ steps.package-info.outputs.filename }} -delete + find ${{ steps.setup-stage.outputs.build-prefix }}/build -iname ${{ needs.prepare.outputs.release-binary-filename }} -delete + rm -Rf ${{ steps.setup-stage.outputs.build-prefix }}/build/tools/clang/stage2-bins/_CPack_Packages - # We need to create an archive of the build directory, because it has too - # many files to upload. - - name: Save Build and Source Directories - run: | - tar -c . | zstd -T0 -c > llvm-project.tar.zst - tar -C /mnt/ -c build/ | zstd -T0 -c > build.tar.zst - - - name: Upload Stage 3 Source - uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 #v4.3.0 - with: - name: stage3-source - path: llvm-project.tar.zst - retention-days: 2 - - - name: Upload Stage 3 Build Dir - uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 #v4.3.0 + - name: Save Stage + uses: ./workflows/.github/workflows/release-binaries-save-stage with: - name: stage3-build - path: build.tar.zst - retention-days: 2 + build-prefix: ${{ steps.setup-stage.outputs.build-prefix }} - upload-release-binaries-linux: - name: "Upload Linux Release Binaries" + upload-release-binaries: + name: "Upload Release Binaries" needs: - prepare - - build-stage3-linux - if : ${{ needs.prepare.outputs.upload == 'true' }} + - build-stage3-all + if: >- + always() && + github.event_name != 'pull_request' && + needs.prepare.outputs.upload == 'true' runs-on: ubuntu-22.04 permissions: contents: write # For release uploads + id-token: write # For artifact attestations + attestations: write # For artifact attestations steps: - name: 'Download artifact' uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1 with: - name: release-binary + pattern: '*-release-binary' + merge-multiple: true + + - name: Attest Build Provenance + id: provenance + uses: actions/attest-build-provenance@897ed5eab6ed058a474202017ada7f40bfa52940 # v1.0.0 + with: + subject-path: ${{ needs.prepare.outputs.release-binary-filename }} + + - name: Rename attestation file + run: + mv ${{ steps.provenance.outputs.bundle-path }} ${{ needs.prepare.outputs.release-binary-filename }}.jsonl + + - name: Upload Build Provenance + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 #v4.3.3 + with: + name: ${{ runner.os }}-${{ runner.arch }}-release-binary-attestation + path: ${{ needs.prepare.outputs.release-binary-filename }}.jsonl - name: Upload Release + shell: bash run: | sudo apt install python3-github ./llvm-project/llvm/utils/release/github-upload-release.py \ --token ${{ github.token }} \ --release ${{ needs.prepare.outputs.release-version }} \ upload \ - --files ${{ needs.build-stage3-linux.outputs.release-filename }} - + --files ${{ needs.prepare.outputs.release-binary-filename }}* - test-stage3-linux: - name: "Test Stage 3 Linux" + test-stage3: + name: "Test Stage 3" needs: - prepare - - build-stage3-linux - runs-on: ubuntu-22.04 - if: github.repository == 'llvm/llvm-project' + - build-stage3-all + if: >- + github.repository == 'llvm/llvm-project' + runs-on: ${{ inputs.runs-on }} steps: - - name: Install Ninja - uses: llvm/actions/install-ninja@22e9f909d35b50bd1181709564bfe816eaeaae81 # main - - - name: 'Download artifact' - uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1 + - name: Checkout Actions + uses: actions/checkout@v4 with: - pattern: stage3-* - merge-multiple: true - - - name: Unpack Artifact - run: | - tar --zstd -xf llvm-project.tar.zst - rm llvm-project.tar.zst - sudo chown $USER:$USER /mnt/ - tar --zstd -C /mnt -xf build.tar.zst - rm build.tar.zst + ref: ${{ (github.event_name == 'pull_request' && github.sha) || 'main' }} + sparse-checkout: | + .github/workflows/ + sparse-checkout-cone-mode: false + path: workflows + - name: Setup Stage + id: setup-stage + uses: ./workflows/.github/workflows/release-binaries-setup-stage + with: + previous-artifact: build-stage3-all - name: Run Tests + shell: bash run: | - ninja -C /mnt/build stage2-check-all + ninja -C ${{ steps.setup-stage.outputs.build-prefix }}/build stage2-check-all diff --git a/.github/workflows/release-sources.yml b/.github/workflows/release-sources.yml index 9c5b1a9f01709..b0c0b652f3758 100644 --- a/.github/workflows/release-sources.yml +++ b/.github/workflows/release-sources.yml @@ -47,7 +47,7 @@ jobs: steps: - id: inputs run: | - ref=${{ inputs.release-version || github.sha }} + ref=${{ (inputs.release-version && format('llvmorg-{0}', inputs.release-version)) || github.sha }} if [ -n "${{ inputs.release-version }}" ]; then export_args="-release ${{ inputs.release-version }} -final" else diff --git a/.github/workflows/release-tasks.yml b/.github/workflows/release-tasks.yml index 2ed56dace1d4c..7dd4c306671b7 100644 --- a/.github/workflows/release-tasks.yml +++ b/.github/workflows/release-tasks.yml @@ -81,10 +81,20 @@ jobs: needs: - validate-tag - release-create + strategy: + fail-fast: false + matrix: + runs-on: + - ubuntu-22.04 + - windows-2022 + - macos-13 + - macos-14 + uses: ./.github/workflows/release-binaries.yml with: release-version: ${{ needs.validate-tag.outputs.release-version }} upload: true + runs-on: ${{ matrix.runs-on }} release-sources: name: Package Release Sources diff --git a/.github/workflows/unprivileged-download-artifact/action.yml b/.github/workflows/unprivileged-download-artifact/action.yml new file mode 100644 index 0000000000000..9d8fb59a67c0e --- /dev/null +++ b/.github/workflows/unprivileged-download-artifact/action.yml @@ -0,0 +1,81 @@ +name: Unprivileged Download Artifact +description: >- + Download artifacts from another workflow run without using an access token. +inputs: + run-id: + description: >- + The run-id for the workflow run that you want to download the artifact + from. If ommitted it will download the most recently created artifact + from the repo with the artifact-name. + required: false + artifact-name: + desciption: The name of the artifact to download. + required: true + + +outputs: + filename: + description: >- + The filename of the downloaded artifact or the empty string if the + artifact was not found. + value: ${{ steps.download-artifact.outputs.filename }} + artifact-id: + description: "The id of the artifact being downloaded." + value: ${{ steps.artifact-url.outputs.id }} + + +runs: + using: "composite" + steps: + - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea #v7.0.1 + id: artifact-url + with: + script: | + var response; + if (!"${{ inputs.run-id }}") { + response = await github.rest.actions.listArtifactsForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + name: "${{ inputs.artifact-name }}" + }) + } else { + response = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: "${{ inputs.run-id }}", + name: "${{ inputs.artifact-name }}" + }) + } + + console.log(response) + + for (artifact of response.data.artifacts) { + console.log(artifact); + } + + if (response.data.artifacts.length == 0) { + console.log("Could not find artifact ${{ inputs.artifact-name }} for workflow run ${{ inputs.run-id }}") + return; + } + + const url_response = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: response.data.artifacts[0].id, + archive_format: "zip" + }) + + core.setOutput("url", url_response.url); + core.setOutput("id", response.data.artifacts[0].id); + + - shell: bash + if: steps.artifact-url.outputs.url != '' + id: download-artifact + run: | + curl -L -o ${{ inputs.artifact-name }}.zip "${{ steps.artifact-url.outputs.url }}" + echo "filename=${{ inputs.artifact-name }}.zip" >> $GITHUB_OUTPUT + + - shell: bash + if: steps.download-artifact.outputs.filename != '' + run: | + unzip ${{ steps.download-artifact.outputs.filename }} diff --git a/.github/workflows/version-check.yml b/.github/workflows/version-check.yml index 4ce6119a407f5..894e07d323ca9 100644 --- a/.github/workflows/version-check.yml +++ b/.github/workflows/version-check.yml @@ -27,5 +27,5 @@ jobs: - name: Version Check run: | - version=$(grep -o 'LLVM_VERSION_\(MAJOR\|MINOR\|PATCH\) [0-9]\+' llvm/CMakeLists.txt | cut -d ' ' -f 2 | tr "\n" "." | sed 's/.$//g') + version=$(grep -o 'LLVM_VERSION_\(MAJOR\|MINOR\|PATCH\) [0-9]\+' cmake/Modules/LLVMVersion.cmake | cut -d ' ' -f 2 | tr "\n" "." | sed 's/.$//g') .github/workflows/version-check.py "$version" diff --git a/bolt/CMakeLists.txt b/bolt/CMakeLists.txt index 74907ad118d12..9f5875dd21284 100644 --- a/bolt/CMakeLists.txt +++ b/bolt/CMakeLists.txt @@ -1,6 +1,17 @@ +cmake_minimum_required(VERSION 3.20.0) + set(LLVM_SUBPROJECT_TITLE "BOLT") -include(ExternalProject) +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) + +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + project(bolt) + set(BOLT_BUILT_STANDALONE TRUE) +endif() set(BOLT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(BOLT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) @@ -9,6 +20,42 @@ set(CMAKE_CXX_STANDARD 17) # Add path for custom modules. list(INSERT CMAKE_MODULE_PATH 0 "${BOLT_SOURCE_DIR}/cmake/modules") +include(GNUInstallDirs) + +# standalone build, copied from clang +if(BOLT_BUILT_STANDALONE) + set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to") + set(CMAKE_CXX_STANDARD_REQUIRED YES) + set(CMAKE_CXX_EXTENSIONS NO) + + if(NOT MSVC_IDE) + set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS} + CACHE BOOL "Enable assertions") + # Assertions should follow llvm-config's. + mark_as_advanced(LLVM_ENABLE_ASSERTIONS) + endif() + + find_package(LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR}") + list(APPEND CMAKE_MODULE_PATH "${LLVM_DIR}") + + set(LLVM_MAIN_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../llvm" CACHE PATH "Path to LLVM source tree") + find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR} + NO_DEFAULT_PATH) + + # They are used as destination of target generators. + set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin) + set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX}) + + include(AddLLVM) + include(TableGen) + include_directories(${LLVM_INCLUDE_DIRS}) + link_directories("${LLVM_LIBRARY_DIR}") + + set( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_INSTALL_BINDIR}" ) + set( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_INSTALL_LIBDIR}/${LLVM_LIBDIR_SUFFIX}" ) + set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_INSTALL_LIBDIR}/${LLVM_LIBDIR_SUFFIX}") +endif() # standalone + # Determine default set of targets to build -- the intersection of # those BOLT supports and those LLVM is targeting. set(BOLT_TARGETS_TO_BUILD_all "AArch64;X86;RISCV") @@ -94,6 +141,8 @@ if (BOLT_ENABLE_RUNTIME) if(CMAKE_SYSROOT) list(APPEND extra_args -DCMAKE_SYSROOT=${CMAKE_SYSROOT}) endif() + + include(ExternalProject) ExternalProject_Add(bolt_rt SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/runtime" STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-stamps @@ -104,6 +153,7 @@ if (BOLT_ENABLE_RUNTIME) -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} -DLLVM_LIBDIR_SUFFIX=${LLVM_LIBDIR_SUFFIX} -DLLVM_LIBRARY_DIR=${LLVM_LIBRARY_DIR} + -DBOLT_BUILT_STANDALONE=${BOLT_BUILT_STANDALONE} ${extra_args} INSTALL_COMMAND "" BUILD_ALWAYS True @@ -113,6 +163,8 @@ if (BOLT_ENABLE_RUNTIME) add_llvm_install_targets(install-bolt_rt DEPENDS bolt_rt bolt COMPONENT bolt) + set(LIBBOLT_RT_INSTR "${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-bins/lib/libbolt_rt_instr.a") + set(LIBBOLT_RT_HUGIFY "${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-bins/lib/libbolt_rt_hugify.a") endif() find_program(GNU_LD_EXECUTABLE NAMES ${LLVM_DEFAULT_TARGET_TRIPLE}-ld.bfd ld.bfd DOC "GNU ld") diff --git a/bolt/docs/CommandLineArgumentReference.md b/bolt/docs/CommandLineArgumentReference.md index bd6e2ec01b53e..0c8935457366d 100644 --- a/bolt/docs/CommandLineArgumentReference.md +++ b/bolt/docs/CommandLineArgumentReference.md @@ -88,7 +88,7 @@ - `--comp-dir-override=` - Overrides DW_AT_comp_dir, and provides an alterantive base location, which is + Overrides DW_AT_comp_dir, and provides an alternative base location, which is used with DW_AT_dwo_name to construct a path to *.dwo files. - `--create-debug-names-section` @@ -113,11 +113,6 @@ Prints out offsets for abbrev and debug_info of Skeleton CUs that get patched. -- `--deterministic-debuginfo` - - Disables parallel execution of tasks that may produce nondeterministic debug - info - - `--dot-tooltip-code` Add basic block instructions as tool tips on nodes @@ -686,6 +681,10 @@ threshold means fewer functions to process. E.g threshold of 90 means only top 10 percent of functions with profile will be processed. +- `--match-with-call-graph` + + Match functions with call graph + - `--memcpy1-spec=` List of functions with call sites for which to specialize memcpy() for size 1 diff --git a/bolt/docs/OptimizingClang.md b/bolt/docs/OptimizingClang.md index ff7e71b6a76bc..685fcc2b738fa 100644 --- a/bolt/docs/OptimizingClang.md +++ b/bolt/docs/OptimizingClang.md @@ -49,6 +49,7 @@ $ cd ${TOPLEV}/stage3 $ CPATH=${TOPLEV}/stage2-prof-use-lto/install/bin/ $ cmake -G Ninja ${TOPLEV}/llvm -DLLVM_TARGETS_TO_BUILD=X86 -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_C_COMPILER=$CPATH/clang -DCMAKE_CXX_COMPILER=$CPATH/clang++ \ + -DLLVM_ENABLE_PROJECTS="clang" \ -DLLVM_USE_LINKER=lld -DCMAKE_INSTALL_PREFIX=${TOPLEV}/stage3/install $ perf record -e cycles:u -j any,u -- ninja clang ``` diff --git a/bolt/docs/generate_doc.py b/bolt/docs/generate_doc.py index d8829daf677b4..763dc00b44ca3 100644 --- a/bolt/docs/generate_doc.py +++ b/bolt/docs/generate_doc.py @@ -45,7 +45,7 @@ def parse_bolt_options(output): cleaned_line = line.strip() if cleaned_line.casefold() in map(str.casefold, section_headers): - if prev_section != None: # Save last option from prev section + if prev_section is not None: # Save last option from prev section add_info(sections, current_section, option, description) option, description = None, [] @@ -76,7 +76,7 @@ def parse_bolt_options(output): description = [descr] if option.startswith("--print") or option.startswith("--time"): current_section = "BOLT printing options:" - elif prev_section != None: + elif prev_section is not None: current_section = prev_section continue diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h index 73932c4ca2fb3..5fb32a1ea6784 100644 --- a/bolt/include/bolt/Core/BinaryContext.h +++ b/bolt/include/bolt/Core/BinaryContext.h @@ -23,6 +23,7 @@ #include "bolt/RuntimeLibs/RuntimeLibrary.h" #include "llvm/ADT/AddressRanges.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/EquivalenceClasses.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/iterator.h" #include "llvm/BinaryFormat/Dwarf.h" @@ -32,6 +33,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCPseudoProbe.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" @@ -240,12 +242,19 @@ class BinaryContext { /// Function fragments to skip. std::unordered_set FragmentsToSkip; + /// Fragment equivalence classes to query belonging to the same "family" in + /// presence of multiple fragments/multiple parents. + EquivalenceClasses FragmentClasses; + /// The runtime library. std::unique_ptr RtLibrary; /// DWP Context. std::shared_ptr DWPContext; + /// Decoded pseudo probes. + std::shared_ptr PseudoProbeDecoder; + /// A map of DWO Ids to CUs. using DWOIdToCUMapType = std::unordered_map; DWOIdToCUMapType DWOCUs; @@ -377,6 +386,15 @@ class BinaryContext { RtLibrary = std::move(Lib); } + const MCPseudoProbeDecoder *getPseudoProbeDecoder() const { + return PseudoProbeDecoder.get(); + } + + void setPseudoProbeDecoder(std::shared_ptr Decoder) { + assert(!PseudoProbeDecoder && "Cannot set pseudo probe decoder twice."); + PseudoProbeDecoder = Decoder; + } + /// Return BinaryFunction containing a given \p Address or nullptr if /// no registered function contains the \p Address. /// @@ -431,6 +449,9 @@ class BinaryContext { return nullptr; } + /// Deregister JumpTable registered at a given \p Address and delete it. + void deleteJumpTable(uint64_t Address); + unsigned getDWARFEncodingSize(unsigned Encoding) { if (Encoding == dwarf::DW_EH_PE_omit) return 0; @@ -1016,7 +1037,15 @@ class BinaryContext { /// fragment_name == parent_name.cold(.\d+)? /// True if the Function is registered, false if the check failed. bool registerFragment(BinaryFunction &TargetFunction, - BinaryFunction &Function) const; + BinaryFunction &Function); + + /// Return true if two functions belong to the same "family": are fragments + /// of one another, or fragments of the same parent, or transitively fragment- + /// related. + bool areRelatedFragments(const BinaryFunction *LHS, + const BinaryFunction *RHS) const { + return FragmentClasses.isEquivalent(LHS, RHS); + } /// Add interprocedural reference for \p Function to \p Address void addInterproceduralReference(BinaryFunction *Function, uint64_t Address) { @@ -1436,10 +1465,7 @@ class BinaryContext { std::unique_ptr OW = MAB->createObjectWriter(OS); std::unique_ptr Streamer(TheTarget->createMCObjectStreamer( *TheTriple, *Ctx, std::unique_ptr(MAB), std::move(OW), - std::unique_ptr(MCE), *STI, - /* RelaxAll */ false, - /* IncrementalLinkerCompatible */ false, - /* DWARFMustBeAtTheEnd */ false)); + std::unique_ptr(MCE), *STI)); return Streamer; } diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h index 7d0afee4d1b78..24c7db2f5d69c 100644 --- a/bolt/include/bolt/Core/BinaryFunction.h +++ b/bolt/include/bolt/Core/BinaryFunction.h @@ -416,6 +416,9 @@ class BinaryFunction { /// different parameters by every pass. mutable uint64_t Hash{0}; + /// Function GUID assigned externally. + uint64_t GUID{0}; + /// For PLT functions it contains a symbol associated with a function /// reference. It is nullptr for non-PLT functions. const MCSymbol *PLTSymbol{nullptr}; @@ -1790,11 +1793,6 @@ class BinaryFunction { return ParentFragments.contains(&Other); } - /// Returns if this function is a parent of \p Other function. - bool isParentOf(const BinaryFunction &Other) const { - return Fragments.contains(&Other); - } - /// Return the child fragment form parent function iterator_range getFragments() const { return iterator_range(Fragments.begin(), @@ -1804,11 +1802,6 @@ class BinaryFunction { /// Return the parent function for split function fragments. FragmentsSetTy *getParentFragments() { return &ParentFragments; } - /// Returns if this function is a parent or child of \p Other function. - bool isParentOrChildOf(const BinaryFunction &Other) const { - return isChildOf(Other) || isParentOf(Other); - } - /// Set the profile data for the number of times the function was called. BinaryFunction &setExecutionCount(uint64_t Count) { ExecutionCount = Count; @@ -2256,6 +2249,11 @@ class BinaryFunction { /// Returns the last computed hash value of the function. size_t getHash() const { return Hash; } + /// Returns the function GUID. + uint64_t getGUID() const { return GUID; } + + void setGUID(uint64_t Id) { GUID = Id; } + using OperandHashFuncTy = function_ref; diff --git a/bolt/include/bolt/Core/DIEBuilder.h b/bolt/include/bolt/Core/DIEBuilder.h index 0b840c142ed81..e5b057ea1e42b 100644 --- a/bolt/include/bolt/Core/DIEBuilder.h +++ b/bolt/include/bolt/Core/DIEBuilder.h @@ -127,6 +127,9 @@ class DIEBuilder { DWARFContext *DwarfContext{nullptr}; DWARFUnit *SkeletonCU{nullptr}; uint64_t UnitSize{0}; + /// Adds separate UnitSize counter for updating DebugNames + /// so there is no dependency between the functions. + uint64_t DebugNamesUnitSize{0}; llvm::DenseSet AllProcessed; DWARF5AcceleratorTable &DebugNamesTable; // Unordered map to handle name collision if output DWO directory is @@ -203,13 +206,16 @@ class DIEBuilder { /// Update references once the layout is finalized. void updateReferences(); - /// Update the Offset and Size of DIE, populate DebugNames table. + /// Update the Offset and Size of DIE. /// Along with current CU, and DIE being processed and the new DIE offset to /// be updated, it takes in Parents vector that can be empty if this DIE has /// no parents. - uint32_t finalizeDIEs(DWARFUnit &CU, DIE &Die, - std::optional Parent, - uint32_t NumberParentsInChain, uint32_t &CurOffset); + uint32_t finalizeDIEs(DWARFUnit &CU, DIE &Die, uint32_t &CurOffset); + + /// Populates DebugNames table. + void populateDebugNamesTable(DWARFUnit &CU, const DIE &Die, + std::optional Parent, + uint32_t NumberParentsInChain); void registerUnit(DWARFUnit &DU, bool NeedSort); @@ -338,6 +344,9 @@ class DIEBuilder { /// Finish current DIE construction. void finish(); + /// Update debug names table. + void updateDebugNamesTable(); + // Interface to edit DIE template T *allocateDIEValue() { return new (getState().DIEAlloc) T; diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h index 5935ffaa46af7..6ea3b1af1024f 100644 --- a/bolt/include/bolt/Core/DebugData.h +++ b/bolt/include/bolt/Core/DebugData.h @@ -475,7 +475,8 @@ class DebugStrOffsetsWriter { } /// Update Str offset in .debug_str in .debug_str_offsets. - void updateAddressMap(uint32_t Index, uint32_t Address); + void updateAddressMap(uint32_t Index, uint32_t Address, + const DWARFUnit &Unit); /// Get offset for given index in original .debug_str_offsets section. uint64_t getOffset(uint32_t Index) const { return StrOffsets[Index]; } @@ -507,6 +508,8 @@ class DebugStrOffsetsWriter { std::unique_ptr StrOffsetsBuffer; std::unique_ptr StrOffsetsStream; std::map IndexToAddressMap; + [[maybe_unused]] + DenseSet DebugStrOffsetFinalized; SmallVector StrOffsets; std::unordered_map ProcessedBaseOffsets; bool StrOffsetSectionWasModified = false; diff --git a/bolt/include/bolt/Core/GDBIndex.h b/bolt/include/bolt/Core/GDBIndex.h index 6604c2a11472d..0ebcf4ecfe99e 100644 --- a/bolt/include/bolt/Core/GDBIndex.h +++ b/bolt/include/bolt/Core/GDBIndex.h @@ -53,6 +53,14 @@ class GDBIndex { const GDBIndexTUEntryType &getGDBIndexTUEntryVector() const { return GDBIndexTUEntryVector; } + + /// Sorts entries in GDBIndexTUEntryVector according to the TypeHash. + void sortGDBIndexTUEntryVector() { + llvm::stable_sort(GDBIndexTUEntryVector, [](const GDBIndexTUEntry &LHS, + const GDBIndexTUEntry &RHS) { + return LHS.TypeHash > RHS.TypeHash; + }); + } }; } // namespace bolt diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h index c916c6f95751f..32eda0b283b88 100644 --- a/bolt/include/bolt/Core/MCPlusBuilder.h +++ b/bolt/include/bolt/Core/MCPlusBuilder.h @@ -58,6 +58,8 @@ enum class IndirectBranchType : char { POSSIBLE_PIC_JUMP_TABLE, /// Possibly a jump table for PIC. POSSIBLE_GOTO, /// Possibly a gcc's computed goto. POSSIBLE_FIXED_BRANCH, /// Possibly an indirect branch to a fixed location. + POSSIBLE_PIC_FIXED_BRANCH, /// Possibly an indirect jump to a fixed entry in a + /// PIC jump table. }; class MCPlusBuilder { @@ -1474,12 +1476,11 @@ class MCPlusBuilder { /// will be set to the different components of the branch. \p MemLocInstr /// is the instruction that loads up the indirect function pointer. It may /// or may not be same as \p Instruction. - virtual IndirectBranchType - analyzeIndirectBranch(MCInst &Instruction, InstructionIterator Begin, - InstructionIterator End, const unsigned PtrSize, - MCInst *&MemLocInstr, unsigned &BaseRegNum, - unsigned &IndexRegNum, int64_t &DispValue, - const MCExpr *&DispExpr, MCInst *&PCRelBaseOut) const { + virtual IndirectBranchType analyzeIndirectBranch( + MCInst &Instruction, InstructionIterator Begin, InstructionIterator End, + const unsigned PtrSize, MCInst *&MemLocInstr, unsigned &BaseRegNum, + unsigned &IndexRegNum, int64_t &DispValue, const MCExpr *&DispExpr, + MCInst *&PCRelBaseOut, MCInst *&FixedEntryLoadInst) const { llvm_unreachable("not implemented"); return IndirectBranchType::UNKNOWN; } diff --git a/bolt/include/bolt/Profile/ProfileYAMLMapping.h b/bolt/include/bolt/Profile/ProfileYAMLMapping.h index 9dd3920dbf094..2a0514d7d9304 100644 --- a/bolt/include/bolt/Profile/ProfileYAMLMapping.h +++ b/bolt/include/bolt/Profile/ProfileYAMLMapping.h @@ -93,11 +93,36 @@ template <> struct MappingTraits { static const bool flow = true; }; +namespace bolt { +struct PseudoProbeInfo { + llvm::yaml::Hex64 GUID; + uint64_t Index; + uint8_t Type; + + bool operator==(const PseudoProbeInfo &Other) const { + return GUID == Other.GUID && Index == Other.Index; + } + bool operator!=(const PseudoProbeInfo &Other) const { + return !(*this == Other); + } +}; +} // end namespace bolt + +template <> struct MappingTraits { + static void mapping(IO &YamlIO, bolt::PseudoProbeInfo &PI) { + YamlIO.mapRequired("guid", PI.GUID); + YamlIO.mapRequired("id", PI.Index); + YamlIO.mapRequired("type", PI.Type); + } + + static const bool flow = true; +}; } // end namespace yaml } // end namespace llvm LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::bolt::CallSiteInfo) LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::bolt::SuccessorInfo) +LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::bolt::PseudoProbeInfo) namespace llvm { namespace yaml { @@ -111,6 +136,7 @@ struct BinaryBasicBlockProfile { uint64_t EventCount{0}; std::vector CallSites; std::vector Successors; + std::vector PseudoProbes; bool operator==(const BinaryBasicBlockProfile &Other) const { return Index == Other.Index; @@ -132,6 +158,8 @@ template <> struct MappingTraits { std::vector()); YamlIO.mapOptional("succ", BBP.Successors, std::vector()); + YamlIO.mapOptional("pseudo_probes", BBP.PseudoProbes, + std::vector()); } }; @@ -151,6 +179,8 @@ struct BinaryFunctionProfile { llvm::yaml::Hex64 Hash{0}; uint64_t ExecCount{0}; std::vector Blocks; + llvm::yaml::Hex64 GUID{0}; + llvm::yaml::Hex64 PseudoProbeDescHash{0}; bool Used{false}; }; } // end namespace bolt @@ -164,6 +194,9 @@ template <> struct MappingTraits { YamlIO.mapRequired("nblocks", BFP.NumBasicBlocks); YamlIO.mapOptional("blocks", BFP.Blocks, std::vector()); + YamlIO.mapOptional("guid", BFP.GUID, (uint64_t)0); + YamlIO.mapOptional("pseudo_probe_desc_hash", BFP.PseudoProbeDescHash, + (uint64_t)0); } }; diff --git a/bolt/include/bolt/Profile/YAMLProfileReader.h b/bolt/include/bolt/Profile/YAMLProfileReader.h index 502a1ad612bb0..bd5a86fd676a5 100644 --- a/bolt/include/bolt/Profile/YAMLProfileReader.h +++ b/bolt/include/bolt/Profile/YAMLProfileReader.h @@ -43,6 +43,59 @@ class YAMLProfileReader : public ProfileReaderBase { using ProfileLookupMap = DenseMap; + /// A class for matching binary functions in functions in the YAML profile. + /// First, a call graph is constructed for both profiled and binary functions. + /// Then functions are hashed based on the names of their callee/caller + /// functions. Finally, functions are matched based on these neighbor hashes. + class CallGraphMatcher { + public: + /// Constructs the call graphs for binary and profiled functions and + /// computes neighbor hashes for binary functions. + CallGraphMatcher(BinaryContext &BC, yaml::bolt::BinaryProfile &YamlBP, + ProfileLookupMap &IdToYAMLBF); + + /// Returns the YamlBFs adjacent to the parameter YamlBF in the call graph. + std::optional> + getAdjacentYamlBFs(yaml::bolt::BinaryFunctionProfile &YamlBF) { + auto It = YamlBFAdjacencyMap.find(&YamlBF); + return It == YamlBFAdjacencyMap.end() ? std::nullopt + : std::make_optional(It->second); + } + + /// Returns the binary functions with the parameter neighbor hash. + std::optional> + getBFsWithNeighborHash(uint64_t NeighborHash) { + auto It = NeighborHashToBFs.find(NeighborHash); + return It == NeighborHashToBFs.end() ? std::nullopt + : std::make_optional(It->second); + } + + private: + /// Adds edges to the binary function call graph given the callsites of the + /// parameter function. + void constructBFCG(BinaryContext &BC, yaml::bolt::BinaryProfile &YamlBP); + + /// Using the constructed binary function call graph, computes and creates + /// mappings from "neighbor hash" (composed of the function names of callee + /// and caller functions of a function) to binary functions. + void computeBFNeighborHashes(BinaryContext &BC); + + /// Constructs the call graph for profile functions. + void constructYAMLFCG(yaml::bolt::BinaryProfile &YamlBP, + ProfileLookupMap &IdToYAMLBF); + + /// Adjacency map for binary functions in the call graph. + DenseMap> BFAdjacencyMap; + + /// Maps neighbor hashes to binary functions. + DenseMap> NeighborHashToBFs; + + /// Adjacency map for profile functions in the call graph. + DenseMap> + YamlBFAdjacencyMap; + }; + private: /// Adjustments for basic samples profiles (without LBR). bool NormalizeByInsnCount{false}; @@ -100,6 +153,9 @@ class YAMLProfileReader : public ProfileReaderBase { /// Matches functions using exact hash. size_t matchWithHash(BinaryContext &BC); + /// Matches functions using the call graph. + size_t matchWithCallGraph(BinaryContext &BC); + /// Matches functions with similarly named profiled functions. size_t matchWithNameSimilarity(BinaryContext &BC); diff --git a/bolt/include/bolt/Rewrite/DWARFRewriter.h b/bolt/include/bolt/Rewrite/DWARFRewriter.h index abd18b56113b6..deaf179140c01 100644 --- a/bolt/include/bolt/Rewrite/DWARFRewriter.h +++ b/bolt/include/bolt/Rewrite/DWARFRewriter.h @@ -15,7 +15,6 @@ #include "bolt/Core/GDBIndex.h" #include "llvm/ADT/StringRef.h" #include "llvm/CodeGen/DIE.h" -#include "llvm/DWP/DWP.h" #include "llvm/MC/MCContext.h" #include "llvm/Support/ToolOutputFile.h" #include @@ -41,13 +40,6 @@ class DWARFRewriter { uint64_t TypeHash; uint64_t TypeDIERelativeOffset; }; - /// Contains information for CU or TU so we can output correct {cu, tu}-index. - struct UnitMeta { - uint64_t Offset; - uint64_t Length; - uint64_t TUHash; - }; - using UnitMetaVectorType = std::vector; private: BinaryContext &BC; @@ -95,9 +87,6 @@ class DWARFRewriter { std::mutex LocListDebugInfoPatchesMutex; - /// Dwo id specific its RangesBase. - std::unordered_map DwoRangesBase; - std::unordered_map LineTablePatchMap; std::unordered_map TypeUnitRelocMap; @@ -191,47 +180,12 @@ class DWARFRewriter { /// Update stmt_list for CUs based on the new .debug_line \p Layout. void updateLineTableOffsets(const MCAssembler &Asm); - uint64_t getDwoRangesBase(uint64_t DWOId) { return DwoRangesBase[DWOId]; } - - void setDwoRangesBase(uint64_t DWOId, uint64_t RangesBase) { - DwoRangesBase[DWOId] = RangesBase; - } - using OverriddenSectionsMap = std::unordered_map; /// Output .dwo files. void writeDWOFiles(DWARFUnit &, const OverriddenSectionsMap &, const std::string &, DebugLocWriter &, DebugStrOffsetsWriter &, DebugStrWriter &); using KnownSectionsEntry = std::pair; - struct DWPState { - std::unique_ptr Out; - std::unique_ptr TmpBC; - std::unique_ptr Streamer; - std::unique_ptr Strings; - /// Used to store String sections for .dwo files if they are being modified. - std::vector> StrSections; - const MCObjectFileInfo *MCOFI = nullptr; - const DWARFUnitIndex *CUIndex = nullptr; - std::deque> UncompressedSections; - MapVector IndexEntries; - MapVector TypeIndexEntries; - StringMap KnownSections; - uint32_t ContributionOffsets[8] = {}; - uint32_t IndexVersion = 2; - uint64_t DebugInfoSize = 0; - uint16_t Version = 0; - bool IsDWP = false; - }; - /// Init .dwp file - void initDWPState(DWPState &); - - /// Write out .dwp File - void finalizeDWP(DWPState &); - - /// add content of dwo to .dwp file. - void updateDWP(DWARFUnit &, const OverriddenSectionsMap &, const UnitMeta &, - UnitMetaVectorType &, DWPState &, DebugLocWriter &, - DebugStrOffsetsWriter &, DebugStrWriter &); }; } // namespace bolt diff --git a/bolt/include/bolt/RuntimeLibs/RuntimeLibrary.h b/bolt/include/bolt/RuntimeLibs/RuntimeLibrary.h index e392029156bce..fc1db7369eb4a 100644 --- a/bolt/include/bolt/RuntimeLibs/RuntimeLibrary.h +++ b/bolt/include/bolt/RuntimeLibs/RuntimeLibrary.h @@ -58,7 +58,16 @@ class RuntimeLibrary { uint64_t RuntimeFiniAddress{0}; uint64_t RuntimeStartAddress{0}; - /// Get the full path to a runtime library specified by \p LibFileName. + /// Get the full path to a runtime library specified by \p LibFileName and \p + /// ToolPath. + static std::string getLibPathByToolPath(StringRef ToolPath, + StringRef LibFileName); + + /// Get the full path to a runtime library by the install directory. + static std::string getLibPathByInstalled(StringRef LibFileName); + + /// Gets the full path to a runtime library based on whether it exists + /// in the install libdir or runtime libdir. static std::string getLibPath(StringRef ToolPath, StringRef LibFileName); /// Load a static runtime library specified by \p LibPath. diff --git a/bolt/lib/CMakeLists.txt b/bolt/lib/CMakeLists.txt index 22a6be44f6458..d0f921a1a1e2c 100644 --- a/bolt/lib/CMakeLists.txt +++ b/bolt/lib/CMakeLists.txt @@ -1,3 +1,5 @@ +add_compile_definitions(CMAKE_INSTALL_FULL_LIBDIR="${CMAKE_INSTALL_FULL_LIBDIR}") + add_subdirectory(Core) add_subdirectory(Passes) add_subdirectory(Profile) diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp index 0a1f1bb9e0d20..e86075e69c05d 100644 --- a/bolt/lib/Core/BinaryContext.cpp +++ b/bolt/lib/Core/BinaryContext.cpp @@ -71,7 +71,7 @@ PrintMemData("print-mem-data", cl::opt CompDirOverride( "comp-dir-override", - cl::desc("overrides DW_AT_comp_dir, and provides an alterantive base " + cl::desc("overrides DW_AT_comp_dir, and provides an alternative base " "location, which is used with DW_AT_dwo_name to construct a path " "to *.dwo files."), cl::Hidden, cl::init(""), cl::cat(BoltCategory)); @@ -646,7 +646,7 @@ bool BinaryContext::analyzeJumpTable(const uint64_t Address, const BinaryFunction *TargetBF = getBinaryFunctionContainingAddress(Value); const bool DoesBelongToFunction = BF.containsAddress(Value) || - (TargetBF && TargetBF->isParentOrChildOf(BF)); + (TargetBF && areRelatedFragments(TargetBF, &BF)); if (!DoesBelongToFunction) { LLVM_DEBUG({ if (!BF.containsAddress(Value)) { @@ -839,9 +839,11 @@ BinaryContext::getOrCreateJumpTable(BinaryFunction &Function, uint64_t Address, assert(Address == JT->getAddress() && "unexpected non-empty jump table"); // Prevent associating a jump table to a specific fragment twice. - // This simple check arises from the assumption: no more than 2 fragments. - if (JT->Parents.size() == 1 && JT->Parents[0] != &Function) { - assert(JT->Parents[0]->isParentOrChildOf(Function) && + if (!llvm::is_contained(JT->Parents, &Function)) { + assert(llvm::all_of(JT->Parents, + [&](const BinaryFunction *BF) { + return areRelatedFragments(&Function, BF); + }) && "cannot re-use jump table of a different function"); // Duplicate the entry for the parent function for easy access JT->Parents.push_back(&Function); @@ -852,8 +854,8 @@ BinaryContext::getOrCreateJumpTable(BinaryFunction &Function, uint64_t Address, JT->print(this->outs()); } Function.JumpTables.emplace(Address, JT); - JT->Parents[0]->setHasIndirectTargetToSplitFragment(true); - JT->Parents[1]->setHasIndirectTargetToSplitFragment(true); + for (BinaryFunction *Parent : JT->Parents) + Parent->setHasIndirectTargetToSplitFragment(true); } bool IsJumpTableParent = false; @@ -1209,12 +1211,13 @@ void BinaryContext::generateSymbolHashes() { } bool BinaryContext::registerFragment(BinaryFunction &TargetFunction, - BinaryFunction &Function) const { + BinaryFunction &Function) { assert(TargetFunction.isFragment() && "TargetFunction must be a fragment"); if (TargetFunction.isChildOf(Function)) return true; TargetFunction.addParentFragment(Function); Function.addFragment(TargetFunction); + FragmentClasses.unionSets(&TargetFunction, &Function); if (!HasRelocations) { TargetFunction.setSimple(false); Function.setSimple(false); @@ -1336,7 +1339,7 @@ void BinaryContext::processInterproceduralReferences() { if (TargetFunction) { if (TargetFunction->isFragment() && - !TargetFunction->isChildOf(Function)) { + !areRelatedFragments(TargetFunction, &Function)) { this->errs() << "BOLT-WARNING: interprocedural reference between unrelated " "fragments: " @@ -2367,10 +2370,7 @@ BinaryContext::calculateEmittedSize(BinaryFunction &BF, bool FixBranches) { std::unique_ptr OW = MAB->createObjectWriter(VecOS); std::unique_ptr Streamer(TheTarget->createMCObjectStreamer( *TheTriple, *LocalCtx, std::unique_ptr(MAB), std::move(OW), - std::unique_ptr(MCEInstance.MCE.release()), *STI, - /*RelaxAll=*/false, - /*IncrementalLinkerCompatible=*/false, - /*DWARFMustBeAtTheEnd=*/false)); + std::unique_ptr(MCEInstance.MCE.release()), *STI)); Streamer->initSections(false, *STI); @@ -2523,6 +2523,16 @@ BinaryFunction *BinaryContext::getBinaryFunctionAtAddress(uint64_t Address) { return nullptr; } +/// Deregister JumpTable registered at a given \p Address and delete it. +void BinaryContext::deleteJumpTable(uint64_t Address) { + assert(JumpTables.count(Address) && "Must have a jump table at address"); + JumpTable *JT = JumpTables.at(Address); + for (BinaryFunction *Parent : JT->Parents) + Parent->JumpTables.erase(Address); + JumpTables.erase(Address); + delete JT; +} + DebugAddressRangesVector BinaryContext::translateModuleAddressRanges( const DWARFAddressRangesVector &InputRanges) const { DebugAddressRangesVector OutputRanges; diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp index 282638f9dc76f..ea09371b57e8a 100644 --- a/bolt/lib/Core/BinaryFunction.cpp +++ b/bolt/lib/Core/BinaryFunction.cpp @@ -780,6 +780,9 @@ BinaryFunction::processIndirectBranch(MCInst &Instruction, unsigned Size, // setting the value of the register used by the branch. MCInst *MemLocInstr; + // The instruction loading the fixed PIC jump table entry value. + MCInst *FixedEntryLoadInstr; + // Address of the table referenced by MemLocInstr. Could be either an // array of function pointers, or a jump table. uint64_t ArrayStart = 0; @@ -811,7 +814,7 @@ BinaryFunction::processIndirectBranch(MCInst &Instruction, unsigned Size, IndirectBranchType BranchType = BC.MIB->analyzeIndirectBranch( Instruction, Begin, Instructions.end(), PtrSize, MemLocInstr, BaseRegNum, - IndexRegNum, DispValue, DispExpr, PCRelBaseInstr); + IndexRegNum, DispValue, DispExpr, PCRelBaseInstr, FixedEntryLoadInstr); if (BranchType == IndirectBranchType::UNKNOWN && !MemLocInstr) return BranchType; @@ -877,6 +880,43 @@ BinaryFunction::processIndirectBranch(MCInst &Instruction, unsigned Size, if (BaseRegNum == BC.MRI->getProgramCounter()) ArrayStart += getAddress() + Offset + Size; + if (FixedEntryLoadInstr) { + assert(BranchType == IndirectBranchType::POSSIBLE_PIC_FIXED_BRANCH && + "Invalid IndirectBranch type"); + MCInst::iterator FixedEntryDispOperand = + BC.MIB->getMemOperandDisp(*FixedEntryLoadInstr); + assert(FixedEntryDispOperand != FixedEntryLoadInstr->end() && + "Invalid memory instruction"); + const MCExpr *FixedEntryDispExpr = FixedEntryDispOperand->getExpr(); + const uint64_t EntryAddress = getExprValue(FixedEntryDispExpr); + uint64_t EntrySize = BC.getJumpTableEntrySize(JumpTable::JTT_PIC); + ErrorOr Value = + BC.getSignedValueAtAddress(EntryAddress, EntrySize); + if (!Value) + return IndirectBranchType::UNKNOWN; + + BC.outs() << "BOLT-INFO: fixed PIC indirect branch detected in " << *this + << " at 0x" << Twine::utohexstr(getAddress() + Offset) + << " referencing data at 0x" << Twine::utohexstr(EntryAddress) + << " the destination value is 0x" + << Twine::utohexstr(ArrayStart + *Value) << '\n'; + + TargetAddress = ArrayStart + *Value; + + // Remove spurious JumpTable at EntryAddress caused by PIC reference from + // the load instruction. + BC.deleteJumpTable(EntryAddress); + + // Replace FixedEntryDispExpr used in target address calculation with outer + // jump table reference. + JumpTable *JT = BC.getJumpTableContainingAddress(ArrayStart); + assert(JT && "Must have a containing jump table for PIC fixed branch"); + BC.MIB->replaceMemOperandDisp(*FixedEntryLoadInstr, JT->getFirstLabel(), + EntryAddress - ArrayStart, &*BC.Ctx); + + return BranchType; + } + LLVM_DEBUG(dbgs() << "BOLT-DEBUG: addressed memory is 0x" << Twine::utohexstr(ArrayStart) << '\n'); @@ -1126,6 +1166,7 @@ void BinaryFunction::handleIndirectBranch(MCInst &Instruction, uint64_t Size, } case IndirectBranchType::POSSIBLE_JUMP_TABLE: case IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE: + case IndirectBranchType::POSSIBLE_PIC_FIXED_BRANCH: if (opts::JumpTables == JTS_NONE) IsSimple = false; break; @@ -1878,9 +1919,11 @@ bool BinaryFunction::postProcessIndirectBranches( int64_t DispValue; const MCExpr *DispExpr; MCInst *PCRelBaseInstr; + MCInst *FixedEntryLoadInstr; IndirectBranchType Type = BC.MIB->analyzeIndirectBranch( Instr, BB.begin(), II, PtrSize, MemLocInstr, BaseRegNum, - IndexRegNum, DispValue, DispExpr, PCRelBaseInstr); + IndexRegNum, DispValue, DispExpr, PCRelBaseInstr, + FixedEntryLoadInstr); if (Type != IndirectBranchType::UNKNOWN || MemLocInstr != nullptr) continue; diff --git a/bolt/lib/Core/DIEBuilder.cpp b/bolt/lib/Core/DIEBuilder.cpp index b0f550fd77318..69cfd58a1df04 100644 --- a/bolt/lib/Core/DIEBuilder.cpp +++ b/bolt/lib/Core/DIEBuilder.cpp @@ -78,7 +78,7 @@ static void addStringHelper(DebugStrOffsetsWriter &StrOffstsWriter, uint32_t NewOffset = StrWriter.addString(Str); if (Unit.getVersion() >= 5) { StrOffstsWriter.updateAddressMap(DIEAttrInfo.getDIEInteger().getValue(), - NewOffset); + NewOffset, Unit); return; } DIEBldr.replaceValue(&Die, DIEAttrInfo.getAttribute(), DIEAttrInfo.getForm(), @@ -461,17 +461,11 @@ getUnitForOffset(DIEBuilder &Builder, DWARFContext &DWCtx, return nullptr; } -uint32_t -DIEBuilder::finalizeDIEs(DWARFUnit &CU, DIE &Die, - std::optional Parent, - uint32_t NumberParentsInChain, uint32_t &CurOffset) { +uint32_t DIEBuilder::finalizeDIEs(DWARFUnit &CU, DIE &Die, + uint32_t &CurOffset) { getState().DWARFDieAddressesParsed.erase(Die.getOffset()); uint32_t CurSize = 0; Die.setOffset(CurOffset); - std::optional NameEntry = - DebugNamesTable.addAccelTableEntry( - CU, Die, SkeletonCU ? SkeletonCU->getDWOId() : std::nullopt, - NumberParentsInChain, Parent); // It is possible that an indexed debugging information entry has a parent // that is not indexed (for example, if its parent does not have a name // attribute). In such a case, a parent attribute may point to a nameless @@ -485,18 +479,13 @@ DIEBuilder::finalizeDIEs(DWARFUnit &CU, DIE &Die, // If Parent is nullopt and NumberParentsInChain is not zero, then forward // declaration was encountered in this DF traversal. Propagating nullopt for // Parent to children. - if (!Parent && NumberParentsInChain) - NameEntry = std::nullopt; - if (NameEntry) - ++NumberParentsInChain; for (DIEValue &Val : Die.values()) CurSize += Val.sizeOf(CU.getFormParams()); CurSize += getULEB128Size(Die.getAbbrevNumber()); CurOffset += CurSize; for (DIE &Child : Die.children()) { - uint32_t ChildSize = - finalizeDIEs(CU, Child, NameEntry, NumberParentsInChain, CurOffset); + uint32_t ChildSize = finalizeDIEs(CU, Child, CurOffset); CurSize += ChildSize; } // for children end mark. @@ -514,10 +503,9 @@ void DIEBuilder::finish() { DIE *UnitDIE = getUnitDIEbyUnit(CU); uint32_t HeaderSize = CU.getHeaderSize(); uint32_t CurOffset = HeaderSize; - DebugNamesTable.setCurrentUnit(CU, UnitStartOffset); std::vector> Parents; Parents.push_back(std::nullopt); - finalizeDIEs(CU, *UnitDIE, std::nullopt, 0, CurOffset); + finalizeDIEs(CU, *UnitDIE, CurOffset); DWARFUnitInfo &CurUnitInfo = getUnitInfoByDwarfUnit(CU); CurUnitInfo.UnitOffset = UnitStartOffset; @@ -548,6 +536,48 @@ void DIEBuilder::finish() { dbgs() << Twine::utohexstr(Address) << "\n"; } } +} + +void DIEBuilder::populateDebugNamesTable( + DWARFUnit &CU, const DIE &Die, + std::optional Parent, + uint32_t NumberParentsInChain) { + std::optional NameEntry = + DebugNamesTable.addAccelTableEntry( + CU, Die, SkeletonCU ? SkeletonCU->getDWOId() : std::nullopt, + NumberParentsInChain, Parent); + if (!Parent && NumberParentsInChain) + NameEntry = std::nullopt; + if (NameEntry) + ++NumberParentsInChain; + + for (const DIE &Child : Die.children()) + populateDebugNamesTable(CU, Child, NameEntry, NumberParentsInChain); +} + +void DIEBuilder::updateDebugNamesTable() { + auto finalizeDebugNamesTableForCU = [&](DWARFUnit &CU, + uint64_t &UnitStartOffset) -> void { + DIE *UnitDIE = getUnitDIEbyUnit(CU); + DebugNamesTable.setCurrentUnit(CU, UnitStartOffset); + populateDebugNamesTable(CU, *UnitDIE, std::nullopt, 0); + + DWARFUnitInfo &CurUnitInfo = getUnitInfoByDwarfUnit(CU); + UnitStartOffset += CurUnitInfo.UnitLength; + }; + + uint64_t TypeUnitStartOffset = 0; + for (DWARFUnit *CU : getState().DUList) { + if (!(CU->getVersion() < 5 && CU->isTypeUnit())) + break; + finalizeDebugNamesTableForCU(*CU, TypeUnitStartOffset); + } + + for (DWARFUnit *CU : getState().DUList) { + if (CU->getVersion() < 5 && CU->isTypeUnit()) + continue; + finalizeDebugNamesTableForCU(*CU, DebugNamesUnitSize); + } updateReferences(); } diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp index 002f58c474346..bd8aa807f1aae 100644 --- a/bolt/lib/Core/DebugData.cpp +++ b/bolt/lib/Core/DebugData.cpp @@ -851,7 +851,11 @@ void DebugStrOffsetsWriter::initialize(DWARFUnit &Unit) { StrOffsetsSection.Data.data() + Contr->Base + Offset)); } -void DebugStrOffsetsWriter::updateAddressMap(uint32_t Index, uint32_t Address) { +void DebugStrOffsetsWriter::updateAddressMap(uint32_t Index, uint32_t Address, + const DWARFUnit &Unit) { + assert(DebugStrOffsetFinalized.count(Unit.getOffset()) == 0 && + "Cannot update address map since debug_str_offsets was already " + "finalized for this CU."); IndexToAddressMap[Index] = Address; StrOffsetSectionWasModified = true; } @@ -906,6 +910,8 @@ void DebugStrOffsetsWriter::finalizeSection(DWARFUnit &Unit, } StrOffsetSectionWasModified = false; + assert(DebugStrOffsetFinalized.insert(Unit.getOffset()).second && + "debug_str_offsets was already finalized for this CU."); clear(); } diff --git a/bolt/lib/Core/Exceptions.cpp b/bolt/lib/Core/Exceptions.cpp index 82bddf76d5b8c..6a46a49a983d8 100644 --- a/bolt/lib/Core/Exceptions.cpp +++ b/bolt/lib/Core/Exceptions.cpp @@ -207,7 +207,7 @@ Error BinaryFunction::parseLSDA(ArrayRef LSDASectionData, "BOLT-ERROR: cannot find landing pad fragment"); BC.addInterproceduralReference(this, Fragment->getAddress()); BC.processInterproceduralReferences(); - assert(isParentOrChildOf(*Fragment) && + assert(BC.areRelatedFragments(this, Fragment) && "BOLT-ERROR: cannot have landing pads in different functions"); setHasIndirectTargetToSplitFragment(true); BC.addFragmentsToSkip(this); diff --git a/bolt/lib/Core/GDBIndex.cpp b/bolt/lib/Core/GDBIndex.cpp index 9e6d24167d559..c7fb4889646b4 100644 --- a/bolt/lib/Core/GDBIndex.cpp +++ b/bolt/lib/Core/GDBIndex.cpp @@ -23,7 +23,6 @@ void GDBIndex::updateGdbIndexSection( DebugARangesSectionWriter &ARangesSectionWriter) { if (!BC.getGdbIndexSection()) return; - // See https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html // for .gdb_index section format. @@ -141,7 +140,7 @@ void GDBIndex::updateGdbIndexSection( write64le(Buffer + 8, CUInfo.second.Length + 4); Buffer += 16; } - + sortGDBIndexTUEntryVector(); // Rewrite TU CU List, since abbrevs can be different. // Entry example: // 0: offset = 0x00000000, type_offset = 0x0000001e, type_signature = diff --git a/bolt/lib/Passes/AsmDump.cpp b/bolt/lib/Passes/AsmDump.cpp index 0a12eae8b5f7f..97f985d56ce64 100644 --- a/bolt/lib/Passes/AsmDump.cpp +++ b/bolt/lib/Passes/AsmDump.cpp @@ -139,11 +139,8 @@ void dumpFunction(const BinaryFunction &BF) { auto FOut = std::make_unique(OS); FOut->SetUnbuffered(); std::unique_ptr AsmStreamer( - createAsmStreamer(*LocalCtx, std::move(FOut), - /*isVerboseAsm=*/true, - /*useDwarfDirectory=*/false, InstructionPrinter, - std::move(MCEInstance.MCE), std::move(MAB), - /*ShowInst=*/false)); + createAsmStreamer(*LocalCtx, std::move(FOut), InstructionPrinter, + std::move(MCEInstance.MCE), std::move(MAB))); AsmStreamer->initSections(true, *BC.STI); std::unique_ptr TM(BC.TheTarget->createTargetMachine( BC.TripleName, "", "", TargetOptions(), std::nullopt)); diff --git a/bolt/lib/Passes/IndirectCallPromotion.cpp b/bolt/lib/Passes/IndirectCallPromotion.cpp index a73eb867b3777..2b5a591f4c7a2 100644 --- a/bolt/lib/Passes/IndirectCallPromotion.cpp +++ b/bolt/lib/Passes/IndirectCallPromotion.cpp @@ -386,13 +386,15 @@ IndirectCallPromotion::maybeGetHotJumpTableTargets(BinaryBasicBlock &BB, JumpTableInfoType HotTargets; MCInst *MemLocInstr; MCInst *PCRelBaseOut; + MCInst *FixedEntryLoadInstr; unsigned BaseReg, IndexReg; int64_t DispValue; const MCExpr *DispExpr; MutableArrayRef Insts(&BB.front(), &CallInst); const IndirectBranchType Type = BC.MIB->analyzeIndirectBranch( CallInst, Insts.begin(), Insts.end(), BC.AsmInfo->getCodePointerSize(), - MemLocInstr, BaseReg, IndexReg, DispValue, DispExpr, PCRelBaseOut); + MemLocInstr, BaseReg, IndexReg, DispValue, DispExpr, PCRelBaseOut, + FixedEntryLoadInstr); assert(MemLocInstr && "There should always be a load for jump tables"); if (!MemLocInstr) diff --git a/bolt/lib/Profile/CMakeLists.txt b/bolt/lib/Profile/CMakeLists.txt index 39708baac4036..9aa4ba0490b0f 100644 --- a/bolt/lib/Profile/CMakeLists.txt +++ b/bolt/lib/Profile/CMakeLists.txt @@ -11,6 +11,7 @@ add_llvm_library(LLVMBOLTProfile LINK_COMPONENTS Demangle + MC Support TransformUtils ) diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp index ce6ec0a04ac16..a300e5b2b1dab 100644 --- a/bolt/lib/Profile/DataAggregator.cpp +++ b/bolt/lib/Profile/DataAggregator.cpp @@ -88,6 +88,7 @@ MaxSamples("max-samples", cl::cat(AggregatorCategory)); extern cl::opt ProfileFormat; +extern cl::opt ProfileUsePseudoProbes; extern cl::opt SaveProfile; cl::opt ReadPreAggregated( @@ -2298,6 +2299,9 @@ std::error_code DataAggregator::writeBATYAML(BinaryContext &BC, yaml::bolt::BinaryProfile BP; + const MCPseudoProbeDecoder *PseudoProbeDecoder = + opts::ProfileUsePseudoProbes ? BC.getPseudoProbeDecoder() : nullptr; + // Fill out the header info. BP.Header.Version = 1; BP.Header.FileName = std::string(BC.getFilename()); @@ -2398,6 +2402,33 @@ std::error_code DataAggregator::writeBATYAML(BinaryContext &BC, const unsigned BlockIndex = BlockMap.getBBIndex(BI.To.Offset); YamlBF.Blocks[BlockIndex].ExecCount += BI.Branches; } + if (PseudoProbeDecoder) { + if ((YamlBF.GUID = BF->getGUID())) { + const MCPseudoProbeFuncDesc *FuncDesc = + PseudoProbeDecoder->getFuncDescForGUID(YamlBF.GUID); + YamlBF.PseudoProbeDescHash = FuncDesc->FuncHash; + } + // Fetch probes belonging to all fragments + const AddressProbesMap &ProbeMap = + PseudoProbeDecoder->getAddress2ProbesMap(); + BinaryFunction::FragmentsSetTy Fragments(BF->Fragments); + Fragments.insert(BF); + for (const BinaryFunction *F : Fragments) { + const uint64_t FuncAddr = F->getAddress(); + const auto &FragmentProbes = + llvm::make_range(ProbeMap.lower_bound(FuncAddr), + ProbeMap.lower_bound(FuncAddr + F->getSize())); + for (const auto &[OutputAddress, Probes] : FragmentProbes) { + const uint32_t InputOffset = BAT->translate( + FuncAddr, OutputAddress - FuncAddr, /*IsBranchSrc=*/true); + const unsigned BlockIndex = getBlock(InputOffset).second; + for (const MCDecodedPseudoProbe &Probe : Probes) + YamlBF.Blocks[BlockIndex].PseudoProbes.emplace_back( + yaml::bolt::PseudoProbeInfo{Probe.getGuid(), Probe.getIndex(), + Probe.getType()}); + } + } + } // Drop blocks without a hash, won't be useful for stale matching. llvm::erase_if(YamlBF.Blocks, [](const yaml::bolt::BinaryBasicBlockProfile &YamlBB) { diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp index d9a6998bc5e9f..3eca5e972fa5b 100644 --- a/bolt/lib/Profile/YAMLProfileReader.cpp +++ b/bolt/lib/Profile/YAMLProfileReader.cpp @@ -41,15 +41,87 @@ llvm::cl::opt MatchProfileWithFunctionHash("match-profile-with-function-hash", cl::desc("Match profile with function hash"), cl::Hidden, cl::cat(BoltOptCategory)); +llvm::cl::opt + MatchWithCallGraph("match-with-call-graph", + cl::desc("Match functions with call graph"), cl::Hidden, + cl::cat(BoltOptCategory)); llvm::cl::opt ProfileUseDFS("profile-use-dfs", cl::desc("use DFS order for YAML profile"), cl::Hidden, cl::cat(BoltOptCategory)); + +llvm::cl::opt ProfileUsePseudoProbes( + "profile-use-pseudo-probes", + cl::desc("Use pseudo probes for profile generation and matching"), + cl::Hidden, cl::cat(BoltOptCategory)); } // namespace opts namespace llvm { namespace bolt { +YAMLProfileReader::CallGraphMatcher::CallGraphMatcher( + BinaryContext &BC, yaml::bolt::BinaryProfile &YamlBP, + ProfileLookupMap &IdToYAMLBF) { + constructBFCG(BC, YamlBP); + constructYAMLFCG(YamlBP, IdToYAMLBF); + computeBFNeighborHashes(BC); +} + +void YAMLProfileReader::CallGraphMatcher::constructBFCG( + BinaryContext &BC, yaml::bolt::BinaryProfile &YamlBP) { + for (BinaryFunction *BF : BC.getAllBinaryFunctions()) { + for (const BinaryBasicBlock &BB : BF->blocks()) { + for (const MCInst &Instr : BB) { + if (!BC.MIB->isCall(Instr)) + continue; + const MCSymbol *CallSymbol = BC.MIB->getTargetSymbol(Instr); + if (!CallSymbol) + continue; + BinaryData *BD = BC.getBinaryDataByName(CallSymbol->getName()); + if (!BD) + continue; + BinaryFunction *CalleeBF = BC.getFunctionForSymbol(BD->getSymbol()); + if (!CalleeBF) + continue; + + BFAdjacencyMap[CalleeBF].insert(BF); + BFAdjacencyMap[BF].insert(CalleeBF); + } + } + } +} + +void YAMLProfileReader::CallGraphMatcher::computeBFNeighborHashes( + BinaryContext &BC) { + for (BinaryFunction *BF : BC.getAllBinaryFunctions()) { + auto It = BFAdjacencyMap.find(BF); + if (It == BFAdjacencyMap.end()) + continue; + auto &AdjacentBFs = It->second; + std::string HashStr; + for (BinaryFunction *BF : AdjacentBFs) + HashStr += BF->getOneName(); + uint64_t Hash = std::hash{}(HashStr); + NeighborHashToBFs[Hash].push_back(BF); + } +} + +void YAMLProfileReader::CallGraphMatcher::constructYAMLFCG( + yaml::bolt::BinaryProfile &YamlBP, ProfileLookupMap &IdToYAMLBF) { + + for (auto &CallerYamlBF : YamlBP.Functions) { + for (auto &YamlBB : CallerYamlBF.Blocks) { + for (auto &CallSite : YamlBB.CallSites) { + auto IdToYAMLBFIt = IdToYAMLBF.find(CallSite.DestId); + if (IdToYAMLBFIt == IdToYAMLBF.end()) + continue; + YamlBFAdjacencyMap[&CallerYamlBF].insert(IdToYAMLBFIt->second); + YamlBFAdjacencyMap[IdToYAMLBFIt->second].insert(&CallerYamlBF); + } + } + } +} + bool YAMLProfileReader::isYAML(const StringRef Filename) { if (auto MB = MemoryBuffer::getFileOrSTDIN(Filename)) { StringRef Buffer = (*MB)->getBuffer(); @@ -350,7 +422,7 @@ bool YAMLProfileReader::profileMatches( } bool YAMLProfileReader::mayHaveProfileData(const BinaryFunction &BF) { - if (opts::MatchProfileWithFunctionHash) + if (opts::MatchProfileWithFunctionHash || opts::MatchWithCallGraph) return true; for (StringRef Name : BF.getNames()) if (ProfileFunctionNames.contains(Name)) @@ -446,6 +518,79 @@ size_t YAMLProfileReader::matchWithLTOCommonName() { return MatchedWithLTOCommonName; } +size_t YAMLProfileReader::matchWithCallGraph(BinaryContext &BC) { + if (!opts::MatchWithCallGraph) + return 0; + + size_t MatchedWithCallGraph = 0; + CallGraphMatcher CGMatcher(BC, YamlBP, IdToYamLBF); + + ItaniumPartialDemangler Demangler; + auto GetBaseName = [&](std::string &FunctionName) { + if (Demangler.partialDemangle(FunctionName.c_str())) + return std::string(""); + size_t BufferSize = 1; + char *Buffer = static_cast(std::malloc(BufferSize)); + char *BaseName = Demangler.getFunctionBaseName(Buffer, &BufferSize); + if (!BaseName) { + std::free(Buffer); + return std::string(""); + } + if (Buffer != BaseName) + Buffer = BaseName; + std::string BaseNameStr(Buffer, BufferSize); + std::free(Buffer); + return BaseNameStr; + }; + + // Matches YAMLBF to BFs with neighbor hashes. + for (yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions) { + if (YamlBF.Used) + continue; + auto AdjacentYamlBFsOpt = CGMatcher.getAdjacentYamlBFs(YamlBF); + if (!AdjacentYamlBFsOpt) + continue; + std::set AdjacentYamlBFs = + AdjacentYamlBFsOpt.value(); + std::string AdjacentYamlBFsHashStr; + for (auto *AdjacentYamlBF : AdjacentYamlBFs) + AdjacentYamlBFsHashStr += AdjacentYamlBF->Name; + uint64_t Hash = std::hash{}(AdjacentYamlBFsHashStr); + auto BFsWithSameHashOpt = CGMatcher.getBFsWithNeighborHash(Hash); + if (!BFsWithSameHashOpt) + continue; + std::vector BFsWithSameHash = BFsWithSameHashOpt.value(); + // Finds the binary function with the longest common prefix to the profiled + // function and matches. + BinaryFunction *ClosestBF = nullptr; + size_t LCP = 0; + std::string YamlBFBaseName = GetBaseName(YamlBF.Name); + for (BinaryFunction *BF : BFsWithSameHash) { + if (ProfiledFunctions.count(BF)) + continue; + std::string BFName = std::string(BF->getOneName()); + std::string BFBaseName = GetBaseName(BFName); + size_t PrefixLength = 0; + size_t N = std::min(YamlBFBaseName.size(), BFBaseName.size()); + for (size_t I = 0; I < N; ++I) { + if (YamlBFBaseName[I] != BFBaseName[I]) + break; + ++PrefixLength; + } + if (PrefixLength >= LCP) { + LCP = PrefixLength; + ClosestBF = BF; + } + } + if (ClosestBF) { + matchProfileToFunction(YamlBF, *ClosestBF); + ++MatchedWithCallGraph; + } + } + + return MatchedWithCallGraph; +} + size_t YAMLProfileReader::matchWithNameSimilarity(BinaryContext &BC) { if (opts::NameSimilarityFunctionMatchingThreshold == 0) return 0; @@ -581,9 +726,14 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) { } } + // Map profiled function ids to names. + for (yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions) + IdToYamLBF[YamlBF.Id] = &YamlBF; + const size_t MatchedWithExactName = matchWithExactName(); const size_t MatchedWithHash = matchWithHash(BC); const size_t MatchedWithLTOCommonName = matchWithLTOCommonName(); + const size_t MatchedWithCallGraph = matchWithCallGraph(BC); const size_t MatchedWithNameSimilarity = matchWithNameSimilarity(BC); for (auto [YamlBF, BF] : llvm::zip_equal(YamlBP.Functions, ProfileBFs)) @@ -603,6 +753,8 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) { << " functions with hash\n"; outs() << "BOLT-INFO: matched " << MatchedWithLTOCommonName << " functions with matching LTO common names\n"; + outs() << "BOLT-INFO: matched " << MatchedWithCallGraph + << " functions with call graph\n"; outs() << "BOLT-INFO: matched " << MatchedWithNameSimilarity << " functions with similar names\n"; } @@ -610,11 +762,6 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) { // Set for parseFunctionProfile(). NormalizeByInsnCount = usesEvent("cycles") || usesEvent("instructions"); NormalizeByCalls = usesEvent("branches"); - - // Map profiled function ids to names. - for (yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions) - IdToYamLBF[YamlBF.Id] = &YamlBF; - uint64_t NumUnused = 0; for (yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions) { if (YamlBF.Id >= YamlProfileToFunction.size()) { @@ -630,7 +777,8 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) { BC.setNumUnusedProfiledObjects(NumUnused); - if (opts::Lite && opts::MatchProfileWithFunctionHash) { + if (opts::Lite && + (opts::MatchProfileWithFunctionHash || opts::MatchWithCallGraph)) { for (BinaryFunction *BF : BC.getAllBinaryFunctions()) if (!BF->hasProfile()) BF->setIgnored(); diff --git a/bolt/lib/Profile/YAMLProfileWriter.cpp b/bolt/lib/Profile/YAMLProfileWriter.cpp index 9adbfdc5ff089..84777741d611a 100644 --- a/bolt/lib/Profile/YAMLProfileWriter.cpp +++ b/bolt/lib/Profile/YAMLProfileWriter.cpp @@ -22,6 +22,7 @@ namespace opts { extern llvm::cl::opt ProfileUseDFS; +extern llvm::cl::opt ProfileUsePseudoProbes; } // namespace opts namespace llvm { @@ -57,6 +58,8 @@ YAMLProfileWriter::convert(const BinaryFunction &BF, bool UseDFS, const BoltAddressTranslation *BAT) { yaml::bolt::BinaryFunctionProfile YamlBF; const BinaryContext &BC = BF.getBinaryContext(); + const MCPseudoProbeDecoder *PseudoProbeDecoder = + opts::ProfileUsePseudoProbes ? BC.getPseudoProbeDecoder() : nullptr; const uint16_t LBRProfile = BF.getProfileFlags() & BinaryFunction::PF_LBR; @@ -69,6 +72,13 @@ YAMLProfileWriter::convert(const BinaryFunction &BF, bool UseDFS, YamlBF.Hash = BF.getHash(); YamlBF.NumBasicBlocks = BF.size(); YamlBF.ExecCount = BF.getKnownExecutionCount(); + if (PseudoProbeDecoder) { + if ((YamlBF.GUID = BF.getGUID())) { + const MCPseudoProbeFuncDesc *FuncDesc = + PseudoProbeDecoder->getFuncDescForGUID(YamlBF.GUID); + YamlBF.PseudoProbeDescHash = FuncDesc->FuncHash; + } + } BinaryFunction::BasicBlockOrderType Order; llvm::copy(UseDFS ? BF.dfs() : BF.getLayout().blocks(), @@ -177,6 +187,21 @@ YAMLProfileWriter::convert(const BinaryFunction &BF, bool UseDFS, ++BranchInfo; } + if (PseudoProbeDecoder) { + const AddressProbesMap &ProbeMap = + PseudoProbeDecoder->getAddress2ProbesMap(); + const uint64_t FuncAddr = BF.getAddress(); + const std::pair &BlockRange = + BB->getInputAddressRange(); + const auto &BlockProbes = + llvm::make_range(ProbeMap.lower_bound(FuncAddr + BlockRange.first), + ProbeMap.lower_bound(FuncAddr + BlockRange.second)); + for (const auto &[_, Probes] : BlockProbes) + for (const MCDecodedPseudoProbe &Probe : Probes) + YamlBB.PseudoProbes.emplace_back(yaml::bolt::PseudoProbeInfo{ + Probe.getGuid(), Probe.getIndex(), Probe.getType()}); + } + YamlBF.Blocks.emplace_back(YamlBB); } return YamlBF; diff --git a/bolt/lib/Rewrite/BinaryPassManager.cpp b/bolt/lib/Rewrite/BinaryPassManager.cpp index aaa0e1ff4d46f..5dfef0b71cc79 100644 --- a/bolt/lib/Rewrite/BinaryPassManager.cpp +++ b/bolt/lib/Rewrite/BinaryPassManager.cpp @@ -263,6 +263,10 @@ static cl::opt CMOVConversionFlag("cmov-conversion", cl::ReallyHidden, cl::cat(BoltOptCategory)); +static cl::opt ShortenInstructions("shorten-instructions", + cl::desc("shorten instructions"), + cl::init(true), + cl::cat(BoltOptCategory)); } // namespace opts namespace llvm { @@ -378,7 +382,8 @@ Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) { else if (opts::Hugify) Manager.registerPass(std::make_unique(NeverPrint)); - Manager.registerPass(std::make_unique(NeverPrint)); + Manager.registerPass(std::make_unique(NeverPrint), + opts::ShortenInstructions); Manager.registerPass(std::make_unique(NeverPrint), !opts::KeepNops); diff --git a/bolt/lib/Rewrite/CMakeLists.txt b/bolt/lib/Rewrite/CMakeLists.txt index 34993af2623bf..5d114925f59b0 100644 --- a/bolt/lib/Rewrite/CMakeLists.txt +++ b/bolt/lib/Rewrite/CMakeLists.txt @@ -1,7 +1,6 @@ set(LLVM_LINK_COMPONENTS Core DebugInfoDWARF - DWP JITLink MC Object diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp index 042c39a574561..98f81f44d6490 100644 --- a/bolt/lib/Rewrite/DWARFRewriter.cpp +++ b/bolt/lib/Rewrite/DWARFRewriter.cpp @@ -32,6 +32,7 @@ #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCTargetOptionsCommandFlags.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" @@ -56,6 +57,8 @@ #undef DEBUG_TYPE #define DEBUG_TYPE "bolt" +static mc::RegisterMCTargetOptionsFlags MOF; + static void printDie(const DWARFDie &DIE) { DIDumpOptions DumpOpts; DumpOpts.ShowForm = true; @@ -326,22 +329,10 @@ static cl::opt KeepARanges( "keep or generate .debug_aranges section if .gdb_index is written"), cl::Hidden, cl::cat(BoltCategory)); -static cl::opt DeterministicDebugInfo( - "deterministic-debuginfo", - cl::desc("disables parallel execution of tasks that may produce " - "nondeterministic debug info"), - cl::init(true), cl::cat(BoltCategory)); - static cl::opt DwarfOutputPath( "dwarf-output-path", - cl::desc("Path to where .dwo files or dwp file will be written out to."), - cl::init(""), cl::cat(BoltCategory)); - -static cl::opt - WriteDWP("write-dwp", - cl::desc("output a single dwarf package file (dwp) instead of " - "multiple non-relocatable dwarf object files (dwo)."), - cl::init(false), cl::cat(BoltCategory)); + cl::desc("Path to where .dwo files will be written out to."), cl::init(""), + cl::cat(BoltCategory)); static cl::opt CreateDebugNames( "create-debug-names-section", @@ -473,23 +464,19 @@ createDIEStreamer(const Triple &TheTriple, raw_pwrite_stream &OutFile, return Streamer; } -static DWARFRewriter::UnitMeta -emitUnit(DIEBuilder &DIEBldr, DIEStreamer &Streamer, DWARFUnit &Unit) { +static void emitUnit(DIEBuilder &DIEBldr, DIEStreamer &Streamer, + DWARFUnit &Unit) { DIE *UnitDIE = DIEBldr.getUnitDIEbyUnit(Unit); - const DIEBuilder::DWARFUnitInfo &U = DIEBldr.getUnitInfoByDwarfUnit(Unit); Streamer.emitUnit(Unit, *UnitDIE); - uint64_t TypeHash = 0; - if (DWARFTypeUnit *DTU = dyn_cast_or_null(&Unit)) - TypeHash = DTU->getTypeHash(); - return {U.UnitOffset, U.UnitLength, TypeHash}; } -static void -emitDWOBuilder(const std::string &DWOName, DIEBuilder &DWODIEBuilder, - DWARFRewriter &Rewriter, DWARFUnit &SplitCU, DWARFUnit &CU, - DWARFRewriter::DWPState &State, DebugLocWriter &LocWriter, - DebugStrOffsetsWriter &StrOffstsWriter, - DebugStrWriter &StrWriter, GDBIndex &GDBIndexSection) { +static void emitDWOBuilder(const std::string &DWOName, + DIEBuilder &DWODIEBuilder, DWARFRewriter &Rewriter, + DWARFUnit &SplitCU, DWARFUnit &CU, + DebugLocWriter &LocWriter, + DebugStrOffsetsWriter &StrOffstsWriter, + DebugStrWriter &StrWriter, + GDBIndex &GDBIndexSection) { // Populate debug_info and debug_abbrev for current dwo into StringRef. DWODIEBuilder.generateAbbrevs(); DWODIEBuilder.finish(); @@ -502,28 +489,22 @@ emitDWOBuilder(const std::string &DWOName, DIEBuilder &DWODIEBuilder, std::unique_ptr Streamer = createDIEStreamer(*TheTriple, *ObjOS, "DwoStreamerInitAug2", DWODIEBuilder, GDBIndexSection); - DWARFRewriter::UnitMetaVectorType TUMetaVector; - DWARFRewriter::UnitMeta CUMI = {0, 0, 0}; if (SplitCU.getContext().getMaxDWOVersion() >= 5) { for (std::unique_ptr &CU : SplitCU.getContext().dwo_info_section_units()) { if (!CU->isTypeUnit()) continue; - DWARFRewriter::UnitMeta MI = - emitUnit(DWODIEBuilder, *Streamer, *CU.get()); - TUMetaVector.emplace_back(MI); + emitUnit(DWODIEBuilder, *Streamer, *CU.get()); } - CUMI = emitUnit(DWODIEBuilder, *Streamer, SplitCU); + emitUnit(DWODIEBuilder, *Streamer, SplitCU); } else { for (std::unique_ptr &CU : SplitCU.getContext().dwo_compile_units()) emitUnit(DWODIEBuilder, *Streamer, *CU.get()); // emit debug_types sections for dwarf4 - for (DWARFUnit *CU : DWODIEBuilder.getDWARF4TUVector()) { - DWARFRewriter::UnitMeta MI = emitUnit(DWODIEBuilder, *Streamer, *CU); - TUMetaVector.emplace_back(MI); - } + for (DWARFUnit *CU : DWODIEBuilder.getDWARF4TUVector()) + emitUnit(DWODIEBuilder, *Streamer, *CU); } Streamer->emitAbbrevs(DWODIEBuilder.getAbbrevs(), @@ -550,12 +531,8 @@ emitDWOBuilder(const std::string &DWOName, DIEBuilder &DWODIEBuilder, continue; OverriddenSections[Kind] = Contents; } - if (opts::WriteDWP) - Rewriter.updateDWP(CU, OverriddenSections, CUMI, TUMetaVector, State, - LocWriter, StrOffstsWriter, StrWriter); - else - Rewriter.writeDWOFiles(CU, OverriddenSections, DWOName, LocWriter, - StrOffstsWriter, StrWriter); + Rewriter.writeDWOFiles(CU, OverriddenSections, DWOName, LocWriter, + StrOffstsWriter, StrWriter); } using DWARFUnitVec = std::vector; @@ -607,11 +584,6 @@ void DWARFRewriter::updateDebugInfo() { StrWriter = std::make_unique(*BC.DwCtx, false); StrOffstsWriter = std::make_unique(BC); - if (!opts::DeterministicDebugInfo) { - opts::DeterministicDebugInfo = true; - errs() << "BOLT-WARNING: --deterministic-debuginfo is being deprecated\n"; - } - /// Stores and serializes information that will be put into the /// .debug_addr DWARF section. std::unique_ptr FinalAddrWriter; @@ -631,8 +603,8 @@ void DWARFRewriter::updateDebugInfo() { uint32_t CUIndex = 0; std::mutex AccessMutex; // Needs to be invoked in the same order as CUs are processed. - auto createRangeLocListAddressWriters = - [&](DWARFUnit &CU) -> DebugLocWriter * { + llvm::DenseMap LocListWritersIndexByCU; + auto createRangeLocListAddressWriters = [&](DWARFUnit &CU) { std::lock_guard Lock(AccessMutex); const uint16_t DwarfVersion = CU.getVersion(); if (DwarfVersion >= 5) { @@ -652,7 +624,6 @@ void DWARFRewriter::updateDebugInfo() { RangeListsWritersByCU[*DWOId] = std::move(DWORangeListsSectionWriter); } AddressWritersByCU[CU.getOffset()] = std::move(AddrW); - } else { auto AddrW = std::make_unique(&BC, CU.getAddressByteSize()); @@ -668,84 +639,68 @@ void DWARFRewriter::updateDebugInfo() { std::move(LegacyRangesSectionWriterByCU); } } - return LocListWritersByCU[CUIndex++].get(); + LocListWritersIndexByCU[CU.getOffset()] = CUIndex++; }; DWARF5AcceleratorTable DebugNamesTable(opts::CreateDebugNames, BC, *StrWriter); GDBIndex GDBIndexSection(BC); - DWPState State; - if (opts::WriteDWP) - initDWPState(State); - auto processUnitDIE = [&](DWARFUnit *Unit, DIEBuilder *DIEBlder) { - // Check if the unit is a skeleton and we need special updates for it and - // its matching split/DWO CU. + auto processSplitCU = [&](DWARFUnit &Unit, DWARFUnit &SplitCU, + DIEBuilder &DIEBlder, + DebugRangesSectionWriter &TempRangesSectionWriter, + DebugAddrWriter &AddressWriter, + const std::string &DWOName, + const std::optional &DwarfOutputPath, + DIEBuilder &DWODIEBuilder) { + DWODIEBuilder.buildDWOUnit(SplitCU); + DebugStrOffsetsWriter DWOStrOffstsWriter(BC); + DebugStrWriter DWOStrWriter((SplitCU).getContext(), true); + DWODIEBuilder.updateDWONameCompDirForTypes( + DWOStrOffstsWriter, DWOStrWriter, SplitCU, DwarfOutputPath, DWOName); + DebugLoclistWriter DebugLocDWoWriter(Unit, Unit.getVersion(), true, + AddressWriter); + + updateUnitDebugInfo(SplitCU, DWODIEBuilder, DebugLocDWoWriter, + TempRangesSectionWriter, AddressWriter); + DebugLocDWoWriter.finalize(DWODIEBuilder, + *DWODIEBuilder.getUnitDIEbyUnit(SplitCU)); + if (Unit.getVersion() >= 5) + TempRangesSectionWriter.finalizeSection(); + + emitDWOBuilder(DWOName, DWODIEBuilder, *this, SplitCU, Unit, + DebugLocDWoWriter, DWOStrOffstsWriter, DWOStrWriter, + GDBIndexSection); + }; + auto processMainBinaryCU = [&](DWARFUnit &Unit, DIEBuilder &DIEBlder) { std::optional SplitCU; std::optional RangesBase; - std::optional DWOId = Unit->getDWOId(); + std::optional DWOId = Unit.getDWOId(); if (DWOId) SplitCU = BC.getDWOCU(*DWOId); - DebugLocWriter *DebugLocWriter = createRangeLocListAddressWriters(*Unit); - DebugRangesSectionWriter *RangesSectionWriter = - Unit->getVersion() >= 5 ? RangeListsSectionWriter.get() - : LegacyRangesSectionWriter.get(); - DebugAddrWriter *AddressWriter = - AddressWritersByCU[Unit->getOffset()].get(); - // Skipping CUs that failed to load. - if (SplitCU) { - DIEBuilder DWODIEBuilder(BC, &(*SplitCU)->getContext(), DebugNamesTable, - Unit); - DWODIEBuilder.buildDWOUnit(**SplitCU); - std::string DWOName = ""; - std::optional DwarfOutputPath = - opts::DwarfOutputPath.empty() - ? std::nullopt - : std::optional(opts::DwarfOutputPath.c_str()); - { - std::lock_guard Lock(AccessMutex); - DWOName = DIEBlder->updateDWONameCompDir( - *StrOffstsWriter, *StrWriter, *Unit, DwarfOutputPath, std::nullopt); - } - DebugStrOffsetsWriter DWOStrOffstsWriter(BC); - DebugStrWriter DWOStrWriter((*SplitCU)->getContext(), true); - DWODIEBuilder.updateDWONameCompDirForTypes(DWOStrOffstsWriter, - DWOStrWriter, **SplitCU, - DwarfOutputPath, DWOName); - DebugLoclistWriter DebugLocDWoWriter(*Unit, Unit->getVersion(), true, - *AddressWriter); - DebugRangesSectionWriter *TempRangesSectionWriter = RangesSectionWriter; - if (Unit->getVersion() >= 5) { - TempRangesSectionWriter = RangeListsWritersByCU[*DWOId].get(); - } else { - TempRangesSectionWriter = LegacyRangesWritersByCU[*DWOId].get(); - RangesBase = RangesSectionWriter->getSectionOffset(); - setDwoRangesBase(*DWOId, *RangesBase); - } - - updateUnitDebugInfo(*(*SplitCU), DWODIEBuilder, DebugLocDWoWriter, - *TempRangesSectionWriter, *AddressWriter); - DebugLocDWoWriter.finalize(DWODIEBuilder, - *DWODIEBuilder.getUnitDIEbyUnit(**SplitCU)); - if (Unit->getVersion() >= 5) - TempRangesSectionWriter->finalizeSection(); - - emitDWOBuilder(DWOName, DWODIEBuilder, *this, **SplitCU, *Unit, State, - DebugLocDWoWriter, DWOStrOffstsWriter, DWOStrWriter, - GDBIndexSection); - } - - if (Unit->getVersion() >= 5) { - RangesBase = RangesSectionWriter->getSectionOffset() + + DebugLocWriter &DebugLocWriter = + *LocListWritersByCU[LocListWritersIndexByCU[Unit.getOffset()]].get(); + DebugRangesSectionWriter &RangesSectionWriter = + Unit.getVersion() >= 5 ? *RangeListsSectionWriter.get() + : *LegacyRangesSectionWriter.get(); + DebugAddrWriter &AddressWriter = + *AddressWritersByCU[Unit.getOffset()].get(); + if (Unit.getVersion() >= 5) + RangeListsSectionWriter->setAddressWriter(&AddressWriter); + if (Unit.getVersion() >= 5) { + RangesBase = RangesSectionWriter.getSectionOffset() + getDWARF5RngListLocListHeaderSize(); - RangesSectionWriter->initSection(*Unit); - StrOffstsWriter->finalizeSection(*Unit, *DIEBlder); + RangesSectionWriter.initSection(Unit); + if (!SplitCU) + StrOffstsWriter->finalizeSection(Unit, DIEBlder); + } else if (SplitCU) { + RangesBase = LegacyRangesSectionWriter.get()->getSectionOffset(); } - updateUnitDebugInfo(*Unit, *DIEBlder, *DebugLocWriter, *RangesSectionWriter, - *AddressWriter, RangesBase); - DebugLocWriter->finalize(*DIEBlder, *DIEBlder->getUnitDIEbyUnit(*Unit)); - if (Unit->getVersion() >= 5) - RangesSectionWriter->finalizeSection(); + updateUnitDebugInfo(Unit, DIEBlder, DebugLocWriter, RangesSectionWriter, + AddressWriter, RangesBase); + DebugLocWriter.finalize(DIEBlder, *DIEBlder.getUnitDIEbyUnit(Unit)); + if (Unit.getVersion() >= 5) + RangesSectionWriter.finalizeSection(); }; DIEBuilder DIEBlder(BC, BC.DwCtx.get(), DebugNamesTable); @@ -760,32 +715,48 @@ void DWARFRewriter::updateDebugInfo() { CUOffsetMap OffsetMap = finalizeTypeSections(DIEBlder, *Streamer, GDBIndexSection); - const bool SingleThreadedMode = - opts::NoThreads || opts::DeterministicDebugInfo; - if (!SingleThreadedMode) - DIEBlder.buildCompileUnits(); - if (SingleThreadedMode) { - CUPartitionVector PartVec = partitionCUs(*BC.DwCtx); - for (std::vector &Vec : PartVec) { - DIEBlder.buildCompileUnits(Vec); - for (DWARFUnit *CU : DIEBlder.getProcessedCUs()) - processUnitDIE(CU, &DIEBlder); - finalizeCompileUnits(DIEBlder, *Streamer, OffsetMap, - DIEBlder.getProcessedCUs(), *FinalAddrWriter); + CUPartitionVector PartVec = partitionCUs(*BC.DwCtx); + for (std::vector &Vec : PartVec) { + DIEBlder.buildCompileUnits(Vec); + llvm::SmallVector, 72> DWODIEBuildersByCU; + for (DWARFUnit *CU : DIEBlder.getProcessedCUs()) { + createRangeLocListAddressWriters(*CU); + std::optional SplitCU; + std::optional DWOId = CU->getDWOId(); + if (DWOId) + SplitCU = BC.getDWOCU(*DWOId); + if (!SplitCU) + continue; + DebugAddrWriter &AddressWriter = + *AddressWritersByCU[CU->getOffset()].get(); + DebugRangesSectionWriter *TempRangesSectionWriter = + CU->getVersion() >= 5 ? RangeListsWritersByCU[*DWOId].get() + : LegacyRangesWritersByCU[*DWOId].get(); + std::optional DwarfOutputPath = + opts::DwarfOutputPath.empty() + ? std::nullopt + : std::optional(opts::DwarfOutputPath.c_str()); + std::string DWOName = DIEBlder.updateDWONameCompDir( + *StrOffstsWriter, *StrWriter, *CU, DwarfOutputPath, std::nullopt); + auto DWODIEBuilderPtr = std::make_unique( + BC, &(**SplitCU).getContext(), DebugNamesTable, CU); + DIEBuilder &DWODIEBuilder = + *DWODIEBuildersByCU.emplace_back(std::move(DWODIEBuilderPtr)).get(); + if (CU->getVersion() >= 5) + StrOffstsWriter->finalizeSection(*CU, DIEBlder); + processSplitCU(*CU, **SplitCU, DIEBlder, *TempRangesSectionWriter, + AddressWriter, DWOName, DwarfOutputPath, DWODIEBuilder); } - } else { - // Update unit debug info in parallel - ThreadPoolInterface &ThreadPool = ParallelUtilities::getThreadPool(); - for (std::unique_ptr &CU : BC.DwCtx->compile_units()) - ThreadPool.async(processUnitDIE, CU.get(), &DIEBlder); - ThreadPool.wait(); + for (std::unique_ptr &DWODIEBuilderPtr : DWODIEBuildersByCU) + DWODIEBuilderPtr->updateDebugNamesTable(); + for (DWARFUnit *CU : DIEBlder.getProcessedCUs()) + processMainBinaryCU(*CU, DIEBlder); + finalizeCompileUnits(DIEBlder, *Streamer, OffsetMap, + DIEBlder.getProcessedCUs(), *FinalAddrWriter); } DebugNamesTable.emitAccelTable(); - if (opts::WriteDWP) - finalizeDWP(State); - finalizeDebugSections(DIEBlder, DebugNamesTable, *Streamer, *ObjOS, OffsetMap, *FinalAddrWriter); GDBIndexSection.updateGdbIndexSection(OffsetMap, CUIndex, @@ -1477,6 +1448,7 @@ CUOffsetMap DWARFRewriter::finalizeTypeSections(DIEBuilder &DIEBlder, // generate and populate abbrevs here DIEBlder.generateAbbrevs(); DIEBlder.finish(); + DIEBlder.updateDebugNamesTable(); SmallVector OutBuffer; std::shared_ptr ObjOS = std::make_shared(OutBuffer); @@ -1681,6 +1653,7 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder, } DIEBlder.generateAbbrevs(); DIEBlder.finish(); + DIEBlder.updateDebugNamesTable(); // generate debug_info and CUMap for (DWARFUnit *CU : CUs) { emitUnit(DIEBlder, Streamer, *CU); @@ -1831,220 +1804,6 @@ std::optional updateDebugData( } // namespace -void DWARFRewriter::initDWPState(DWPState &State) { - SmallString<0> OutputNameStr; - StringRef OutputName; - if (opts::DwarfOutputPath.empty()) { - OutputName = - Twine(opts::OutputFilename).concat(".dwp").toStringRef(OutputNameStr); - } else { - StringRef ExeFileName = llvm::sys::path::filename(opts::OutputFilename); - OutputName = Twine(opts::DwarfOutputPath) - .concat("/") - .concat(ExeFileName) - .concat(".dwp") - .toStringRef(OutputNameStr); - errs() << "BOLT-WARNING: dwarf-output-path is in effect and .dwp file will " - "possibly be written to another location that is not the same as " - "the executable\n"; - } - std::error_code EC; - State.Out = - std::make_unique(OutputName, EC, sys::fs::OF_None); - const object::ObjectFile *File = BC.DwCtx->getDWARFObj().getFile(); - State.TmpBC = createDwarfOnlyBC(*File); - State.Streamer = State.TmpBC->createStreamer(State.Out->os()); - State.MCOFI = State.Streamer->getContext().getObjectFileInfo(); - State.KnownSections = createKnownSectionsMap(*State.MCOFI); - MCSection *const StrSection = State.MCOFI->getDwarfStrDWOSection(); - - // Data Structures for DWP book keeping - // Size of array corresponds to the number of sections supported by DWO format - // in DWARF4/5. - - State.Strings = std::make_unique(*State.Streamer, StrSection); - - // Setup DWP code once. - DWARFContext *DWOCtx = BC.getDWOContext(); - - if (DWOCtx) { - State.CUIndex = &DWOCtx->getCUIndex(); - State.IsDWP = !State.CUIndex->getRows().empty(); - } -} - -void DWARFRewriter::finalizeDWP(DWPState &State) { - if (State.Version < 5) { - // Lie about there being no info contributions so the TU index only includes - // the type unit contribution for DWARF < 5. In DWARFv5 the TU index has a - // contribution to the info section, so we do not want to lie about it. - State.ContributionOffsets[0] = 0; - } - writeIndex(*State.Streamer.get(), State.MCOFI->getDwarfTUIndexSection(), - State.ContributionOffsets, State.TypeIndexEntries, - State.IndexVersion); - - if (State.Version < 5) { - // Lie about the type contribution for DWARF < 5. In DWARFv5 the type - // section does not exist, so no need to do anything about this. - State.ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)] = 0; - // Unlie about the info contribution - State.ContributionOffsets[0] = 1; - } - writeIndex(*State.Streamer.get(), State.MCOFI->getDwarfCUIndexSection(), - State.ContributionOffsets, State.IndexEntries, State.IndexVersion); - - State.Streamer->finish(); - State.Out->keep(); -} - -void DWARFRewriter::updateDWP(DWARFUnit &CU, - const OverriddenSectionsMap &OverridenSections, - const DWARFRewriter::UnitMeta &CUMI, - DWARFRewriter::UnitMetaVectorType &TUMetaVector, - DWPState &State, DebugLocWriter &LocWriter, - DebugStrOffsetsWriter &StrOffstsWriter, - DebugStrWriter &StrWriter) { - const uint64_t DWOId = *CU.getDWOId(); - MCSection *const StrOffsetSection = State.MCOFI->getDwarfStrOffDWOSection(); - assert(StrOffsetSection && "StrOffsetSection does not exist."); - // Skipping CUs that we failed to load. - std::optional DWOCU = BC.getDWOCU(DWOId); - if (!DWOCU) - return; - - if (State.Version == 0) { - State.Version = CU.getVersion(); - State.IndexVersion = State.Version < 5 ? 2 : 5; - } else if (State.Version != CU.getVersion()) { - errs() << "BOLT-ERROR: incompatible DWARF compile unit versions\n"; - exit(1); - } - - UnitIndexEntry CurEntry = {}; - CurEntry.DWOName = dwarf::toString( - CU.getUnitDIE().find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), - ""); - const char *Name = CU.getUnitDIE().getShortName(); - if (Name) - CurEntry.Name = Name; - StringRef CurStrSection; - StringRef CurStrOffsetSection; - - // This maps each section contained in this file to its length. - // This information is later on used to calculate the contributions, - // i.e. offset and length, of each compile/type unit to a section. - std::vector> SectionLength; - - const DWARFUnitIndex::Entry *CUDWOEntry = nullptr; - if (State.IsDWP) - CUDWOEntry = State.CUIndex->getFromHash(DWOId); - - bool StrSectionWrittenOut = false; - const object::ObjectFile *DWOFile = - (*DWOCU)->getContext().getDWARFObj().getFile(); - - DebugRangeListsSectionWriter *RangeListssWriter = nullptr; - if (CU.getVersion() == 5) { - assert(RangeListsWritersByCU.count(DWOId) != 0 && - "No RangeListsWriter for DWO ID."); - RangeListssWriter = RangeListsWritersByCU[DWOId].get(); - } - auto AddType = [&](unsigned int Index, uint32_t IndexVersion, uint64_t Offset, - uint64_t Length, uint64_t Hash) -> void { - UnitIndexEntry TUEntry = CurEntry; - if (IndexVersion < 5) - TUEntry.Contributions[0] = {}; - TUEntry.Contributions[Index].setOffset(Offset); - TUEntry.Contributions[Index].setLength(Length); - State.ContributionOffsets[Index] += - TUEntry.Contributions[Index].getLength32(); - State.TypeIndexEntries.insert(std::make_pair(Hash, TUEntry)); - }; - std::unique_ptr StrOffsetsOutputData; - std::unique_ptr StrOutputData; - for (const SectionRef &Section : DWOFile->sections()) { - std::unique_ptr OutputData = nullptr; - StringRef SectionName = getSectionName(Section); - Expected ContentsExp = Section.getContents(); - assert(ContentsExp && "Invalid contents."); - std::optional TOutData = - updateDebugData((*DWOCU)->getContext(), SectionName, *ContentsExp, - State.KnownSections, *State.Streamer, *this, CUDWOEntry, - DWOId, OutputData, RangeListssWriter, LocWriter, - StrOffstsWriter, StrWriter, OverridenSections); - if (!TOutData) - continue; - - StringRef OutData = *TOutData; - if (SectionName == "debug_types.dwo") { - State.Streamer->emitBytes(OutData); - continue; - } - - if (SectionName == "debug_str.dwo") { - CurStrSection = OutData; - StrOutputData = std::move(OutputData); - } else { - // Since handleDebugDataPatching returned true, we already know this is - // a known section. - auto SectionIter = State.KnownSections.find(SectionName); - if (SectionIter->second.second == DWARFSectionKind::DW_SECT_STR_OFFSETS) { - CurStrOffsetSection = OutData; - StrOffsetsOutputData = std::move(OutputData); - } else { - State.Streamer->emitBytes(OutData); - } - unsigned int Index = - getContributionIndex(SectionIter->second.second, State.IndexVersion); - uint64_t Offset = State.ContributionOffsets[Index]; - uint64_t Length = OutData.size(); - if (CU.getVersion() >= 5 && - SectionIter->second.second == DWARFSectionKind::DW_SECT_INFO) { - for (UnitMeta &MI : TUMetaVector) - MI.Offset += State.DebugInfoSize; - - Offset = State.DebugInfoSize + CUMI.Offset; - Length = CUMI.Length; - State.DebugInfoSize += OutData.size(); - } - CurEntry.Contributions[Index].setOffset(Offset); - CurEntry.Contributions[Index].setLength(Length); - State.ContributionOffsets[Index] += - CurEntry.Contributions[Index].getLength32(); - } - - // Strings are combined in to a new string section, and de-duplicated - // based on hash. - if (!StrSectionWrittenOut && !CurStrOffsetSection.empty() && - !CurStrSection.empty()) { - // If debug_str.dwo section was modified storing it until dwp is written - // out. DWPStringPool stores raw pointers to strings. - if (StrOutputData) - State.StrSections.push_back(std::move(StrOutputData)); - writeStringsAndOffsets(*State.Streamer.get(), *State.Strings.get(), - StrOffsetSection, CurStrSection, - CurStrOffsetSection, CU.getVersion()); - StrSectionWrittenOut = true; - } - } - CompileUnitIdentifiers CUI{DWOId, CurEntry.Name.c_str(), - CurEntry.DWOName.c_str()}; - auto P = State.IndexEntries.insert(std::make_pair(CUI.Signature, CurEntry)); - if (!P.second) { - Error Err = buildDuplicateError(*P.first, CUI, ""); - errs() << "BOLT-ERROR: " << toString(std::move(Err)) << "\n"; - return; - } - - // Handling TU - const unsigned Index = getContributionIndex( - State.IndexVersion < 5 ? DW_SECT_EXT_TYPES : DW_SECT_INFO, - State.IndexVersion); - for (UnitMeta &MI : TUMetaVector) - AddType(Index, State.IndexVersion, MI.Offset, MI.Length, MI.TUHash); -} - void DWARFRewriter::writeDWOFiles( DWARFUnit &CU, const OverriddenSectionsMap &OverridenSections, const std::string &DWOName, DebugLocWriter &LocWriter, diff --git a/bolt/lib/Rewrite/PseudoProbeRewriter.cpp b/bolt/lib/Rewrite/PseudoProbeRewriter.cpp index 51038dbead330..886bbdbf9d686 100644 --- a/bolt/lib/Rewrite/PseudoProbeRewriter.cpp +++ b/bolt/lib/Rewrite/PseudoProbeRewriter.cpp @@ -19,6 +19,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/LEB128.h" +#include #undef DEBUG_TYPE #define DEBUG_TYPE "pseudo-probe-rewriter" @@ -48,6 +49,7 @@ static cl::opt PrintPseudoProbes( clEnumValN(PPP_All, "all", "enable all debugging printout")), cl::Hidden, cl::cat(BoltCategory)); +extern cl::opt ProfileUsePseudoProbes; } // namespace opts namespace { @@ -72,23 +74,38 @@ class PseudoProbeRewriter final : public MetadataRewriter { void parsePseudoProbe(); /// PseudoProbe decoder - MCPseudoProbeDecoder ProbeDecoder; + std::shared_ptr ProbeDecoderPtr; public: PseudoProbeRewriter(BinaryContext &BC) - : MetadataRewriter("pseudo-probe-rewriter", BC) {} + : MetadataRewriter("pseudo-probe-rewriter", BC), + ProbeDecoderPtr(std::make_shared()) { + BC.setPseudoProbeDecoder(ProbeDecoderPtr); + } + Error preCFGInitializer() override; Error postEmitFinalizer() override; + + ~PseudoProbeRewriter() override { ProbeDecoderPtr.reset(); } }; +Error PseudoProbeRewriter::preCFGInitializer() { + if (opts::ProfileUsePseudoProbes) + parsePseudoProbe(); + + return Error::success(); +} + Error PseudoProbeRewriter::postEmitFinalizer() { - parsePseudoProbe(); + if (!opts::ProfileUsePseudoProbes) + parsePseudoProbe(); updatePseudoProbes(); return Error::success(); } void PseudoProbeRewriter::parsePseudoProbe() { + MCPseudoProbeDecoder &ProbeDecoder(*ProbeDecoderPtr); PseudoProbeDescSection = BC.getUniqueSectionByName(".pseudo_probe_desc"); PseudoProbeSection = BC.getUniqueSectionByName(".pseudo_probe"); @@ -138,9 +155,18 @@ void PseudoProbeRewriter::parsePseudoProbe() { ProbeDecoder.printGUID2FuncDescMap(outs()); ProbeDecoder.printProbesForAllAddresses(outs()); } + + for (const auto &[GUID, FuncDesc] : ProbeDecoder.getGUID2FuncDescMap()) { + if (!FuncStartAddrs.contains(GUID)) + continue; + BinaryFunction *BF = BC.getBinaryFunctionAtAddress(FuncStartAddrs[GUID]); + assert(BF); + BF->setGUID(GUID); + } } void PseudoProbeRewriter::updatePseudoProbes() { + MCPseudoProbeDecoder &ProbeDecoder(*ProbeDecoderPtr); // check if there is pseudo probe section decoded if (ProbeDecoder.getAddress2ProbesMap().empty()) return; @@ -241,6 +267,7 @@ void PseudoProbeRewriter::updatePseudoProbes() { } void PseudoProbeRewriter::encodePseudoProbes() { + MCPseudoProbeDecoder &ProbeDecoder(*ProbeDecoderPtr); // Buffer for new pseudo probes section SmallString<8> Contents; MCDecodedPseudoProbe *LastProbe = nullptr; diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp index 4ae802dc97ccd..9077869fe4955 100644 --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -669,6 +669,7 @@ Error RewriteInstance::run() { opts::ProfileFormat == opts::ProfileFormatKind::PF_YAML) { selectFunctionsToProcess(); disassembleFunctions(); + processMetadataPreCFG(); buildFunctionsCFG(); } processProfileData(); @@ -3130,18 +3131,24 @@ void RewriteInstance::initializeMetadataManager() { } void RewriteInstance::processSectionMetadata() { + NamedRegionTimer T("processmetadata-section", "process section metadata", + TimerGroupName, TimerGroupDesc, opts::TimeRewrite); initializeMetadataManager(); MetadataManager.runSectionInitializers(); } void RewriteInstance::processMetadataPreCFG() { + NamedRegionTimer T("processmetadata-precfg", "process metadata pre-CFG", + TimerGroupName, TimerGroupDesc, opts::TimeRewrite); MetadataManager.runInitializersPreCFG(); processProfileDataPreCFG(); } void RewriteInstance::processMetadataPostCFG() { + NamedRegionTimer T("processmetadata-postcfg", "process metadata post-CFG", + TimerGroupName, TimerGroupDesc, opts::TimeRewrite); MetadataManager.runInitializersPostCFG(); } @@ -3193,6 +3200,7 @@ void RewriteInstance::processProfileData() { if (opts::AggregateOnly) { PrintProgramStats PPS(&*BAT); BC->logBOLTErrorsAndQuitOnFatal(PPS.runOnFunctions(*BC)); + TimerGroup::printAll(outs()); exit(0); } } @@ -3535,10 +3543,14 @@ void RewriteInstance::emitAndLink() { } void RewriteInstance::finalizeMetadataPreEmit() { + NamedRegionTimer T("finalizemetadata-preemit", "finalize metadata pre-emit", + TimerGroupName, TimerGroupDesc, opts::TimeRewrite); MetadataManager.runFinalizersPreEmit(); } void RewriteInstance::updateMetadata() { + NamedRegionTimer T("updatemetadata-postemit", "update metadata post-emit", + TimerGroupName, TimerGroupDesc, opts::TimeRewrite); MetadataManager.runFinalizersAfterEmit(); if (opts::UpdateDebugSections) { diff --git a/bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp b/bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp index d114d70f2d376..026f8d35c55c6 100644 --- a/bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp +++ b/bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp @@ -32,10 +32,10 @@ cl::opt "(which is what --hot-text relies on)."), cl::cat(BoltOptCategory)); -static cl::opt RuntimeHugifyLib( - "runtime-hugify-lib", - cl::desc("specify file name of the runtime hugify library"), - cl::init("libbolt_rt_hugify.a"), cl::cat(BoltOptCategory)); +static cl::opt + RuntimeHugifyLib("runtime-hugify-lib", + cl::desc("specify path of the runtime hugify library"), + cl::init("libbolt_rt_hugify.a"), cl::cat(BoltOptCategory)); } // namespace opts diff --git a/bolt/lib/RuntimeLibs/InstrumentationRuntimeLibrary.cpp b/bolt/lib/RuntimeLibs/InstrumentationRuntimeLibrary.cpp index cd1b975be7b90..53a0c811b41d5 100644 --- a/bolt/lib/RuntimeLibs/InstrumentationRuntimeLibrary.cpp +++ b/bolt/lib/RuntimeLibs/InstrumentationRuntimeLibrary.cpp @@ -26,7 +26,7 @@ namespace opts { cl::opt RuntimeInstrumentationLib( "runtime-instrumentation-lib", - cl::desc("specify file name of the runtime instrumentation library"), + cl::desc("specify path of the runtime instrumentation library"), cl::init("libbolt_rt_instr.a"), cl::cat(BoltOptCategory)); extern cl::opt InstrumentationFileAppendPID; diff --git a/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp b/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp index 276b034d71f96..336c6768a7f71 100644 --- a/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp +++ b/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp @@ -26,8 +26,8 @@ using namespace bolt; void RuntimeLibrary::anchor() {} -std::string RuntimeLibrary::getLibPath(StringRef ToolPath, - StringRef LibFileName) { +std::string RuntimeLibrary::getLibPathByToolPath(StringRef ToolPath, + StringRef LibFileName) { StringRef Dir = llvm::sys::path::parent_path(ToolPath); SmallString<128> LibPath = llvm::sys::path::parent_path(Dir); llvm::sys::path::append(LibPath, "lib" LLVM_LIBDIR_SUFFIX); @@ -38,13 +38,36 @@ std::string RuntimeLibrary::getLibPath(StringRef ToolPath, llvm::sys::path::append(LibPath, "lib" LLVM_LIBDIR_SUFFIX); } llvm::sys::path::append(LibPath, LibFileName); - if (!llvm::sys::fs::exists(LibPath)) { - errs() << "BOLT-ERROR: library not found: " << LibPath << "\n"; - exit(1); - } return std::string(LibPath); } +std::string RuntimeLibrary::getLibPathByInstalled(StringRef LibFileName) { + SmallString<128> LibPath(CMAKE_INSTALL_FULL_LIBDIR); + llvm::sys::path::append(LibPath, LibFileName); + return std::string(LibPath); +} + +std::string RuntimeLibrary::getLibPath(StringRef ToolPath, + StringRef LibFileName) { + if (llvm::sys::fs::exists(LibFileName)) { + return std::string(LibFileName); + } + + std::string ByTool = getLibPathByToolPath(ToolPath, LibFileName); + if (llvm::sys::fs::exists(ByTool)) { + return ByTool; + } + + std::string ByInstalled = getLibPathByInstalled(LibFileName); + if (llvm::sys::fs::exists(ByInstalled)) { + return ByInstalled; + } + + errs() << "BOLT-ERROR: library not found: " << ByTool << ", " << ByInstalled + << ", or " << LibFileName << "\n"; + exit(1); +} + void RuntimeLibrary::loadLibrary(StringRef LibPath, BOLTLinker &Linker, BOLTLinker::SectionsMapper MapSections) { ErrorOr> MaybeBuf = diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp index 1a2327df1d323..f58f7857e28ae 100644 --- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp +++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp @@ -852,16 +852,19 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { return Uses; } - IndirectBranchType analyzeIndirectBranch( - MCInst &Instruction, InstructionIterator Begin, InstructionIterator End, - const unsigned PtrSize, MCInst *&MemLocInstrOut, unsigned &BaseRegNumOut, - unsigned &IndexRegNumOut, int64_t &DispValueOut, - const MCExpr *&DispExprOut, MCInst *&PCRelBaseOut) const override { + IndirectBranchType + analyzeIndirectBranch(MCInst &Instruction, InstructionIterator Begin, + InstructionIterator End, const unsigned PtrSize, + MCInst *&MemLocInstrOut, unsigned &BaseRegNumOut, + unsigned &IndexRegNumOut, int64_t &DispValueOut, + const MCExpr *&DispExprOut, MCInst *&PCRelBaseOut, + MCInst *&FixedEntryLoadInstr) const override { MemLocInstrOut = nullptr; BaseRegNumOut = AArch64::NoRegister; IndexRegNumOut = AArch64::NoRegister; DispValueOut = 0; DispExprOut = nullptr; + FixedEntryLoadInstr = nullptr; // An instruction referencing memory used by jump instruction (directly or // via register). This location could be an array of function pointers diff --git a/bolt/lib/Target/AArch64/CMakeLists.txt b/bolt/lib/Target/AArch64/CMakeLists.txt index be03e247aa96b..7e2d33e09b5a0 100644 --- a/bolt/lib/Target/AArch64/CMakeLists.txt +++ b/bolt/lib/Target/AArch64/CMakeLists.txt @@ -4,6 +4,18 @@ set(LLVM_LINK_COMPONENTS AArch64Desc ) +if(BOLT_BUILT_STANDALONE) + set(LLVM_TARGET_DEFINITIONS ${LLVM_MAIN_SRC_DIR}/lib/Target/AArch64/AArch64.td) + list(APPEND LLVM_TABLEGEN_FLAGS -I ${LLVM_MAIN_SRC_DIR}/lib/Target/AArch64) + tablegen(LLVM AArch64GenInstrInfo.inc -gen-instr-info) + tablegen(LLVM AArch64GenRegisterInfo.inc -gen-register-info) + tablegen(LLVM AArch64GenSystemOperands.inc -gen-searchable-tables) + tablegen(LLVM AArch64GenSubtargetInfo.inc -gen-subtarget) + + add_public_tablegen_target(AArch64CommonTableGen) + include_directories(${CMAKE_CURRENT_BINARY_DIR}) +endif() + add_llvm_library(LLVMBOLTTargetAArch64 AArch64MCPlusBuilder.cpp diff --git a/bolt/lib/Target/RISCV/CMakeLists.txt b/bolt/lib/Target/RISCV/CMakeLists.txt index 7f95576063200..5d19d38717de4 100644 --- a/bolt/lib/Target/RISCV/CMakeLists.txt +++ b/bolt/lib/Target/RISCV/CMakeLists.txt @@ -4,6 +4,19 @@ set(LLVM_LINK_COMPONENTS RISCVDesc ) +if(BOLT_BUILT_STANDALONE) + # tablegen, copied from llvm/lib/Target/RISCV/CMakeLists.txt + set(LLVM_TARGET_DEFINITIONS ${LLVM_MAIN_SRC_DIR}/lib/Target/RISCV/RISCV.td) + list(APPEND LLVM_TABLEGEN_FLAGS -I ${LLVM_MAIN_SRC_DIR}/lib/Target/RISCV) + tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info) + tablegen(LLVM RISCVGenRegisterInfo.inc -gen-register-info) + tablegen(LLVM RISCVGenSearchableTables.inc -gen-searchable-tables) + tablegen(LLVM RISCVGenSubtargetInfo.inc -gen-subtarget) + + add_public_tablegen_target(RISCVCommonTableGen) + include_directories(${CMAKE_CURRENT_BINARY_DIR}) +endif() + add_llvm_library(LLVMBOLTTargetRISCV RISCVMCPlusBuilder.cpp diff --git a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp index eb3f38a0b8f4a..f8c83b09395f5 100644 --- a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp +++ b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp @@ -176,13 +176,14 @@ class RISCVMCPlusBuilder : public MCPlusBuilder { MCInst &Instruction, InstructionIterator Begin, InstructionIterator End, const unsigned PtrSize, MCInst *&MemLocInstr, unsigned &BaseRegNum, unsigned &IndexRegNum, int64_t &DispValue, const MCExpr *&DispExpr, - MCInst *&PCRelBaseOut) const override { + MCInst *&PCRelBaseOut, MCInst *&FixedEntryLoadInst) const override { MemLocInstr = nullptr; BaseRegNum = 0; IndexRegNum = 0; DispValue = 0; DispExpr = nullptr; PCRelBaseOut = nullptr; + FixedEntryLoadInst = nullptr; // Check for the following long tail call sequence: // 1: auipc xi, %pcrel_hi(sym) diff --git a/bolt/lib/Target/X86/CMakeLists.txt b/bolt/lib/Target/X86/CMakeLists.txt index 2b769bc7e7f5c..b274716e89a4c 100644 --- a/bolt/lib/Target/X86/CMakeLists.txt +++ b/bolt/lib/Target/X86/CMakeLists.txt @@ -5,6 +5,18 @@ set(LLVM_LINK_COMPONENTS X86Desc ) +if(BOLT_BUILT_STANDALONE) + set(LLVM_TARGET_DEFINITIONS ${LLVM_MAIN_SRC_DIR}/lib/Target/X86/X86.td) + list(APPEND LLVM_TABLEGEN_FLAGS -I ${LLVM_MAIN_SRC_DIR}/lib/Target/X86) + tablegen(LLVM X86GenInstrInfo.inc -gen-instr-info -instr-info-expand-mi-operand-info=0) + tablegen(LLVM X86GenMnemonicTables.inc -gen-x86-mnemonic-tables -asmwriternum=1) + tablegen(LLVM X86GenRegisterInfo.inc -gen-register-info) + tablegen(LLVM X86GenSubtargetInfo.inc -gen-subtarget) + + add_public_tablegen_target(X86CommonTableGen) + include_directories(${CMAKE_CURRENT_BINARY_DIR}) +endif() + add_llvm_library(LLVMBOLTTargetX86 X86MCPlusBuilder.cpp X86MCSymbolizer.cpp diff --git a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp index e46c42533031c..63086c06d74fd 100644 --- a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp +++ b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp @@ -1866,8 +1866,11 @@ class X86MCPlusBuilder : public MCPlusBuilder { return true; } + /// Analyzes PIC-style jump table code template and return identified + /// IndirectBranchType, MemLocInstr (all cases) and FixedEntryLoadInstr + /// (POSSIBLE_PIC_FIXED_BRANCH case). template - std::pair + std::tuple analyzePICJumpTable(Itr II, Itr IE, MCPhysReg R1, MCPhysReg R2) const { // Analyze PIC-style jump table code template: // @@ -1876,6 +1879,13 @@ class X86MCPlusBuilder : public MCPlusBuilder { // add %r2, %r1 // jmp *%r1 // + // or a fixed indirect jump template: + // + // movslq En(%rip), {%r2|%r1} <- FixedEntryLoadInstr + // lea PIC_JUMP_TABLE(%rip), {%r1|%r2} <- MemLocInstr + // add %r2, %r1 + // jmp *%r1 + // // (with any irrelevant instructions in-between) // // When we call this helper we've already determined %r1 and %r2, and @@ -1916,8 +1926,13 @@ class X86MCPlusBuilder : public MCPlusBuilder { MO.SegRegNum == X86::NoRegister; }; LLVM_DEBUG(dbgs() << "Checking for PIC jump table\n"); - MCInst *MemLocInstr = nullptr; - const MCInst *MovInstr = nullptr; + MCInst *FirstInstr = nullptr; + MCInst *SecondInstr = nullptr; + enum { + NOMATCH = 0, + MATCH_JUMP_TABLE, + MATCH_FIXED_BRANCH, + } MatchingState = NOMATCH; while (++II != IE) { MCInst &Instr = *II; const MCInstrDesc &InstrDesc = Info->get(Instr.getOpcode()); @@ -1926,68 +1941,76 @@ class X86MCPlusBuilder : public MCPlusBuilder { // Ignore instructions that don't affect R1, R2 registers. continue; } - if (!MovInstr) { - // Expect to see MOV instruction. - if (!isMOVSX64rm32(Instr)) { - LLVM_DEBUG(dbgs() << "MOV instruction expected.\n"); + const bool IsMOVSXInstr = isMOVSX64rm32(Instr); + const bool IsLEAInstr = isLEA64r(Instr); + if (MatchingState == NOMATCH) { + if (IsMOVSXInstr) + MatchingState = MATCH_JUMP_TABLE; + else if (IsLEAInstr) + MatchingState = MATCH_FIXED_BRANCH; + else break; - } - // Check if it's setting %r1 or %r2. In canonical form it sets %r2. - // If it sets %r1 - rename the registers so we have to only check - // a single form. - unsigned MovDestReg = Instr.getOperand(0).getReg(); - if (MovDestReg != R2) + // Check if the first instruction is setting %r1 or %r2. In canonical + // form lea sets %r1 and mov sets %r2. If it's the opposite - rename so + // we have to only check a single form. + unsigned DestReg = Instr.getOperand(0).getReg(); + MCPhysReg &ExpectReg = MatchingState == MATCH_JUMP_TABLE ? R2 : R1; + if (DestReg != ExpectReg) std::swap(R1, R2); - if (MovDestReg != R2) { - LLVM_DEBUG(dbgs() << "MOV instruction expected to set %r2\n"); + if (DestReg != ExpectReg) break; - } - // Verify operands for MOV. + // Verify operands std::optional MO = evaluateX86MemoryOperand(Instr); if (!MO) break; - if (!isIndexed(*MO, R1)) - // POSSIBLE_PIC_JUMP_TABLE + if ((MatchingState == MATCH_JUMP_TABLE && isIndexed(*MO, R1)) || + (MatchingState == MATCH_FIXED_BRANCH && isRIPRel(*MO))) + FirstInstr = &Instr; + else break; - MovInstr = &Instr; } else { - if (!InstrDesc.hasDefOfPhysReg(Instr, R1, *RegInfo)) + unsigned ExpectReg = MatchingState == MATCH_JUMP_TABLE ? R1 : R2; + if (!InstrDesc.hasDefOfPhysReg(Instr, ExpectReg, *RegInfo)) continue; - if (!isLEA64r(Instr)) { - LLVM_DEBUG(dbgs() << "LEA instruction expected\n"); + if ((MatchingState == MATCH_JUMP_TABLE && !IsLEAInstr) || + (MatchingState == MATCH_FIXED_BRANCH && !IsMOVSXInstr)) break; - } - if (Instr.getOperand(0).getReg() != R1) { - LLVM_DEBUG(dbgs() << "LEA instruction expected to set %r1\n"); + if (Instr.getOperand(0).getReg() != ExpectReg) break; - } - // Verify operands for LEA. + // Verify operands. std::optional MO = evaluateX86MemoryOperand(Instr); if (!MO) break; if (!isRIPRel(*MO)) break; - MemLocInstr = &Instr; + SecondInstr = &Instr; break; } } - if (!MemLocInstr) - return std::make_pair(IndirectBranchType::UNKNOWN, nullptr); + if (!SecondInstr) + return std::make_tuple(IndirectBranchType::UNKNOWN, nullptr, nullptr); + if (MatchingState == MATCH_FIXED_BRANCH) { + LLVM_DEBUG(dbgs() << "checking potential fixed indirect branch\n"); + return std::make_tuple(IndirectBranchType::POSSIBLE_PIC_FIXED_BRANCH, + FirstInstr, SecondInstr); + } LLVM_DEBUG(dbgs() << "checking potential PIC jump table\n"); - return std::make_pair(IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE, - MemLocInstr); + return std::make_tuple(IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE, + SecondInstr, nullptr); } - IndirectBranchType analyzeIndirectBranch( - MCInst &Instruction, InstructionIterator Begin, InstructionIterator End, - const unsigned PtrSize, MCInst *&MemLocInstrOut, unsigned &BaseRegNumOut, - unsigned &IndexRegNumOut, int64_t &DispValueOut, - const MCExpr *&DispExprOut, MCInst *&PCRelBaseOut) const override { + IndirectBranchType + analyzeIndirectBranch(MCInst &Instruction, InstructionIterator Begin, + InstructionIterator End, const unsigned PtrSize, + MCInst *&MemLocInstrOut, unsigned &BaseRegNumOut, + unsigned &IndexRegNumOut, int64_t &DispValueOut, + const MCExpr *&DispExprOut, MCInst *&PCRelBaseOut, + MCInst *&FixedEntryLoadInst) const override { // Try to find a (base) memory location from where the address for // the indirect branch is loaded. For X86-64 the memory will be specified // in the following format: @@ -2014,6 +2037,7 @@ class X86MCPlusBuilder : public MCPlusBuilder { IndexRegNumOut = X86::NoRegister; DispValueOut = 0; DispExprOut = nullptr; + FixedEntryLoadInst = nullptr; std::reverse_iterator II(End); std::reverse_iterator IE(Begin); @@ -2046,7 +2070,8 @@ class X86MCPlusBuilder : public MCPlusBuilder { unsigned R2 = PrevInstr.getOperand(2).getReg(); if (R1 == R2) return IndirectBranchType::UNKNOWN; - std::tie(Type, MemLocInstr) = analyzePICJumpTable(PrevII, IE, R1, R2); + std::tie(Type, MemLocInstr, FixedEntryLoadInst) = + analyzePICJumpTable(PrevII, IE, R1, R2); break; } return IndirectBranchType::UNKNOWN; @@ -2090,6 +2115,8 @@ class X86MCPlusBuilder : public MCPlusBuilder { if (MO->ScaleImm != 1 || MO->BaseRegNum != RIPRegister) return IndirectBranchType::UNKNOWN; break; + case IndirectBranchType::POSSIBLE_PIC_FIXED_BRANCH: + break; default: if (MO->ScaleImm != PtrSize) return IndirectBranchType::UNKNOWN; diff --git a/bolt/lib/Utils/CMakeLists.txt b/bolt/lib/Utils/CMakeLists.txt index d1403314274bd..c452c1fac3772 100644 --- a/bolt/lib/Utils/CMakeLists.txt +++ b/bolt/lib/Utils/CMakeLists.txt @@ -1,15 +1,39 @@ +find_first_existing_vc_file("${LLVM_MAIN_SRC_DIR}" llvm_vc) +find_first_existing_vc_file("${BOLT_SOURCE_DIR}" bolt_vc) + +# The VC revision include that we want to generate. +set(version_inc "${CMAKE_CURRENT_BINARY_DIR}/VCSVersion.inc") + +set(generate_vcs_version_script "${LLVM_CMAKE_DIR}/GenerateVersionFromVCS.cmake") + +# Create custom target to generate the VC revision include. +add_custom_command(OUTPUT "${version_inc}" + DEPENDS "${llvm_vc}" "${bolt_vc}" "${generate_vcs_version_script}" + COMMAND ${CMAKE_COMMAND} "-DNAMES=BOLT" + "-DHEADER_FILE=${version_inc}" + "-DBOLT_SOURCE_DIR=${BOLT_SOURCE_DIR}" + "-DLLVM_VC_REPOSITORY=${llvm_vc_repository}" + "-DLLVM_VC_REVISION=${llvm_vc_revision}" + "-DLLVM_FORCE_VC_REVISION=${LLVM_FORCE_VC_REVISION}" + "-DLLVM_FORCE_VC_REPOSITORY=${LLVM_FORCE_VC_REPOSITORY}" + -P "${generate_vcs_version_script}") + +# Mark the generated header as being generated. +set_source_files_properties("${version_inc}" + PROPERTIES GENERATED TRUE + HEADER_FILE_ONLY TRUE) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + add_llvm_library(LLVMBOLTUtils CommandLineOpts.cpp Utils.cpp - + ${version_inc} DISABLE_LLVM_LINK_LLVM_DYLIB LINK_LIBS ${LLVM_PTHREAD_LIB} - DEPENDS - llvm_vcsrevision_h - LINK_COMPONENTS Support ) diff --git a/bolt/lib/Utils/CommandLineOpts.cpp b/bolt/lib/Utils/CommandLineOpts.cpp index 47375abb2ad3b..435a8fa9cafca 100644 --- a/bolt/lib/Utils/CommandLineOpts.cpp +++ b/bolt/lib/Utils/CommandLineOpts.cpp @@ -11,15 +11,15 @@ //===----------------------------------------------------------------------===// #include "bolt/Utils/CommandLineOpts.h" -#include "llvm/Support/VCSRevision.h" +#include "VCSVersion.inc" using namespace llvm; namespace llvm { namespace bolt { const char *BoltRevision = -#ifdef LLVM_REVISION - LLVM_REVISION; +#ifdef BOLT_REVISION + BOLT_REVISION; #else ""; #endif diff --git a/bolt/runtime/CMakeLists.txt b/bolt/runtime/CMakeLists.txt index 6a65f80fb9079..40f4fbc9f30d5 100644 --- a/bolt/runtime/CMakeLists.txt +++ b/bolt/runtime/CMakeLists.txt @@ -16,12 +16,19 @@ add_library(bolt_rt_instr STATIC instr.cpp ${CMAKE_CURRENT_BINARY_DIR}/config.h ) -set_target_properties(bolt_rt_instr PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${LLVM_LIBRARY_DIR}") +set_target_properties(bolt_rt_instr PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") add_library(bolt_rt_hugify STATIC hugify.cpp ${CMAKE_CURRENT_BINARY_DIR}/config.h ) -set_target_properties(bolt_rt_hugify PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${LLVM_LIBRARY_DIR}") +set_target_properties(bolt_rt_hugify PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") + +if(NOT BOLT_BUILT_STANDALONE) + add_custom_command(TARGET bolt_rt_instr POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/lib/libbolt_rt_instr.a" "${LLVM_LIBRARY_DIR}") + add_custom_command(TARGET bolt_rt_hugify POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/lib/libbolt_rt_hugify.a" "${LLVM_LIBRARY_DIR}") +endif() set(BOLT_RT_FLAGS -ffreestanding @@ -46,18 +53,23 @@ target_include_directories(bolt_rt_instr PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_compile_options(bolt_rt_hugify PRIVATE ${BOLT_RT_FLAGS}) target_include_directories(bolt_rt_hugify PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) -install(TARGETS bolt_rt_instr DESTINATION "lib${LLVM_LIBDIR_SUFFIX}") -install(TARGETS bolt_rt_hugify DESTINATION "lib${LLVM_LIBDIR_SUFFIX}") +install(TARGETS bolt_rt_instr DESTINATION "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") +install(TARGETS bolt_rt_hugify DESTINATION "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") if (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*" AND CMAKE_SYSTEM_NAME STREQUAL "Darwin") add_library(bolt_rt_instr_osx STATIC instr.cpp ${CMAKE_CURRENT_BINARY_DIR}/config.h ) - set_target_properties(bolt_rt_instr_osx PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${LLVM_LIBRARY_DIR}") + set_target_properties(bolt_rt_instr_osx PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") target_include_directories(bolt_rt_instr_osx PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_compile_options(bolt_rt_instr_osx PRIVATE -target x86_64-apple-darwin19.6.0 ${BOLT_RT_FLAGS}) - install(TARGETS bolt_rt_instr_osx DESTINATION "lib${LLVM_LIBDIR_SUFFIX}") + install(TARGETS bolt_rt_instr_osx DESTINATION "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") + + if(NOT BOLT_BUILT_STANDALONE) + add_custom_command(TARGET bolt_rt_instr_osx POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/lib/libbolt_rt_instr_osx.a" "${LLVM_LIBRARY_DIR}") + endif() endif() diff --git a/bolt/test/AArch64/dummy-return.s b/bolt/test/AArch64/dummy-return.s index a446343161730..91f89dcb84762 100644 --- a/bolt/test/AArch64/dummy-return.s +++ b/bolt/test/AArch64/dummy-return.s @@ -1,4 +1,6 @@ -# REQUIRES: system-linux,target=aarch64{{.*}} +# This test checks instrumentation of static binary on AArch64. + +# REQUIRES: system-linux,bolt-runtime,target=aarch64{{.*}} # RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o # RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -static diff --git a/bolt/test/AArch64/update-debug-reloc.test b/bolt/test/AArch64/update-debug-reloc.test index d57f42a3852a5..dd83229ea7143 100644 --- a/bolt/test/AArch64/update-debug-reloc.test +++ b/bolt/test/AArch64/update-debug-reloc.test @@ -2,7 +2,7 @@ # update-debug-sections option. RUN: %clang %cflags -g %p/../Inputs/asm_foo.s %p/../Inputs/asm_main.c -o %t.exe -RUN: llvm-bolt %t.exe -o %t --update-debug-sections +RUN: llvm-bolt %t.exe -o %t --update-debug-sections 2>&1 | FileCheck %s CHECK: BOLT-INFO: Target architecture: aarch64 CHECK-NOT: Reloc num: 10 diff --git a/bolt/test/AArch64/veneer-gold.s b/bolt/test/AArch64/veneer-gold.s index 3b3e34ecb1a9f..275febce2b372 100644 --- a/bolt/test/AArch64/veneer-gold.s +++ b/bolt/test/AArch64/veneer-gold.s @@ -29,7 +29,7 @@ dummy: .type foo, %function foo: # CHECK: : -# CHECK-NEXT : {{.*}} bl {{.*}} +# CHECK-NEXT: {{.*}} bl {{.*}} bl .L2 ret .size foo, .-foo @@ -38,7 +38,7 @@ foo: .type foo2, %function foo2: # CHECK: : -# CHECK-NEXT : {{.*}} bl {{.*}} +# CHECK-NEXT: {{.*}} bl {{.*}} bl .L2 ret .size foo2, .-foo2 diff --git a/bolt/test/X86/Inputs/jump-table-fixed-ref-pic.s b/bolt/test/X86/Inputs/jump-table-fixed-ref-pic.s index 66629a4880e64..6407964593e2d 100644 --- a/bolt/test/X86/Inputs/jump-table-fixed-ref-pic.s +++ b/bolt/test/X86/Inputs/jump-table-fixed-ref-pic.s @@ -6,7 +6,7 @@ main: jae .L4 cmpq $0x1, %rdi jne .L4 - mov .Ljt_pic+8(%rip), %rax + movslq .Ljt_pic+8(%rip), %rax lea .Ljt_pic(%rip), %rdx add %rdx, %rax jmpq *%rax diff --git a/bolt/test/X86/debug-fission-single-convert.s b/bolt/test/X86/debug-fission-single-convert.s index 5ea6eb8e353af..02c9290211fc0 100644 --- a/bolt/test/X86/debug-fission-single-convert.s +++ b/bolt/test/X86/debug-fission-single-convert.s @@ -41,19 +41,6 @@ # CHECK-ADDR-SEC: 0x00000000: Addrs: [ # CHECK-ADDR-SEC: 0x0000000000601000 -# RUN: llvm-bolt %t.exe --reorder-blocks=reverse --update-debug-sections --dwarf-output-path=%T -o %t.bolt.2.exe --write-dwp=true \ -# RUN: --always-convert-to-ranges=true -# RUN: not llvm-dwarfdump --show-form --verbose --debug-info %t.bolt.2.exe.dwp &> %tAddrIndexTestDwp -# RUN: cat %tAddrIndexTestDwp | FileCheck %s --check-prefix=CHECK-DWP-DEBUG - -# CHECK-DWP-DEBUG: DW_TAG_compile_unit [1] * -# CHECK-DWP-DEBUG: DW_AT_producer [DW_FORM_GNU_str_index] (indexed (0000000a) string = "clang version 13.0.0") -# CHECK-DWP-DEBUG: DW_AT_language [DW_FORM_data2] (DW_LANG_C_plus_plus) -# CHECK-DWP-DEBUG: DW_AT_name [DW_FORM_GNU_str_index] (indexed (0000000b) string = "foo") -# CHECK-DWP-DEBUG: DW_AT_GNU_dwo_name [DW_FORM_GNU_str_index] (indexed (0000000c) string = "foo") -# CHECK-DWP-DEBUG: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x06105e732fad3796) - - //clang++ -ffunction-sections -fno-exceptions -g -gsplit-dwarf=split -S debug-fission-simple.cpp -o debug-fission-simple.s static int foo = 2; int doStuff(int val) { diff --git a/bolt/test/X86/debug-fission-single.s b/bolt/test/X86/debug-fission-single.s index 4350bd9ec1815..1aa502fc9a840 100644 --- a/bolt/test/X86/debug-fission-single.s +++ b/bolt/test/X86/debug-fission-single.s @@ -42,18 +42,6 @@ # CHECK-ADDR-SEC: 0x00000000: Addrs: [ # CHECK-ADDR-SEC: 0x0000000000601000 -# RUN: llvm-bolt %t.exe --reorder-blocks=reverse --update-debug-sections --dwarf-output-path=%T -o %t.bolt.2.exe --write-dwp=true -# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt.2.exe.dwp &> %tAddrIndexTestDwp -# RUN: cat %tAddrIndexTestDwp | FileCheck %s --check-prefix=CHECK-DWP-DEBUG - -# CHECK-DWP-DEBUG: DW_TAG_compile_unit [1] * -# CHECK-DWP-DEBUG: DW_AT_producer [DW_FORM_GNU_str_index] (indexed (0000000a) string = "clang version 13.0.0") -# CHECK-DWP-DEBUG: DW_AT_language [DW_FORM_data2] (DW_LANG_C_plus_plus) -# CHECK-DWP-DEBUG: DW_AT_name [DW_FORM_GNU_str_index] (indexed (0000000b) string = "foo") -# CHECK-DWP-DEBUG: DW_AT_GNU_dwo_name [DW_FORM_GNU_str_index] (indexed (0000000c) string = "foo") -# CHECK-DWP-DEBUG: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x06105e732fad3796) - - //clang++ -ffunction-sections -fno-exceptions -g -gsplit-dwarf=split -S debug-fission-simple.cpp -o debug-fission-simple.s static int foo = 2; int doStuff(int val) { diff --git a/bolt/test/X86/dwarf4-ftypes-dwo-input-dwp-output.test b/bolt/test/X86/dwarf4-ftypes-dwo-input-dwp-output.test deleted file mode 100644 index d08b596ec8dd1..0000000000000 --- a/bolt/test/X86/dwarf4-ftypes-dwo-input-dwp-output.test +++ /dev/null @@ -1,30 +0,0 @@ -# REQUIRES: system-linux -; RUN: rm -rf %t -; RUN: mkdir %t -; RUN: cd %t -; RUN: llvm-mc --split-dwarf-file=main.dwo --triple=x86_64-unknown-linux-gnu \ -; RUN: --filetype=obj %p/Inputs/dwarf4-ftypes-split-dwarf.s -o=main.o -; RUN: %clang %cflags -gdwarf-4 -gsplit-dwarf=split main.o -o main.exe -; RUN: llvm-dwarfdump --show-form --verbose --debug-types main.dwo | FileCheck -check-prefix=PRE-BOLT %s -; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --write-dwp -; RUN: llvm-dwarfdump --show-form --verbose --debug-types main.exe.bolt.dwp | FileCheck -check-prefix=BOLT %s -; RUN: llvm-dwarfdump --show-form --verbose --debug-tu-index main.exe.bolt.dwp | FileCheck -check-prefix=BOLT-DWP-TU-INDEX %s - -;; Test input into bolt a .dwo file with TU Index. -;; Make sure the output .dwp file has a type information. - -; PRE-BOLT: DW_TAG_type_unit -; PRE-BOLT: DW_TAG_type_unit - -; PRE-BOLT-DWP-TU-INDEX: version = 2, units = 2, slots = 4 -; PRE-BOLT-DWP-TU-INDEX: Index Signature -; PRE-BOLT-DWP-TU-INDEX: 0x675d23e4f33235f2 -; PRE-BOLT-DWP-TU-INDEX-NEXT: 0x49dc260088be7e56 - -; BOLT: DW_TAG_type_unit -; BOLT: DW_TAG_type_unit - -; BOLT-DWP-TU-INDEX: version = 2, units = 2, slots = 4 -; BOLT-DWP-TU-INDEX: Index Signature -; BOLT-DWP-TU-INDEX: 0x675d23e4f33235f2 -; BOLT-DWP-TU-INDEX-NEXT: 0x49dc260088be7e56 diff --git a/bolt/test/X86/dwarf4-ftypes-dwo-mono-input-dwp-output.test b/bolt/test/X86/dwarf4-ftypes-dwo-mono-input-dwp-output.test deleted file mode 100644 index 54382142afc8f..0000000000000 --- a/bolt/test/X86/dwarf4-ftypes-dwo-mono-input-dwp-output.test +++ /dev/null @@ -1,45 +0,0 @@ -# REQUIRES: system-linux -; RUN: rm -rf %t -; RUN: mkdir %t -; RUN: cd %t -; RUN: llvm-mc --split-dwarf-file=main.dwo -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-split-gdb-index-types-main.s -o main.o -; RUN: llvm-mc --split-dwarf-file=helper.dwo -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-split-gdb-index-types-helper.s -o helper1.o -; RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-types-helper2.s -o helper2.o -; RUN: %clang %cflags -gdwarf-4 -gsplit-dwarf=split main.o helper1.o helper2.o -o main.exe -; RUN: llvm-dwarfdump --show-form --verbose --debug-types main.dwo | FileCheck -check-prefix=PRE-BOLT %s -; RUN: llvm-dwarfdump --show-form --verbose --debug-types helper2.o | FileCheck -check-prefix=PRE-BOLT2 %s -; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --write-dwp -; RUN: llvm-dwarfdump --show-form --verbose --debug-types main.exe.bolt.dwp | FileCheck -check-prefix=BOLT %s -; RUN: llvm-dwarfdump --show-form --verbose --debug-tu-index main.exe.bolt.dwp | FileCheck -check-prefix=BOLT-DWP-TU-INDEX %s - -;; Test input into bolt a .dwo file with TU Index. -;; Test split-dwarf and monolithic TUs. -;; Make sure the output .dwp file has a type information. - -; PRE-BOLT: 0x675d23e4f33235f2 -; PRE-BOLT: DW_TAG_type_unit -; PRE-BOLT: 0x49dc260088be7e56 -; PRE-BOLT: DW_TAG_type_unit - -; PRE-BOLT2: 0x8f55ac73549bc003 -; PRE-BOLT2: DW_TAG_type_unit -; PRE-BOLT2: 0xe7734af8fed0632e -; PRE-BOLT2: DW_TAG_type_unit - -; BOLT: 0x675d23e4f33235f2 -; BOLT: DW_TAG_type_unit -; BOLT: 0x49dc260088be7e56 -; BOLT: DW_TAG_type_unit -; BOLT: 0x104ec427d2ebea6f -; BOLT: DW_TAG_type_unit -; BOLT: 0xb4580bc1535df1e4 -; BOLT: DW_TAG_type_unit -; BOLT-NOT: 0x8f55ac73549bc003 -; BOLT-NOT: 0xe7734af8fed0632e - -; BOLT-DWP-TU-INDEX: version = 2, units = 4, slots = 8 -; BOLT-DWP-TU-INDEX: Index Signature -; BOLT-DWP-TU-INDEX: 0x675d23e4f33235f2 -; BOLT-DWP-TU-INDEX-NEXT: 0xb4580bc1535df1e4 -; BOLT-DWP-TU-INDEX-NEXT: 0x49dc260088be7e56 -; BOLT-DWP-TU-INDEX-NEXT: 0x104ec427d2ebea6f diff --git a/bolt/test/X86/dwarf4-split-gdb-index-types-gdb-generated.test b/bolt/test/X86/dwarf4-split-gdb-index-types-gdb-generated.test index c9b12574caa3a..6caf5870fca02 100644 --- a/bolt/test/X86/dwarf4-split-gdb-index-types-gdb-generated.test +++ b/bolt/test/X86/dwarf4-split-gdb-index-types-gdb-generated.test @@ -17,10 +17,10 @@ # POSTCHECK-NEXT: 0: Offset = 0x0, Length = 0x34 # POSTCHECK-NEXT: 1: Offset = 0x34, Length = 0x34 # POSTCHECK: Types CU list offset = 0x38, has 4 entries -# POSTCHECK-NEXT: 0: offset = 0x00000000, type_offset = 0x0000001e, type_signature = 0x675d23e4f33235f2 -# POSTCHECK-NEXT: 1: offset = 0x0000004a, type_offset = 0x0000001e, type_signature = 0x49dc260088be7e56 -# POSTCHECK-NEXT: 2: offset = 0x00000000, type_offset = 0x0000001e, type_signature = 0x104ec427d2ebea6f -# POSTCHECK-NEXT: 3: offset = 0x0000004a, type_offset = 0x0000001e, type_signature = 0xb4580bc1535df1e4 +# POSTCHECK-NEXT: 0: offset = 0x0000004a, type_offset = 0x0000001e, type_signature = 0xb4580bc1535df1e4 +# POSTCHECK-NEXT: 1: offset = 0x00000000, type_offset = 0x0000001e, type_signature = 0x675d23e4f33235f2 +# POSTCHECK-NEXT: 2: offset = 0x0000004a, type_offset = 0x0000001e, type_signature = 0x49dc260088be7e56 +# POSTCHECK-NEXT: 3: offset = 0x00000000, type_offset = 0x0000001e, type_signature = 0x104ec427d2ebea6f # POSTCHECK: Address area offset = 0x98, has 2 entries # POSTCHECK-NEXT: Low/High address = [0x[[#%.4x,ADDR:]], # POSTCHECK-SAME: 0x[[#ADDR + 0x7a]]) (Size: 0x7a), CU id = 0 diff --git a/bolt/test/X86/dwarf5-df-larger-batch-size.test b/bolt/test/X86/dwarf5-df-larger-batch-size.test new file mode 100644 index 0000000000000..c2c5f63e07ad8 --- /dev/null +++ b/bolt/test/X86/dwarf5-df-larger-batch-size.test @@ -0,0 +1,28 @@ +; RUN: rm -rf %t +; RUN: mkdir %t +; RUN: cd %t +; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-input-lowpc-ranges-main.s \ +; RUN: -split-dwarf-file=main.dwo -o main.o +; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-input-lowpc-ranges-other.s \ +; RUN: -split-dwarf-file=mainOther.dwo -o other.o +; RUN: %clang %cflags main.o other.o -o main.exe +; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --cu-processing-batch-size=1 +; RUN: llvm-bolt main.exe -o main-batch.exe.bolt --update-debug-sections --cu-processing-batch-size=2 +; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.exe.bolt >> %t/foo.txt +; RUN: cat %t/foo.txt | FileCheck -check-prefix=BOLT %s +; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.exe.bolt >> %t/foo-batch.txt +; RUN: cat %t/foo-batch.txt | FileCheck -check-prefix=BOLT-BATCH %s + +;; Tests that BOLT correctly handles DWO name strings with larger batch sizes. + +; BOLT: DW_TAG_skeleton_unit +; BOLT: DW_AT_dwo_name [DW_FORM_strx1] (indexed (00000001) string = "main.dwo.dwo") + +; BOLT: DW_TAG_skeleton_unit +; BOLT: DW_AT_dwo_name [DW_FORM_strx1] (indexed (00000001) string = "mainOther.dwo.dwo") + +; BOLT-BATCH: DW_TAG_skeleton_unit +; BOLT-BATCH: DW_AT_dwo_name [DW_FORM_strx1] (indexed (00000001) string = "main.dwo.dwo") + +; BOLT-BATCH: DW_TAG_skeleton_unit +; BOLT-BATCH: DW_AT_dwo_name [DW_FORM_strx1] (indexed (00000001) string = "mainOther.dwo.dwo") diff --git a/bolt/test/X86/dwarf5-df-types-modify-dwo-name-mixed.test b/bolt/test/X86/dwarf5-df-types-modify-dwo-name-mixed.test index a4f5ee77ab565..c8cfd82753d77 100644 --- a/bolt/test/X86/dwarf5-df-types-modify-dwo-name-mixed.test +++ b/bolt/test/X86/dwarf5-df-types-modify-dwo-name-mixed.test @@ -72,59 +72,6 @@ ; BOLT-NEXT: "helper.cpp" ; BOLT-NEXT: "helper.dwo" - -;; Tests that BOLT correctly handles updating DW_AT_dwo_name when it outputs a DWP file. -;; Currently skipping one of Type units because it is not being de-dupped. -;; In the tu-index this TU is not present. -; RUN: rm main.exe.bolt -; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --write-dwp -; RUN: llvm-dwarfdump --debug-info -r 0 main.exe.bolt.dwp > logDWP.txt -; RUN: llvm-dwarfdump --debug-str-offsets main.exe.bolt.dwp >> logDWP.txt -; RUN: cat logDWP.txt | FileCheck -check-prefix=BOLT-DWP %s -; BOLT-DWP: DW_TAG_type_unit -; BOLT-DWP: DW_AT_comp_dir (".") -; BOLT-DWP: DW_AT_dwo_name ("main.dwo.dwo") -; BOLT-DWP: DW_TAG_type_unit -; BOLT-DWP: DW_AT_comp_dir (".") -; BOLT-DWP: DW_AT_dwo_name ("main.dwo.dwo") -; BOLT-DWP: DW_TAG_compile_unit -; BOLT-DWP: DW_AT_dwo_name ("main.dwo.dwo") -; BOLT-DWP: DW_TAG_type_unit -; BOLT-DW-NOT: DW_AT_dwo_name -; BOLT-DWP: Contribution size = 68, Format = DWARF32, Version = 5 -; BOLT-DWP-NEXT: "main" -; BOLT-DWP-NEXT: "int" -; BOLT-DWP-NEXT: "argc" -; BOLT-DWP-NEXT: "argv" -; BOLT-DWP-NEXT: "char" -; BOLT-DWP-NEXT: "f2" -; BOLT-DWP-NEXT: "." -; BOLT-DWP-NEXT: "main.dwo.dwo" -; BOLT-DWP-NEXT: "c1" -; BOLT-DWP-NEXT: "Foo2" -; BOLT-DWP-NEXT: "f3" -; BOLT-DWP-NEXT: "c2" -; BOLT-DWP-NEXT: "c3" -; BOLT-DWP-NEXT: "Foo2a" -; BOLT-DWP-NEXT: "clang version 18.0.0git (git@github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)" -; BOLT-DWP-NEXT: "main.cpp" -; BOLT-DWP-NEXT: Contribution size = 64, Format = DWARF32, Version = 5 -; BOLT-DWP-NEXT: "fooint" -; BOLT-DWP-NEXT: "int" -; BOLT-DWP-NEXT: "_Z3foov" -; BOLT-DWP-NEXT: "foo" -; BOLT-DWP-NEXT: "fint" -; BOLT-DWP-NEXT: "c1" -; BOLT-DWP-NEXT: "c2" -; BOLT-DWP-NEXT: "Foo2Int" -; BOLT-DWP-NEXT: "f" -; BOLT-DWP-NEXT: "char" -; BOLT-DWP-NEXT: "c3" -; BOLT-DWP-NEXT: "Foo2a" -; BOLT-DWP-NEXT: "clang version 18.0.0" -; BOLT-DWP-NEXT: "helper.cpp" -; BOLT-DWP-NEXT: "helper.dwo - ;; Tests that BOLT correctly handles updating DW_AT_comp_dir/DW_AT_dwo_name when outptut directory is specified. ; RUN: mkdir DWOOut diff --git a/bolt/test/X86/dwarf5-df-types-modify-dwo-name.test b/bolt/test/X86/dwarf5-df-types-modify-dwo-name.test index 086f8f8139628..12a7f648c2325 100644 --- a/bolt/test/X86/dwarf5-df-types-modify-dwo-name.test +++ b/bolt/test/X86/dwarf5-df-types-modify-dwo-name.test @@ -73,31 +73,6 @@ ; BOLT-NEXT: "clang version 18.0.0git (git@github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)" ; BOLT-NEXT: "helper.cpp" - -;; Tests that BOLT correctly handles updating DW_AT_dwo_name when it outputs a DWP file. -;; Currently skipping one of Type units because it is not being de-dupped. -;; In the tu-index this TU is not present. -; RUN: rm main.exe.bolt -; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --write-dwp -; RUN: llvm-dwarfdump --debug-info -r 0 main.exe.bolt.dwp > logDWP.txt -; RUN: llvm-dwarfdump --debug-str-offsets main.exe.bolt.dwp >> logDWP.txt -; RUN: cat logDWP.txt | FileCheck -check-prefix=BOLT-DWP %s -; BOLT-DWP: DW_TAG_type_unit -; BOLT-DWP: DW_AT_comp_dir (".") -; BOLT-DWP: DW_AT_dwo_name ("main.dwo.dwo") -; BOLT-DWP: DW_TAG_type_unit -; BOLT-DWP: DW_AT_comp_dir (".") -; BOLT-DWP: DW_AT_dwo_name ("main.dwo.dwo") -; BOLT-DWP: DW_TAG_compile_unit -; BOLT-DWP: DW_AT_dwo_name ("main.dwo.dwo") -; BOLT-DWP: DW_TAG_type_unit -; BOLT-DWP: DW_AT_comp_dir (".") -; BOLT-DWP: DW_AT_dwo_name ("helper.dwo.dwo") -; BOLT-DWP: DW_TAG_type_unit -; BOLT-DWP: DW_TAG_compile_unit -; BOLT-DWP: DW_AT_name ("helper.cpp") -; BOLT-DWP: DW_AT_dwo_name ("helper.dwo.dwo") - ;; Tests that BOLT correctly handles updating DW_AT_comp_dir/DW_AT_dwo_name when outptut directory is specified. ; RUN: mkdir DWOOut diff --git a/bolt/test/X86/dwarf5-dwarf4-types-backward-forward-cross-reference.test b/bolt/test/X86/dwarf5-dwarf4-types-backward-forward-cross-reference.test index 070648c042c1d..b48d6a5dc20d4 100644 --- a/bolt/test/X86/dwarf5-dwarf4-types-backward-forward-cross-reference.test +++ b/bolt/test/X86/dwarf5-dwarf4-types-backward-forward-cross-reference.test @@ -5,10 +5,11 @@ # RUN: %clang %cflags %tmain.o %thelper.o -o %t.exe # RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s +# RUN: llvm-dwarfdump --show-form --verbose --debug-addr %t.bolt | FileCheck --check-prefix=POSTCHECKADDR %s # RUN: llvm-dwarfdump --show-form --verbose --debug-types %t.bolt | FileCheck --check-prefix=POSTCHECKTU %s ## This test checks that BOLT handles correctly backward and forward cross CU references -## for DWARF5 and DWARF4 with -fdebug-types-section +## for DWARF5 and DWARF4 with -fdebug-types-section and checks the address table is correct. # POSTCHECK: version = 0x0005 # POSTCHECK: DW_TAG_type_unit @@ -29,6 +30,15 @@ # POSTCHECK: DW_TAG_variable [20] # POSTCHECK: DW_AT_type [DW_FORM_ref_addr] (0x{{[0-9a-f]+}} "Foo3a") +# POSTCHECKADDR: Addrs: [ +# POSTCHECKADDR-NEXT: 0x0000000000001360 +# POSTCHECKADDR-NEXT: 0x0000000000000000 +# POSTCHECKADDR-NEXT: ] +# POSTCHECKADDR: Addrs: [ +# POSTCHECKADDR-NEXT: 0x00000000000013e0 +# POSTCHECKADDR-NEXT: 0x0000000000000000 +# POSTCHECKADDR-NEXT: ] + # POSTCHECKTU: version = 0x0004 # POSTCHECKTU: DW_TAG_type_unit # POSTCHECKTU: DW_TAG_structure_type diff --git a/bolt/test/X86/dwarf5-ftypes-dwo-mono-input-dwp-output.test b/bolt/test/X86/dwarf5-ftypes-dwo-mono-input-dwp-output.test deleted file mode 100644 index b6e9f60bbfc70..0000000000000 --- a/bolt/test/X86/dwarf5-ftypes-dwo-mono-input-dwp-output.test +++ /dev/null @@ -1,55 +0,0 @@ -# REQUIRES: system-linux -; RUN: rm -rf %t -; RUN: mkdir %t -; RUN: cd %t -; RUN: llvm-mc --split-dwarf-file=main.dwo -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-split-gdb-index-types-main.s -o main.o -; RUN: llvm-mc --split-dwarf-file=helper.dwo -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-split-gdb-index-types-helper.s -o helper1.o -; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-types-helper2.s -o helper2.o -; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o helper1.o helper2.o -o main.exe -; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.dwo | FileCheck -check-prefix=PRE-BOLT %s -; RUN: llvm-dwarfdump --show-form --verbose --debug-info helper2.o | FileCheck -check-prefix=PRE-BOLT2 %s -; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --write-dwp -; RUN: llvm-dwarfdump --show-form --verbose --debug-info -r 0 main.exe.bolt.dwp | FileCheck -check-prefix=BOLT %s -; RUN: llvm-dwarfdump --show-form --verbose --debug-tu-index main.exe.bolt.dwp | FileCheck -check-prefix=BOLT-DWP-TU-INDEX %s -; RUN: llvm-dwarfdump --show-form --verbose --debug-cu-index main.exe.bolt.dwp | FileCheck -check-prefix=BOLT-DWP-CU-INDEX %s - -;; Test input into bolt a .dwo file with TU Index. -;; Test split-dwarf and monolithic TUs. -;; Make sure the output .dwp file has a type and cu information. - -; PRE-BOLT: Type Unit -; PRE-BOLT-SAME: 0x675d23e4f33235f2 -; PRE-BOLT: Type Unit -; PRE-BOLT-SAME: 0x49dc260088be7e56 - -; PRE-BOLT2: 0x8f55ac73549bc003 -; PRE-BOLT2: DW_TAG_type_unit -; PRE-BOLT2: 0xe7734af8fed0632e -; PRE-BOLT2: DW_TAG_type_unit - -; BOLT: 0x00000000: Type Unit: length = 0x00000047 -; BOLT-SAME: 0x675d23e4f33235f2 -; BOLT: 0x0000004b: Type Unit: length = 0x0000003e -; BOLT-SAME: 0x49dc260088be7e56 -; BOLT: 0x0000008d: Compile Unit: length = 0x00000077 -; BOLT-SAME: 0x4257354d8bb35644 -; BOLT: 0x00000108: Type Unit: length = 0x00000047 -; BOLT-SAME: 0x104ec427d2ebea6f -; BOLT: 0x00000153: Type Unit: length = 0x0000003e -; BOLT-SAME: 0xb4580bc1535df1e4 -; BOLT: 0x00000195: Compile Unit: length = 0x00000054 -; BOLT-SAME: 0x7738bfb5f3edfb73 -; BOLT-NOT: 0x8f55ac73549bc003 -; BOLT-NOT: 0xe7734af8fed0632e - -; BOLT-DWP-TU-INDEX: version = 5, units = 4, slots = 8 -; BOLT-DWP-TU-INDEX: Index Signature -; BOLT-DWP-TU-INDEX: 3 0x675d23e4f33235f2 [0x0000000000000000, 0x000000000000004b) [0x00000000, 0x00000083) [0x00000000, 0x00000056) [0x00000000, 0x00000044) -; BOLT-DWP-TU-INDEX: 5 0xb4580bc1535df1e4 [0x0000000000000153, 0x0000000000000195) [0x00000083, 0x000000f9) [0x00000056, 0x000000ae) [0x00000044, 0x00000084) -; BOLT-DWP-TU-INDEX: 7 0x49dc260088be7e56 [0x000000000000004b, 0x000000000000008d) [0x00000000, 0x00000083) [0x00000000, 0x00000056) [0x00000000, 0x00000044) -; BOLT-DWP-TU-INDEX: 8 0x104ec427d2ebea6f [0x0000000000000108, 0x0000000000000153) [0x00000083, 0x000000f9) [0x00000056, 0x000000ae) [0x00000044, 0x00000084) - -; BOLT-DWP-CU-INDEX: version = 5, units = 2, slots = 4 -; BOLT-DWP-CU-INDEX: Index Signature -; BOLT-DWP-CU-INDEX: 1 0x4257354d8bb35644 [0x000000000000008d, 0x0000000000000108) [0x00000000, 0x00000083) [0x00000000, 0x00000056) [0x00000000, 0x00000044) -; BOLT-DWP-CU-INDEX: 4 0x7738bfb5f3edfb73 [0x0000000000000195, 0x00000000000001ed) [0x00000083, 0x000000f9) [0x00000056, 0x000000ae) [0x00000044, 0x00000084) diff --git a/bolt/test/X86/dwarf5-locexpr-referrence.test b/bolt/test/X86/dwarf5-locexpr-referrence.test index ea73d7601b253..cc7bb27ce602e 100644 --- a/bolt/test/X86/dwarf5-locexpr-referrence.test +++ b/bolt/test/X86/dwarf5-locexpr-referrence.test @@ -5,8 +5,10 @@ # RUN: %clang %cflags -dwarf-5 %tmain.o %thelper.o -o %t.exe -Wl,-q # RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=CHECK %s +# RUN: llvm-dwarfdump --show-form --verbose --debug-addr %t.bolt | FileCheck --check-prefix=CHECKADDR %s -## This test checks that we update relative DIE references with DW_OP_convert that are in locexpr. +## This test checks that we update relative DIE references with DW_OP_convert that are in locexpr +## and checks the address table is correct. # CHECK: version = 0x0005 # CHECK: DW_TAG_variable @@ -19,3 +21,18 @@ # CHECK-SAME: DW_OP_convert (0x00000028 -> 0x00000092) # CHECK-SAME: DW_OP_convert (0x0000002c -> 0x00000096) # CHECK: version = 0x0005 + +# CHECKADDR: Addrs: [ +# CHECKADDR-NEXT: 0x0000000000001330 +# CHECKADDR-NEXT: 0x0000000000000000 +# CHECKADDR-NEXT: 0x0000000000001333 +# CHECKADDR-NEXT: ] +# CHECKADDR: Addrs: [ +# CHECKADDR-NEXT: 0x0000000000001340 +# CHECKADDR-NEXT: 0x0000000000000000 +# CHECKADDR-NEXT: 0x0000000000001343 +# CHECKADDR-NEXT: ] +# CHECKADDR: Addrs: [ +# CHECKADDR-NEXT: 0x0000000000001320 +# CHECKADDR-NEXT: 0x0000000000000000 +# CHECKADDR-NEXT: ] diff --git a/bolt/test/X86/dwarf5-one-loclists-two-bases.test b/bolt/test/X86/dwarf5-one-loclists-two-bases.test index 873512aad5e8d..f25f6c7a46858 100644 --- a/bolt/test/X86/dwarf5-one-loclists-two-bases.test +++ b/bolt/test/X86/dwarf5-one-loclists-two-bases.test @@ -34,7 +34,7 @@ # POSTCHECK: version = 0x0005 # POSTCHECK: DW_AT_loclists_base [DW_FORM_sec_offset] (0x0000000c) # POSTCHECK: DW_AT_rnglists_base [DW_FORM_sec_offset] (0x0000000c) -# POSTCHECK-EMPTY +# POSTCHECK-EMPTY: # POSTCHECK: DW_TAG_variable # POSTCHECK: DW_AT_location [DW_FORM_loclistx] # POSTCHECK-SAME: indexed (0x0) diff --git a/bolt/test/X86/dwarf5-two-loclists.test b/bolt/test/X86/dwarf5-two-loclists.test index 2ede02f3b76fb..a7c6351f9813c 100644 --- a/bolt/test/X86/dwarf5-two-loclists.test +++ b/bolt/test/X86/dwarf5-two-loclists.test @@ -45,7 +45,7 @@ # POSTCHECK: version = 0x0005 # POSTCHECK: DW_AT_loclists_base [DW_FORM_sec_offset] (0x0000000c) # POSTCHECK: DW_AT_rnglists_base [DW_FORM_sec_offset] (0x0000000c) -# POSTCHECK-EMPTY +# POSTCHECK-EMPTY: # POSTCHECK: DW_TAG_variable # POSTCHECK: DW_AT_location [DW_FORM_loclistx] # POSTCHECK-SAME: indexed (0x0) diff --git a/bolt/test/X86/dwarf5-two-rnglists.test b/bolt/test/X86/dwarf5-two-rnglists.test index 17cdc7643bae5..98f2e347d7673 100644 --- a/bolt/test/X86/dwarf5-two-rnglists.test +++ b/bolt/test/X86/dwarf5-two-rnglists.test @@ -52,7 +52,7 @@ # POSTCHECK-NEXT: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008) # POSTCHECK-NEXT: DW_AT_loclists_base [DW_FORM_sec_offset] (0x0000000c) # POSTCHECK-NEXT: DW_AT_rnglists_base [DW_FORM_sec_offset] (0x0000000c) -# POSTCHECK-EMPTY +# POSTCHECK-EMPTY: # POSTCHECK: DW_TAG_subprogram # POSTCHECK-NEXT: DW_AT_ranges [DW_FORM_rnglistx] # POSTCHECK-SAME: indexed (0x1) @@ -75,7 +75,7 @@ # POSTCHECK-NEXT: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000030) # POSTCHECK-NEXT: DW_AT_loclists_base [DW_FORM_sec_offset] (0x00000045) # POSTCHECK-NEXT: DW_AT_rnglists_base [DW_FORM_sec_offset] (0x00000035) -# POSTCHECK-EMPTY +# POSTCHECK-EMPTY: # POSTCHECK: DW_TAG_subprogram # POSTCHECK-NEXT: DW_AT_ranges [DW_FORM_rnglistx] diff --git a/bolt/test/X86/jump-table-fixed-ref-pic.test b/bolt/test/X86/jump-table-fixed-ref-pic.test index c8b6eda2278b9..d215c565b31e5 100644 --- a/bolt/test/X86/jump-table-fixed-ref-pic.test +++ b/bolt/test/X86/jump-table-fixed-ref-pic.test @@ -1,9 +1,13 @@ ## Verify that BOLT detects fixed destination of indirect jump for PIC ## case. -XFAIL: * - RUN: %clang %cflags -no-pie %S/Inputs/jump-table-fixed-ref-pic.s -Wl,-q -o %t -RUN: llvm-bolt %t --relocs -o %t.null 2>&1 | FileCheck %s +RUN: llvm-bolt %t --relocs -o %t.null -print-cfg 2>&1 | FileCheck %s + +CHECK: BOLT-INFO: fixed PIC indirect branch detected in main {{.*}} the destination value is 0x[[#TGT:]] +CHECK: Binary Function "main" after building cfg -CHECK: BOLT-INFO: fixed indirect branch detected in main +CHECK: movslq ".rodata/1"+8(%rip), %rax +CHECK-NEXT: leaq ".rodata/1"(%rip), %rdx +CHECK-NEXT: addq %rdx, %rax +CHECK-NEXT: jmpq *%rax # UNKNOWN CONTROL FLOW diff --git a/bolt/test/X86/match-functions-with-call-graph.test b/bolt/test/X86/match-functions-with-call-graph.test new file mode 100644 index 0000000000000..e826c57f35312 --- /dev/null +++ b/bolt/test/X86/match-functions-with-call-graph.test @@ -0,0 +1,103 @@ +## Tests blocks matching by called function names in inferStaleProfile. + +# REQUIRES: system-linux +# RUN: split-file %s %t +# RUN: %clang %cflags %t/main.cpp -o %t.exe -Wl,-q -nostdlib +# RUN: llvm-bolt %t.exe -o %t.out --data %t/yaml --profile-ignore-hash -v=1 \ +# RUN: --dyno-stats --print-cfg --infer-stale-profile=1 --match-with-call-graph 2>&1 | FileCheck %s + +# CHECK: BOLT-INFO: matched 1 functions with call graph + +#--- main.cpp +void foo() {} + +void bar() {} + +void qux() { + foo(); + bar(); +} + +void fred() { + foo(); + qux(); + bar(); + bar(); + foo(); +} + +int main() { + return 0; +} + +#--- yaml +--- +header: + profile-version: 1 + binary-name: 'match-functions-with-calls-as-anchors.s.tmp.exe' + binary-build-id: '' + profile-flags: [ lbr ] + profile-origin: branch profile reader + profile-events: '' + dfs-order: false + hash-func: xxh3 +functions: + - name: main + fid: 0 + hash: 0x0000000000000001 + exec: 1 + nblocks: 6 + blocks: + - bid: 1 + hash: 0x0000000000000001 + insns: 1 + succ: [ { bid: 3, cnt: 1} ] + - name: _Z3foov + fid: 1 + hash: 0x0000000000000002 + exec: 1 + nblocks: 6 + blocks: + - bid: 1 + hash: 0x0000000000000002 + insns: 1 + succ: [ { bid: 3, cnt: 1} ] + + - name: _Z3barv + fid: 2 + hash: 0x0000000000000003 + exec: 1 + nblocks: 6 + blocks: + - bid: 1 + hash: 0x0000000000000003 + insns: 1 + succ: [ { bid: 3, cnt: 1} ] + - name: _Z3quxv + fid: 3 + hash: 0x0000000000000004 + exec: 4 + nblocks: 6 + blocks: + - bid: 1 + hash: 0x0000000000000004 + insns: 1 + succ: [ { bid: 3, cnt: 1} ] + calls: [ { off : 0, fid : 1, cnt : 0}, + { off : 0, fid : 2, cnt : 0} ] + - name: _Z4bazv + fid: 4 + hash: 0x0000000000000005 + exec: 1 + nblocks: 6 + blocks: + - bid: 1 + hash: 0x0000000000000005 + insns: 1 + succ: [ { bid: 3, cnt: 1} ] + calls: [ { off : 0, fid : 3, cnt : 0}, + { off : 0, fid : 1, cnt : 0}, + { off : 0, fid : 2, cnt : 0}, + { off : 0, fid : 1, cnt : 0}, + { off : 0, fid : 2, cnt : 0} ] +... diff --git a/bolt/test/X86/pseudoprobe-decoding-inline.test b/bolt/test/X86/pseudoprobe-decoding-inline.test index 15e93b1630a66..b361551e5711e 100644 --- a/bolt/test/X86/pseudoprobe-decoding-inline.test +++ b/bolt/test/X86/pseudoprobe-decoding-inline.test @@ -1,5 +1,42 @@ # REQUIRES: system-linux -# RUN: llvm-bolt %S/../../../llvm/test/tools/llvm-profgen/Inputs/inline-cs-pseudoprobe.perfbin --print-pseudo-probes=all -o %t.bolt 2>&1 | FileCheck %s +# RUN: llvm-bolt %S/../../../llvm/test/tools/llvm-profgen/Inputs/inline-cs-pseudoprobe.perfbin --print-pseudo-probes=all -o %t.bolt --lite=0 --enable-bat 2>&1 | FileCheck %s + +# PREAGG: B X:0 #foo# 1 0 +# PREAGG: B X:0 #bar# 1 0 +# PREAGG: B X:0 #main# 1 0 +## Check pseudo-probes in regular YAML profile (non-BOLTed binary) +# RUN: link_fdata %s %S/../../../llvm/test/tools/llvm-profgen/Inputs/inline-cs-pseudoprobe.perfbin %t.preagg PREAGG +# RUN: perf2bolt %S/../../../llvm/test/tools/llvm-profgen/Inputs/inline-cs-pseudoprobe.perfbin -p %t.preagg --pa -w %t.yaml -o %t.fdata --profile-use-pseudo-probes +# RUN: FileCheck --input-file %t.yaml %s --check-prefix CHECK-YAML +## Check pseudo-probes in BAT YAML profile (BOLTed binary) +# RUN: link_fdata %s %t.bolt %t.preagg2 PREAGG +# RUN: perf2bolt %t.bolt -p %t.preagg2 --pa -w %t.yaml2 -o %t.fdata2 --profile-use-pseudo-probes +# RUN: FileCheck --input-file %t.yaml2 %s --check-prefix CHECK-YAML +# CHECK-YAML: name: bar +# CHECK-YAML: - bid: 0 +# CHECK-YAML: pseudo_probes: [ { guid: 0xE413754A191DB537, id: 1, type: 0 }, { guid: 0xE413754A191DB537, id: 4, type: 0 } ] +# CHECK-YAML: guid: 0xE413754A191DB537 +# CHECK-YAML: pseudo_probe_desc_hash: 0x10E852DA94 +# +# CHECK-YAML: name: foo +# CHECK-YAML: - bid: 0 +# CHECK-YAML: pseudo_probes: [ { guid: 0x5CF8C24CDB18BDAC, id: 1, type: 0 }, { guid: 0x5CF8C24CDB18BDAC, id: 2, type: 0 } ] +# CHECK-YAML: guid: 0x5CF8C24CDB18BDAC +# CHECK-YAML: pseudo_probe_desc_hash: 0x200205A19C5B4 +# +# CHECK-YAML: name: main +# CHECK-YAML: - bid: 0 +# CHECK-YAML: pseudo_probes: [ { guid: 0xDB956436E78DD5FA, id: 1, type: 0 }, { guid: 0x5CF8C24CDB18BDAC, id: 1, type: 0 }, { guid: 0x5CF8C24CDB18BDAC, id: 2, type: 0 } ] +# CHECK-YAML: guid: 0xDB956436E78DD5FA +# CHECK-YAML: pseudo_probe_desc_hash: 0x10000FFFFFFFF +# +## Check that without --profile-use-pseudo-probes option, no pseudo probes are +## generated +# RUN: perf2bolt %S/../../../llvm/test/tools/llvm-profgen/Inputs/inline-cs-pseudoprobe.perfbin -p %t.preagg --pa -w %t.yaml -o %t.fdata +# RUN: FileCheck --input-file %t.yaml %s --check-prefix CHECK-NO-OPT +# CHECK-NO-OPT-NOT: pseudo_probes +# CHECK-NO-OPT-NOT: guid +# CHECK-NO-OPT-NOT: pseudo_probe_desc_hash CHECK: Report of decoding input pseudo probe binaries diff --git a/bolt/test/X86/three-way-split-jt.s b/bolt/test/X86/three-way-split-jt.s new file mode 100644 index 0000000000000..c4ddc1b9905d7 --- /dev/null +++ b/bolt/test/X86/three-way-split-jt.s @@ -0,0 +1,95 @@ +## This reproduces an issue where the function is split into three fragments +## and all fragments access the same jump table. + +# REQUIRES: system-linux + +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o +# RUN: llvm-strip --strip-unneeded %t.o +# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q +# RUN: llvm-bolt %t.exe -o %t.out -v=1 -print-only=main.warm -print-cfg 2>&1 | FileCheck %s + +# CHECK-DAG: BOLT-INFO: marking main.warm as a fragment of main +# CHECK-DAG: BOLT-INFO: marking main.cold as a fragment of main +# CHECK-DAG: BOLT-INFO: processing main.warm as a sibling of non-ignored function +# CHECK-DAG: BOLT-INFO: processing main.cold as a sibling of non-ignored function +# CHECK-DAG: BOLT-WARNING: Ignoring main.cold +# CHECK-DAG: BOLT-WARNING: Ignoring main.warm +# CHECK-DAG: BOLT-WARNING: Ignoring main +# CHECK: BOLT-WARNING: skipped 3 functions due to cold fragments + +# CHECK: PIC Jump table JUMP_TABLE for function main, main.warm, main.cold +# CHECK-NEXT: 0x0000 : __ENTRY_main@0x[[#]] +# CHECK-NEXT: 0x0004 : __ENTRY_main@0x[[#]] +# CHECK-NEXT: 0x0008 : __ENTRY_main.cold@0x[[#]] +# CHECK-NEXT: 0x000c : __ENTRY_main@0x[[#]] + .globl main + .type main, %function + .p2align 2 +main: +LBB0: + andl $0xf, %ecx + cmpb $0x4, %cl + ## exit through ret + ja LBB3 + +## jump table dispatch, jumping to label indexed by val in %ecx +LBB1: + leaq JUMP_TABLE(%rip), %r8 + movzbl %cl, %ecx + movslq (%r8,%rcx,4), %rax + addq %rax, %r8 + jmpq *%r8 + +LBB2: + xorq %rax, %rax +LBB3: + addq $0x8, %rsp + ret +.size main, .-main + + .globl main.warm + .type main.warm, %function + .p2align 2 +main.warm: +LBB20: + andl $0xb, %ebx + cmpb $0x1, %cl + # exit through ret + ja LBB23 + +## jump table dispatch, jumping to label indexed by val in %ecx +LBB21: + leaq JUMP_TABLE(%rip), %r8 + movzbl %cl, %ecx + movslq (%r8,%rcx,4), %rax + addq %rax, %r8 + jmpq *%r8 + +LBB22: + xorq %rax, %rax +LBB23: + addq $0x8, %rsp + ret +.size main.warm, .-main.warm + +## cold fragment is only reachable through jump table + .globl main.cold + .type main.cold, %function +main.cold: + leaq JUMP_TABLE(%rip), %r8 + movzbl %cl, %ecx + movslq (%r8,%rcx,4), %rax + addq %rax, %r8 + jmpq *%r8 +LBB4: + callq abort +.size main.cold, .-main.cold + + .rodata +## jmp table, entries must be R_X86_64_PC32 relocs + .globl JUMP_TABLE +JUMP_TABLE: + .long LBB2-JUMP_TABLE + .long LBB3-JUMP_TABLE + .long LBB4-JUMP_TABLE + .long LBB3-JUMP_TABLE diff --git a/bolt/test/lit.cfg.py b/bolt/test/lit.cfg.py index 3a6da210e01f0..da3ae34ba3bdd 100644 --- a/bolt/test/lit.cfg.py +++ b/bolt/test/lit.cfg.py @@ -92,10 +92,22 @@ tool_dirs = [config.llvm_tools_dir, config.test_source_root] +llvm_bolt_args = [] + +if config.libbolt_rt_instr: + llvm_bolt_args.append(f"--runtime-instrumentation-lib={config.libbolt_rt_instr}") + +if config.libbolt_rt_hugify: + llvm_bolt_args.append(f"--runtime-hugify-lib={config.libbolt_rt_hugify}") + tools = [ ToolSubst("llc", unresolved="fatal"), ToolSubst("llvm-dwarfdump", unresolved="fatal"), - ToolSubst("llvm-bolt", unresolved="fatal"), + ToolSubst( + "llvm-bolt", + unresolved="fatal", + extra_args=llvm_bolt_args, + ), ToolSubst("llvm-boltdiff", unresolved="fatal"), ToolSubst("llvm-bolt-heatmap", unresolved="fatal"), ToolSubst("llvm-bat-dump", unresolved="fatal"), diff --git a/bolt/test/lit.site.cfg.py.in b/bolt/test/lit.site.cfg.py.in index 46cb326dfbae1..457908fc7c446 100644 --- a/bolt/test/lit.site.cfg.py.in +++ b/bolt/test/lit.site.cfg.py.in @@ -19,6 +19,8 @@ config.bolt_clang = "@BOLT_CLANG_EXE@" config.bolt_lld = "@BOLT_LLD_EXE@" config.targets_to_build = "@BOLT_TARGETS_TO_BUILD@" config.gnu_ld = "@GNU_LD_EXECUTABLE@" +config.libbolt_rt_instr = "@LIBBOLT_RT_INSTR@" +config.libbolt_rt_hugify = "@LIBBOLT_RT_HUGIFY@" import lit.llvm lit.llvm.initialize(lit_config, config) diff --git a/bolt/test/perf2bolt/lit.local.cfg b/bolt/test/perf2bolt/lit.local.cfg index 05f41ff333b0e..4ee9ad08cc78a 100644 --- a/bolt/test/perf2bolt/lit.local.cfg +++ b/bolt/test/perf2bolt/lit.local.cfg @@ -1,4 +1,4 @@ import shutil -if shutil.which("perf") != None: +if shutil.which("perf") is not None: config.available_features.add("perf") \ No newline at end of file diff --git a/bolt/test/timers.c b/bolt/test/timers.c new file mode 100644 index 0000000000000..a34958a2a15e9 --- /dev/null +++ b/bolt/test/timers.c @@ -0,0 +1,22 @@ +/* This test checks timers for metadata manager phases. +# RUN: %clang %cflags %s -o %t.exe +# RUN: link_fdata %s %t.exe %t.fdata +# RUN: llvm-bolt %t.exe -o %t.null --data %t.fdata -w %t.yaml --time-rewrite \ +# RUN: 2>&1 | FileCheck %s +# RUN: link_fdata %s %t.exe %t.preagg PREAGG +# RUN: perf2bolt %t.exe -o %t.null -p %t.preagg --pa --time-rewrite \ +# RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-P2B + +# CHECK-DAG: update metadata post-emit +# CHECK-DAG: process section metadata +# CHECK-DAG: process metadata pre-CFG +# CHECK-DAG: process metadata post-CFG +# CHECK-DAG: finalize metadata pre-emit + +# CHECK-P2B-DAG: process section metadata +# CHECK-P2B-DAG: process metadata pre-CFG + +# FDATA: 0 [unknown] 0 1 main 0 1 0 +# PREAGG: B X:0 #main# 1 0 +*/ +int main() { return 0; } diff --git a/bolt/utils/docker/Dockerfile b/bolt/utils/docker/Dockerfile index 722a07e46f9e4..c2108f7aec53c 100644 --- a/bolt/utils/docker/Dockerfile +++ b/bolt/utils/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:20.04 AS builder +FROM ubuntu:24.04 AS builder ARG DEBIAN_FRONTEND=noninteractive ENV TZ=UTC @@ -26,6 +26,6 @@ RUN mkdir build && \ ninja install-llvm-bolt install-perf2bolt install-merge-fdata \ install-llvm-boltdiff install-bolt_rt -FROM ubuntu:20.04 +FROM ubuntu:24.04 COPY --from=builder /home/bolt/install /usr/local diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index f6b5e8926f903..aef22453035c3 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -16,6 +16,7 @@ #include "llvm/Support/JSON.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" +#include #include #include @@ -979,6 +980,18 @@ static llvm::Error serializeIndex(ClangDocContext &CDCtx) { "error creating index file: " + FileErr.message()); } + llvm::SmallString<128> RootPath(CDCtx.OutDirectory); + if (llvm::sys::path::is_relative(RootPath)) { + llvm::sys::fs::make_absolute(RootPath); + } + // Replace the escaped characters with a forward slash. It shouldn't matter + // when rendering the webpage in a web browser. This helps to prevent the + // JavaScript from escaping characters incorrectly, and introducing bad paths + // in the URLs. + std::string RootPathEscaped = RootPath.str().str(); + std::replace(RootPathEscaped.begin(), RootPathEscaped.end(), '\\', '/'); + OS << "var RootPath = \"" << RootPathEscaped << "\";\n"; + CDCtx.Idx.sort(); llvm::json::OStream J(OS, 2); std::function IndexToJSON = [&](const Index &I) { diff --git a/clang-tools-extra/clang-doc/Mapper.cpp b/clang-tools-extra/clang-doc/Mapper.cpp index bb8b7952980ac..6c90db03424c6 100644 --- a/clang-tools-extra/clang-doc/Mapper.cpp +++ b/clang-tools-extra/clang-doc/Mapper.cpp @@ -12,16 +12,28 @@ #include "clang/AST/Comment.h" #include "clang/Index/USRGeneration.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/Support/Error.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/Support/Mutex.h" namespace clang { namespace doc { +static llvm::StringSet<> USRVisited; +static llvm::sys::Mutex USRVisitedGuard; + +template bool isTypedefAnonRecord(const T *D) { + if (const auto *C = dyn_cast(D)) { + return C->getTypedefNameForAnonDecl(); + } + return false; +} + void MapASTVisitor::HandleTranslationUnit(ASTContext &Context) { TraverseDecl(Context.getTranslationUnitDecl()); } -template bool MapASTVisitor::mapDecl(const T *D) { +template +bool MapASTVisitor::mapDecl(const T *D, bool IsDefinition) { // If we're looking a decl not in user files, skip this decl. if (D->getASTContext().getSourceManager().isInSystemHeader(D->getLocation())) return true; @@ -34,6 +46,16 @@ template bool MapASTVisitor::mapDecl(const T *D) { // If there is an error generating a USR for the decl, skip this decl. if (index::generateUSRForDecl(D, USR)) return true; + // Prevent Visiting USR twice + { + std::lock_guard Guard(USRVisitedGuard); + StringRef Visited = USR.str(); + if (USRVisited.count(Visited) && !isTypedefAnonRecord(D)) + return true; + // We considered a USR to be visited only when its defined + if (IsDefinition) + USRVisited.insert(Visited); + } bool IsFileInRootDir; llvm::SmallString<128> File = getFile(D, D->getASTContext(), CDCtx.SourceRoot, IsFileInRootDir); @@ -53,30 +75,34 @@ template bool MapASTVisitor::mapDecl(const T *D) { } bool MapASTVisitor::VisitNamespaceDecl(const NamespaceDecl *D) { - return mapDecl(D); + return mapDecl(D, /*isDefinition=*/true); } -bool MapASTVisitor::VisitRecordDecl(const RecordDecl *D) { return mapDecl(D); } +bool MapASTVisitor::VisitRecordDecl(const RecordDecl *D) { + return mapDecl(D, D->isThisDeclarationADefinition()); +} -bool MapASTVisitor::VisitEnumDecl(const EnumDecl *D) { return mapDecl(D); } +bool MapASTVisitor::VisitEnumDecl(const EnumDecl *D) { + return mapDecl(D, D->isThisDeclarationADefinition()); +} bool MapASTVisitor::VisitCXXMethodDecl(const CXXMethodDecl *D) { - return mapDecl(D); + return mapDecl(D, D->isThisDeclarationADefinition()); } bool MapASTVisitor::VisitFunctionDecl(const FunctionDecl *D) { // Don't visit CXXMethodDecls twice if (isa(D)) return true; - return mapDecl(D); + return mapDecl(D, D->isThisDeclarationADefinition()); } bool MapASTVisitor::VisitTypedefDecl(const TypedefDecl *D) { - return mapDecl(D); + return mapDecl(D, /*isDefinition=*/true); } bool MapASTVisitor::VisitTypeAliasDecl(const TypeAliasDecl *D) { - return mapDecl(D); + return mapDecl(D, /*isDefinition=*/true); } comments::FullComment * diff --git a/clang-tools-extra/clang-doc/Mapper.h b/clang-tools-extra/clang-doc/Mapper.h index cedde935ab743..75c8e947c8f90 100644 --- a/clang-tools-extra/clang-doc/Mapper.h +++ b/clang-tools-extra/clang-doc/Mapper.h @@ -43,7 +43,7 @@ class MapASTVisitor : public clang::RecursiveASTVisitor, bool VisitTypeAliasDecl(const TypeAliasDecl *D); private: - template bool mapDecl(const T *D); + template bool mapDecl(const T *D, bool IsDefinition); int getLine(const NamedDecl *D, const ASTContext &Context) const; llvm::SmallString<128> getFile(const NamedDecl *D, const ASTContext &Context, diff --git a/clang-tools-extra/clang-doc/assets/index.js b/clang-tools-extra/clang-doc/assets/index.js index 49818763a4393..6a223de66f84a 100644 --- a/clang-tools-extra/clang-doc/assets/index.js +++ b/clang-tools-extra/clang-doc/assets/index.js @@ -1,42 +1,17 @@ -// Append using posix-style a file name or directory to Base -function append(Base, New) { - if (!New) - return Base; - if (Base) - Base += "/"; - Base += New; - return Base; -} - -// Get relative path to access FilePath from CurrentDirectory -function computeRelativePath(FilePath, CurrentDirectory) { - var Path = FilePath; - while (Path) { - if (CurrentDirectory == Path) - return FilePath.substring(Path.length + 1); - Path = Path.substring(0, Path.lastIndexOf("/")); - } - - var Dir = CurrentDirectory; - var Result = ""; - while (Dir) { - if (Dir == FilePath) - break; - Dir = Dir.substring(0, Dir.lastIndexOf("/")); - Result = append(Result, "..") +function genLink(Ref) { + // we treat the file paths different depending on if we're + // serving via a http server or viewing from a local + var Path = window.location.protocol.startsWith("file") ? + `${window.location.protocol}//${window.location.host}/${Ref.Path}` : + `${window.location.protocol}//${RootPath}/${Ref.Path}`; + if (Ref.RefType === "namespace") { + Path = `${Path}/index.html` + } else if (Ref.Path === "") { + Path = `${Path}${Ref.Name}.html`; + } else { + Path = `${Path}/${Ref.Name}.html`; } - Result = append(Result, FilePath.substring(Dir.length)) - return Result; -} - -function genLink(Ref, CurrentDirectory) { - var Path = computeRelativePath(Ref.Path, CurrentDirectory); - if (Ref.RefType == "namespace") - Path = append(Path, "index.html"); - else - Path = append(Path, Ref.Name + ".html") - - ANode = document.createElement("a"); + ANode = document.createElement("a"); ANode.setAttribute("href", Path); var TextNode = document.createTextNode(Ref.Name); ANode.appendChild(TextNode); diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 6198a6e0cdcc3..3363cafeded5e 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -303,7 +303,6 @@ Example usage for a project using a compile commands database: for (auto &Group : USRToBitcode) { Pool.async([&]() { std::vector> Infos; - for (auto &Bitcode : Group.getValue()) { llvm::BitstreamCursor Stream(Bitcode); doc::ClangDocBitcodeReader Reader(Stream); diff --git a/clang-tools-extra/clang-tidy/add_new_check.py b/clang-tools-extra/clang-tidy/add_new_check.py index 3b14d5d158d2d..bd69bddcc6825 100755 --- a/clang-tools-extra/clang-tidy/add_new_check.py +++ b/clang-tools-extra/clang-tidy/add_new_check.py @@ -13,9 +13,12 @@ import argparse import io +import itertools import os import re import sys +import textwrap + # Adapts the module's CMakelist file. Returns 'True' if it could add a new # entry and 'False' if the entry already existed. @@ -53,7 +56,29 @@ def adapt_cmake(module_path, check_name_camel): # Adds a header for the new check. -def write_header(module_path, module, namespace, check_name, check_name_camel): +def write_header( + module_path, + module, + namespace, + check_name, + check_name_camel, + description, + lang_restrict, +): + wrapped_desc = "\n".join( + textwrap.wrap( + description, width=80, initial_indent="/// ", subsequent_indent="/// " + ) + ) + if lang_restrict: + override_supported = """ + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return %s; + }""" % ( + lang_restrict % {"lang": "LangOpts"} + ) + else: + override_supported = "" filename = os.path.join(module_path, check_name_camel) + ".h" print("Creating %s..." % filename) with io.open(filename, "w", encoding="utf8", newline="\n") as f: @@ -85,7 +110,7 @@ def write_header(module_path, module, namespace, check_name, check_name_camel): namespace clang::tidy::%(namespace)s { -/// FIXME: Write a short description. +%(description)s /// /// For the user-facing documentation see: /// http://clang.llvm.org/extra/clang-tidy/checks/%(module)s/%(check_name)s.html @@ -94,7 +119,7 @@ class %(check_name_camel)s : public ClangTidyCheck { %(check_name_camel)s(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} void registerMatchers(ast_matchers::MatchFinder *Finder) override; - void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override;%(override_supported)s }; } // namespace clang::tidy::%(namespace)s @@ -107,6 +132,8 @@ class %(check_name_camel)s : public ClangTidyCheck { "check_name": check_name, "module": module, "namespace": namespace, + "description": wrapped_desc, + "override_supported": override_supported, } ) @@ -235,7 +262,12 @@ def adapt_module(module_path, module, check_name, check_name_camel): # Adds a release notes entry. -def add_release_notes(module_path, module, check_name): +def add_release_notes(module_path, module, check_name, description): + wrapped_desc = "\n".join( + textwrap.wrap( + description, width=80, initial_indent=" ", subsequent_indent=" " + ) + ) check_name_dashes = module + "-" + check_name filename = os.path.normpath( os.path.join(module_path, "../../docs/ReleaseNotes.rst") @@ -281,10 +313,10 @@ def add_release_notes(module_path, module, check_name): """- New :doc:`%s ` check. - FIXME: add release notes. +%s """ - % (check_name_dashes, module, check_name) + % (check_name_dashes, module, check_name, wrapped_desc) ) note_added = True @@ -292,7 +324,9 @@ def add_release_notes(module_path, module, check_name): # Adds a test for the check. -def write_test(module_path, module, check_name, test_extension): +def write_test(module_path, module, check_name, test_extension, test_standard): + if test_standard: + test_standard = f"-std={test_standard}-or-later " check_name_dashes = module + "-" + check_name filename = os.path.normpath( os.path.join( @@ -309,7 +343,7 @@ def write_test(module_path, module, check_name, test_extension): print("Creating %s..." % filename) with io.open(filename, "w", encoding="utf8", newline="\n") as f: f.write( - """// RUN: %%check_clang_tidy %%s %(check_name_dashes)s %%t + """// RUN: %%check_clang_tidy %(standard)s%%s %(check_name_dashes)s %%t // FIXME: Add something that triggers the check here. void f(); @@ -324,7 +358,7 @@ def write_test(module_path, module, check_name, test_extension): // FIXME: Add something that doesn't trigger the check here. void awesome_f2(); """ - % {"check_name_dashes": check_name_dashes} + % {"check_name_dashes": check_name_dashes, "standard": test_standard} ) @@ -497,7 +531,10 @@ def format_link_alias(doc_file): if (match or (check_name.startswith("clang-analyzer-"))) and check_name: module = doc_file[0] check_file = doc_file[1].replace(".rst", "") - if not match or match.group(1) == "https://clang.llvm.org/docs/analyzer/checkers": + if ( + not match + or match.group(1) == "https://clang.llvm.org/docs/analyzer/checkers" + ): title = "Clang Static Analyzer " + check_file # Preserve the anchor in checkers.html from group 2. target = "" if not match else match.group(1) + ".html" + match.group(2) @@ -515,7 +552,7 @@ def format_link_alias(doc_file): if target: # The checker is just a redirect. return ( - " :doc:`%(check_name)s <%(module)s/%(check_file)s>`, %(ref_begin)s`%(title)s <%(target)s>`%(ref_end)s,%(autofix)s\n" + " :doc:`%(check_name)s <%(module)s/%(check_file)s>`, %(ref_begin)s`%(title)s <%(target)s>`%(ref_end)s,%(autofix)s\n" % { "check_name": check_name, "module": module, @@ -523,13 +560,14 @@ def format_link_alias(doc_file): "target": target, "title": title, "autofix": autofix, - "ref_begin" : ref_begin, - "ref_end" : ref_end - }) + "ref_begin": ref_begin, + "ref_end": ref_end, + } + ) else: # The checker is just a alias without redirect. return ( - " :doc:`%(check_name)s <%(module)s/%(check_file)s>`, %(title)s,%(autofix)s\n" + " :doc:`%(check_name)s <%(module)s/%(check_file)s>`, %(title)s,%(autofix)s\n" % { "check_name": check_name, "module": module, @@ -537,7 +575,8 @@ def format_link_alias(doc_file): "target": target, "title": title, "autofix": autofix, - }) + } + ) return "" checks = map(format_link, doc_files) @@ -552,8 +591,8 @@ def format_link_alias(doc_file): f.write(' :header: "Name", "Offers fixes"\n\n') f.writelines(checks) # and the aliases - f.write("\n\n") - f.write(".. csv-table:: Aliases..\n") + f.write("\nCheck aliases\n-------------\n\n") + f.write(".. csv-table::\n") f.write(' :header: "Name", "Redirect", "Offers fixes"\n\n') f.writelines(checks_alias) break @@ -599,6 +638,22 @@ def main(): "objc": "m", "objc++": "mm", } + cpp_language_to_requirements = { + "c++98": "CPlusPlus", + "c++11": "CPlusPlus11", + "c++14": "CPlusPlus14", + "c++17": "CPlusPlus17", + "c++20": "CPlusPlus20", + "c++23": "CPlusPlus23", + "c++26": "CPlusPlus26", + } + c_language_to_requirements = { + "c99": None, + "c11": "C11", + "c17": "C17", + "c23": "C23", + "c27": "C2Y", + } parser = argparse.ArgumentParser() parser.add_argument( "--update-docs", @@ -609,9 +664,26 @@ def main(): "--language", help="language to use for new check (defaults to c++)", choices=language_to_extension.keys(), - default="c++", + default=None, metavar="LANG", ) + parser.add_argument( + "--description", + "-d", + help="short description of what the check does", + default="FIXME: Write a short description", + type=str, + ) + parser.add_argument( + "--standard", + help="Specify a specific version of the language", + choices=list( + itertools.chain( + cpp_language_to_requirements.keys(), c_language_to_requirements.keys() + ) + ), + default=None, + ) parser.add_argument( "module", nargs="?", @@ -652,12 +724,53 @@ def main(): else: namespace = module - write_header(module_path, module, namespace, check_name, check_name_camel) + description = args.description + if not description.endswith("."): + description += "." + + language = args.language + + if args.standard: + if args.standard in cpp_language_to_requirements: + if language and language != "c++": + raise ValueError("C++ standard chosen when language is not C++") + language = "c++" + elif args.standard in c_language_to_requirements: + if language and language != "c": + raise ValueError("C standard chosen when language is not C") + language = "c" + + if not language: + language = "c++" + + language_restrict = None + + if language == "c": + language_restrict = "!%(lang)s.CPlusPlus" + extra = c_language_to_requirements.get(args.standard, None) + if extra: + language_restrict += f" && %(lang)s.{extra}" + elif language == "c++": + language_restrict = ( + f"%(lang)s.{cpp_language_to_requirements.get(args.standard, 'CPlusPlus')}" + ) + elif language in ["objc", "objc++"]: + language_restrict = "%(lang)s.ObjC" + + write_header( + module_path, + module, + namespace, + check_name, + check_name_camel, + description, + language_restrict, + ) write_implementation(module_path, module, namespace, check_name_camel) adapt_module(module_path, module, check_name, check_name_camel) - add_release_notes(module_path, module, check_name) - test_extension = language_to_extension.get(args.language) - write_test(module_path, module, check_name, test_extension) + add_release_notes(module_path, module, check_name, description) + test_extension = language_to_extension.get(language) + write_test(module_path, module, check_name, test_extension, args.standard) write_docs(module_path, module, check_name) update_checks_list(clang_tidy_path) print("Done. Now it's your turn!") diff --git a/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp index 955a9b94dfaf6..1da5b222c2e8f 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp @@ -138,13 +138,13 @@ UnusedReturnValueCheck::UnusedReturnValueCheck(llvm::StringRef Name, "^::sigismember$;" "^::strcasecmp$;" "^::strsignal$;" - "^::ttyname"))), + "^::ttyname$"))), CheckedReturnTypes(utils::options::parseStringList( - Options.get("CheckedReturnTypes", "::std::error_code$;" - "::std::error_condition$;" - "::std::errc$;" - "::std::expected$;" - "::boost::system::error_code"))), + Options.get("CheckedReturnTypes", "^::std::error_code$;" + "^::std::error_condition$;" + "^::std::errc$;" + "^::std::expected$;" + "^::boost::system::error_code$"))), AllowCastToVoid(Options.get("AllowCastToVoid", false)) {} UnusedReturnValueCheck::UnusedReturnValueCheck( diff --git a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp index ffb62b409b29b..8b5be9cd95f76 100644 --- a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp @@ -49,183 +49,183 @@ namespace { // with NULL argument and in this case the check is not applicable: // `mblen, mbrlen, mbrtowc, mbtowc, wctomb, wctomb_s`. // FIXME: The check can be improved to handle such cases. -const llvm::StringRef CertErr33CCheckedFunctions = "::aligned_alloc;" - "::asctime_s;" - "::at_quick_exit;" - "::atexit;" - "::bsearch;" - "::bsearch_s;" - "::btowc;" - "::c16rtomb;" - "::c32rtomb;" - "::calloc;" - "::clock;" - "::cnd_broadcast;" - "::cnd_init;" - "::cnd_signal;" - "::cnd_timedwait;" - "::cnd_wait;" - "::ctime_s;" - "::fclose;" - "::fflush;" - "::fgetc;" - "::fgetpos;" - "::fgets;" - "::fgetwc;" - "::fopen;" - "::fopen_s;" - "::fprintf;" - "::fprintf_s;" - "::fputc;" - "::fputs;" - "::fputwc;" - "::fputws;" - "::fread;" - "::freopen;" - "::freopen_s;" - "::fscanf;" - "::fscanf_s;" - "::fseek;" - "::fsetpos;" - "::ftell;" - "::fwprintf;" - "::fwprintf_s;" - "::fwrite;" - "::fwscanf;" - "::fwscanf_s;" - "::getc;" - "::getchar;" - "::getenv;" - "::getenv_s;" - "::gets_s;" - "::getwc;" - "::getwchar;" - "::gmtime;" - "::gmtime_s;" - "::localtime;" - "::localtime_s;" - "::malloc;" - "::mbrtoc16;" - "::mbrtoc32;" - "::mbsrtowcs;" - "::mbsrtowcs_s;" - "::mbstowcs;" - "::mbstowcs_s;" - "::memchr;" - "::mktime;" - "::mtx_init;" - "::mtx_lock;" - "::mtx_timedlock;" - "::mtx_trylock;" - "::mtx_unlock;" - "::printf_s;" - "::putc;" - "::putwc;" - "::raise;" - "::realloc;" - "::remove;" - "::rename;" - "::scanf;" - "::scanf_s;" - "::setlocale;" - "::setvbuf;" - "::signal;" - "::snprintf;" - "::snprintf_s;" - "::sprintf;" - "::sprintf_s;" - "::sscanf;" - "::sscanf_s;" - "::strchr;" - "::strerror_s;" - "::strftime;" - "::strpbrk;" - "::strrchr;" - "::strstr;" - "::strtod;" - "::strtof;" - "::strtoimax;" - "::strtok;" - "::strtok_s;" - "::strtol;" - "::strtold;" - "::strtoll;" - "::strtoul;" - "::strtoull;" - "::strtoumax;" - "::strxfrm;" - "::swprintf;" - "::swprintf_s;" - "::swscanf;" - "::swscanf_s;" - "::thrd_create;" - "::thrd_detach;" - "::thrd_join;" - "::thrd_sleep;" - "::time;" - "::timespec_get;" - "::tmpfile;" - "::tmpfile_s;" - "::tmpnam;" - "::tmpnam_s;" - "::tss_create;" - "::tss_get;" - "::tss_set;" - "::ungetc;" - "::ungetwc;" - "::vfprintf;" - "::vfprintf_s;" - "::vfscanf;" - "::vfscanf_s;" - "::vfwprintf;" - "::vfwprintf_s;" - "::vfwscanf;" - "::vfwscanf_s;" - "::vprintf_s;" - "::vscanf;" - "::vscanf_s;" - "::vsnprintf;" - "::vsnprintf_s;" - "::vsprintf;" - "::vsprintf_s;" - "::vsscanf;" - "::vsscanf_s;" - "::vswprintf;" - "::vswprintf_s;" - "::vswscanf;" - "::vswscanf_s;" - "::vwprintf_s;" - "::vwscanf;" - "::vwscanf_s;" - "::wcrtomb;" - "::wcschr;" - "::wcsftime;" - "::wcspbrk;" - "::wcsrchr;" - "::wcsrtombs;" - "::wcsrtombs_s;" - "::wcsstr;" - "::wcstod;" - "::wcstof;" - "::wcstoimax;" - "::wcstok;" - "::wcstok_s;" - "::wcstol;" - "::wcstold;" - "::wcstoll;" - "::wcstombs;" - "::wcstombs_s;" - "::wcstoul;" - "::wcstoull;" - "::wcstoumax;" - "::wcsxfrm;" - "::wctob;" - "::wctrans;" - "::wctype;" - "::wmemchr;" - "::wprintf_s;" - "::wscanf;" - "::wscanf_s;"; +const llvm::StringRef CertErr33CCheckedFunctions = "^::aligned_alloc;" + "^::asctime_s;" + "^::at_quick_exit;" + "^::atexit;" + "^::bsearch;" + "^::bsearch_s;" + "^::btowc;" + "^::c16rtomb;" + "^::c32rtomb;" + "^::calloc;" + "^::clock;" + "^::cnd_broadcast;" + "^::cnd_init;" + "^::cnd_signal;" + "^::cnd_timedwait;" + "^::cnd_wait;" + "^::ctime_s;" + "^::fclose;" + "^::fflush;" + "^::fgetc;" + "^::fgetpos;" + "^::fgets;" + "^::fgetwc;" + "^::fopen;" + "^::fopen_s;" + "^::fprintf;" + "^::fprintf_s;" + "^::fputc;" + "^::fputs;" + "^::fputwc;" + "^::fputws;" + "^::fread;" + "^::freopen;" + "^::freopen_s;" + "^::fscanf;" + "^::fscanf_s;" + "^::fseek;" + "^::fsetpos;" + "^::ftell;" + "^::fwprintf;" + "^::fwprintf_s;" + "^::fwrite;" + "^::fwscanf;" + "^::fwscanf_s;" + "^::getc;" + "^::getchar;" + "^::getenv;" + "^::getenv_s;" + "^::gets_s;" + "^::getwc;" + "^::getwchar;" + "^::gmtime;" + "^::gmtime_s;" + "^::localtime;" + "^::localtime_s;" + "^::malloc;" + "^::mbrtoc16;" + "^::mbrtoc32;" + "^::mbsrtowcs;" + "^::mbsrtowcs_s;" + "^::mbstowcs;" + "^::mbstowcs_s;" + "^::memchr;" + "^::mktime;" + "^::mtx_init;" + "^::mtx_lock;" + "^::mtx_timedlock;" + "^::mtx_trylock;" + "^::mtx_unlock;" + "^::printf_s;" + "^::putc;" + "^::putwc;" + "^::raise;" + "^::realloc;" + "^::remove;" + "^::rename;" + "^::scanf;" + "^::scanf_s;" + "^::setlocale;" + "^::setvbuf;" + "^::signal;" + "^::snprintf;" + "^::snprintf_s;" + "^::sprintf;" + "^::sprintf_s;" + "^::sscanf;" + "^::sscanf_s;" + "^::strchr;" + "^::strerror_s;" + "^::strftime;" + "^::strpbrk;" + "^::strrchr;" + "^::strstr;" + "^::strtod;" + "^::strtof;" + "^::strtoimax;" + "^::strtok;" + "^::strtok_s;" + "^::strtol;" + "^::strtold;" + "^::strtoll;" + "^::strtoul;" + "^::strtoull;" + "^::strtoumax;" + "^::strxfrm;" + "^::swprintf;" + "^::swprintf_s;" + "^::swscanf;" + "^::swscanf_s;" + "^::thrd_create;" + "^::thrd_detach;" + "^::thrd_join;" + "^::thrd_sleep;" + "^::time;" + "^::timespec_get;" + "^::tmpfile;" + "^::tmpfile_s;" + "^::tmpnam;" + "^::tmpnam_s;" + "^::tss_create;" + "^::tss_get;" + "^::tss_set;" + "^::ungetc;" + "^::ungetwc;" + "^::vfprintf;" + "^::vfprintf_s;" + "^::vfscanf;" + "^::vfscanf_s;" + "^::vfwprintf;" + "^::vfwprintf_s;" + "^::vfwscanf;" + "^::vfwscanf_s;" + "^::vprintf_s;" + "^::vscanf;" + "^::vscanf_s;" + "^::vsnprintf;" + "^::vsnprintf_s;" + "^::vsprintf;" + "^::vsprintf_s;" + "^::vsscanf;" + "^::vsscanf_s;" + "^::vswprintf;" + "^::vswprintf_s;" + "^::vswscanf;" + "^::vswscanf_s;" + "^::vwprintf_s;" + "^::vwscanf;" + "^::vwscanf_s;" + "^::wcrtomb;" + "^::wcschr;" + "^::wcsftime;" + "^::wcspbrk;" + "^::wcsrchr;" + "^::wcsrtombs;" + "^::wcsrtombs_s;" + "^::wcsstr;" + "^::wcstod;" + "^::wcstof;" + "^::wcstoimax;" + "^::wcstok;" + "^::wcstok_s;" + "^::wcstol;" + "^::wcstold;" + "^::wcstoll;" + "^::wcstombs;" + "^::wcstombs_s;" + "^::wcstoul;" + "^::wcstoull;" + "^::wcstoumax;" + "^::wcsxfrm;" + "^::wctob;" + "^::wctrans;" + "^::wctype;" + "^::wmemchr;" + "^::wprintf_s;" + "^::wscanf;" + "^::wscanf_s;"; } // namespace diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp index 8b500de0c028c..e20cf6fbcb55a 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp @@ -93,13 +93,12 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { // shall be run. const auto FunctionScope = functionDecl( - hasBody( - compoundStmt(forEachDescendant( - declStmt(containsAnyDeclaration( - LocalValDecl.bind("local-value")), - unless(has(decompositionDecl()))) - .bind("decl-stmt"))) - .bind("scope"))) + hasBody(stmt(forEachDescendant( + declStmt(containsAnyDeclaration( + LocalValDecl.bind("local-value")), + unless(has(decompositionDecl()))) + .bind("decl-stmt"))) + .bind("scope"))) .bind("function-decl"); Finder->addMatcher(FunctionScope, this); @@ -109,7 +108,7 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { enum class VariableCategory { Value, Reference, Pointer }; void ConstCorrectnessCheck::check(const MatchFinder::MatchResult &Result) { - const auto *LocalScope = Result.Nodes.getNodeAs("scope"); + const auto *LocalScope = Result.Nodes.getNodeAs("scope"); const auto *Variable = Result.Nodes.getNodeAs("local-value"); const auto *Function = Result.Nodes.getNodeAs("function-decl"); @@ -198,7 +197,7 @@ void ConstCorrectnessCheck::check(const MatchFinder::MatchResult &Result) { } } -void ConstCorrectnessCheck::registerScope(const CompoundStmt *LocalScope, +void ConstCorrectnessCheck::registerScope(const Stmt *LocalScope, ASTContext *Context) { auto &Analyzer = ScopesCache[LocalScope]; if (!Analyzer) diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h index 08ffde524522a..bba060e555d00 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h @@ -32,10 +32,10 @@ class ConstCorrectnessCheck : public ClangTidyCheck { void check(const ast_matchers::MatchFinder::MatchResult &Result) override; private: - void registerScope(const CompoundStmt *LocalScope, ASTContext *Context); + void registerScope(const Stmt *LocalScope, ASTContext *Context); using MutationAnalyzer = std::unique_ptr; - llvm::DenseMap ScopesCache; + llvm::DenseMap ScopesCache; llvm::DenseSet TemplateDiagnosticsCache; const bool AnalyzeValues; diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp index 5a4c2363bd8af..3a255c5c133f1 100644 --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp @@ -119,65 +119,72 @@ void UnnecessaryValueParamCheck::check(const MatchFinder::MatchResult &Result) { } } - const size_t Index = llvm::find(Function->parameters(), Param) - - Function->parameters().begin(); + handleConstRefFix(*Function, *Param, *Result.Context); +} + +void UnnecessaryValueParamCheck::registerPPCallbacks( + const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + Inserter.registerPreprocessor(PP); +} + +void UnnecessaryValueParamCheck::storeOptions( + ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", Inserter.getStyle()); + Options.store(Opts, "AllowedTypes", + utils::options::serializeStringList(AllowedTypes)); +} + +void UnnecessaryValueParamCheck::onEndOfTranslationUnit() { + MutationAnalyzerCache.clear(); +} + +void UnnecessaryValueParamCheck::handleConstRefFix(const FunctionDecl &Function, + const ParmVarDecl &Param, + ASTContext &Context) { + const size_t Index = + llvm::find(Function.parameters(), &Param) - Function.parameters().begin(); + const bool IsConstQualified = + Param.getType().getCanonicalType().isConstQualified(); auto Diag = - diag(Param->getLocation(), + diag(Param.getLocation(), "the %select{|const qualified }0parameter %1 is copied for each " "invocation%select{ but only used as a const reference|}0; consider " "making it a %select{const |}0reference") - << IsConstQualified << paramNameOrIndex(Param->getName(), Index); + << IsConstQualified << paramNameOrIndex(Param.getName(), Index); // Do not propose fixes when: // 1. the ParmVarDecl is in a macro, since we cannot place them correctly // 2. the function is virtual as it might break overrides // 3. the function is referenced outside of a call expression within the // compilation unit as the signature change could introduce build errors. // 4. the function is an explicit template/ specialization. - const auto *Method = llvm::dyn_cast(Function); - if (Param->getBeginLoc().isMacroID() || (Method && Method->isVirtual()) || - isReferencedOutsideOfCallExpr(*Function, *Result.Context) || - Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) + const auto *Method = llvm::dyn_cast(&Function); + if (Param.getBeginLoc().isMacroID() || (Method && Method->isVirtual()) || + isReferencedOutsideOfCallExpr(Function, Context) || + Function.getTemplateSpecializationKind() == TSK_ExplicitSpecialization) return; - for (const auto *FunctionDecl = Function; FunctionDecl != nullptr; + for (const auto *FunctionDecl = &Function; FunctionDecl != nullptr; FunctionDecl = FunctionDecl->getPreviousDecl()) { const auto &CurrentParam = *FunctionDecl->getParamDecl(Index); - Diag << utils::fixit::changeVarDeclToReference(CurrentParam, - *Result.Context); + Diag << utils::fixit::changeVarDeclToReference(CurrentParam, Context); // The parameter of each declaration needs to be checked individually as to // whether it is const or not as constness can differ between definition and // declaration. if (!CurrentParam.getType().getCanonicalType().isConstQualified()) { if (std::optional Fix = utils::fixit::addQualifierToVarDecl( - CurrentParam, *Result.Context, DeclSpec::TQ::TQ_const)) + CurrentParam, Context, DeclSpec::TQ::TQ_const)) Diag << *Fix; } } } -void UnnecessaryValueParamCheck::registerPPCallbacks( - const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { - Inserter.registerPreprocessor(PP); -} - -void UnnecessaryValueParamCheck::storeOptions( - ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "IncludeStyle", Inserter.getStyle()); - Options.store(Opts, "AllowedTypes", - utils::options::serializeStringList(AllowedTypes)); -} - -void UnnecessaryValueParamCheck::onEndOfTranslationUnit() { - MutationAnalyzerCache.clear(); -} - -void UnnecessaryValueParamCheck::handleMoveFix(const ParmVarDecl &Var, +void UnnecessaryValueParamCheck::handleMoveFix(const ParmVarDecl &Param, const DeclRefExpr &CopyArgument, - const ASTContext &Context) { + ASTContext &Context) { auto Diag = diag(CopyArgument.getBeginLoc(), "parameter %0 is passed by value and only copied once; " "consider moving it to avoid unnecessary copies") - << &Var; + << &Param; // Do not propose fixes in macros since we cannot place them correctly. if (CopyArgument.getBeginLoc().isMacroID()) return; diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.h b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.h index 7250bffd20b2f..8bfd814d16357 100644 --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.h +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.h @@ -33,10 +33,16 @@ class UnnecessaryValueParamCheck : public ClangTidyCheck { void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void onEndOfTranslationUnit() override; -private: - void handleMoveFix(const ParmVarDecl &Var, const DeclRefExpr &CopyArgument, - const ASTContext &Context); +protected: + // Create diagnostics. These are virtual so that derived classes can change + // behaviour. + virtual void handleMoveFix(const ParmVarDecl &Param, + const DeclRefExpr &CopyArgument, + ASTContext &Context); + virtual void handleConstRefFix(const FunctionDecl &Function, + const ParmVarDecl &Param, ASTContext &Context); +private: ExprMutationAnalyzer::Memoized MutationAnalyzerCache; utils::IncludeInserter Inserter; const std::vector AllowedTypes; diff --git a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp index 95a3a5165e2e8..43b69a24bdb16 100644 --- a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp @@ -157,9 +157,12 @@ void NonConstParameterCheck::diagnoseNonConstParameters() { if (!Function) continue; unsigned Index = Par->getFunctionScopeIndex(); - for (FunctionDecl *FnDecl : Function->redecls()) + for (FunctionDecl *FnDecl : Function->redecls()) { + if (FnDecl->getNumParams() <= Index) + continue; Fixes.push_back(FixItHint::CreateInsertion( FnDecl->getParamDecl(Index)->getBeginLoc(), "const ")); + } diag(Par->getLocation(), "pointer parameter '%0' can be pointer to const") << Par->getName() << Fixes; diff --git a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py index 0dc35ad587362..48401ba5ea42a 100755 --- a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py +++ b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py @@ -34,29 +34,32 @@ http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html """ -from __future__ import print_function - import argparse +import asyncio +from dataclasses import dataclass import glob import json import multiprocessing import os -import queue import re import shutil import subprocess import sys import tempfile -import threading +import time import traceback +from types import ModuleType +from typing import Any, Awaitable, Callable, List, Optional, Tuple, TypeVar + +yaml: Optional[ModuleType] = None try: import yaml except ImportError: yaml = None -def strtobool(val): +def strtobool(val: str) -> bool: """Convert a string representation of truth to a bool following LLVM's CLI argument parsing.""" val = val.lower() @@ -67,11 +70,11 @@ def strtobool(val): # Return ArgumentTypeError so that argparse does not substitute its own error message raise argparse.ArgumentTypeError( - "'{}' is invalid value for boolean argument! Try 0 or 1.".format(val) + f"'{val}' is invalid value for boolean argument! Try 0 or 1." ) -def find_compilation_database(path): +def find_compilation_database(path: str) -> str: """Adjusts the directory until a compilation database is found.""" result = os.path.realpath("./") while not os.path.isfile(os.path.join(result, path)): @@ -83,49 +86,43 @@ def find_compilation_database(path): return result -def make_absolute(f, directory): - if os.path.isabs(f): - return f - return os.path.normpath(os.path.join(directory, f)) - - def get_tidy_invocation( - f, - clang_tidy_binary, - checks, - tmpdir, - build_path, - header_filter, - allow_enabling_alpha_checkers, - extra_arg, - extra_arg_before, - quiet, - config_file_path, - config, - line_filter, - use_color, - plugins, - warnings_as_errors, - exclude_header_filter, - allow_no_checks, -): + f: str, + clang_tidy_binary: str, + checks: str, + tmpdir: Optional[str], + build_path: str, + header_filter: Optional[str], + allow_enabling_alpha_checkers: bool, + extra_arg: List[str], + extra_arg_before: List[str], + quiet: bool, + config_file_path: str, + config: str, + line_filter: Optional[str], + use_color: bool, + plugins: List[str], + warnings_as_errors: Optional[str], + exclude_header_filter: Optional[str], + allow_no_checks: bool, +) -> List[str]: """Gets a command line for clang-tidy.""" start = [clang_tidy_binary] if allow_enabling_alpha_checkers: start.append("-allow-enabling-analyzer-alpha-checkers") if exclude_header_filter is not None: - start.append("--exclude-header-filter=" + exclude_header_filter) + start.append(f"--exclude-header-filter={exclude_header_filter}") if header_filter is not None: - start.append("-header-filter=" + header_filter) + start.append(f"-header-filter={header_filter}") if line_filter is not None: - start.append("-line-filter=" + line_filter) + start.append(f"-line-filter={line_filter}") if use_color is not None: if use_color: start.append("--use-color") else: start.append("--use-color=false") if checks: - start.append("-checks=" + checks) + start.append(f"-checks={checks}") if tmpdir is not None: start.append("-export-fixes") # Get a temporary file. We immediately close the handle so clang-tidy can @@ -134,28 +131,29 @@ def get_tidy_invocation( os.close(handle) start.append(name) for arg in extra_arg: - start.append("-extra-arg=%s" % arg) + start.append(f"-extra-arg={arg}") for arg in extra_arg_before: - start.append("-extra-arg-before=%s" % arg) - start.append("-p=" + build_path) + start.append(f"-extra-arg-before={arg}") + start.append(f"-p={build_path}") if quiet: start.append("-quiet") if config_file_path: - start.append("--config-file=" + config_file_path) + start.append(f"--config-file={config_file_path}") elif config: - start.append("-config=" + config) + start.append(f"-config={config}") for plugin in plugins: - start.append("-load=" + plugin) + start.append(f"-load={plugin}") if warnings_as_errors: - start.append("--warnings-as-errors=" + warnings_as_errors) + start.append(f"--warnings-as-errors={warnings_as_errors}") if allow_no_checks: start.append("--allow-no-checks") start.append(f) return start -def merge_replacement_files(tmpdir, mergefile): +def merge_replacement_files(tmpdir: str, mergefile: str) -> None: """Merge all replacement files in a directory into a single file""" + assert yaml # The fixes suggested by clang-tidy >= 4.0.0 are given under # the top level key 'Diagnostics' in the output yaml files mergekey = "Diagnostics" @@ -179,16 +177,14 @@ def merge_replacement_files(tmpdir, mergefile): open(mergefile, "w").close() -def find_binary(arg, name, build_path): +def find_binary(arg: str, name: str, build_path: str) -> str: """Get the path for a binary or exit""" if arg: if shutil.which(arg): return arg else: raise SystemExit( - "error: passed binary '{}' was not found or is not executable".format( - arg - ) + f"error: passed binary '{arg}' was not found or is not executable" ) built_path = os.path.join(build_path, "bin", name) @@ -196,66 +192,102 @@ def find_binary(arg, name, build_path): if binary: return binary else: - raise SystemExit( - "error: failed to find {} in $PATH or at {}".format(name, built_path) - ) + raise SystemExit(f"error: failed to find {name} in $PATH or at {built_path}") -def apply_fixes(args, clang_apply_replacements_binary, tmpdir): +def apply_fixes( + args: argparse.Namespace, clang_apply_replacements_binary: str, tmpdir: str +) -> None: """Calls clang-apply-fixes on a given directory.""" invocation = [clang_apply_replacements_binary] invocation.append("-ignore-insert-conflict") if args.format: invocation.append("-format") if args.style: - invocation.append("-style=" + args.style) + invocation.append(f"-style={args.style}") invocation.append(tmpdir) subprocess.call(invocation) -def run_tidy(args, clang_tidy_binary, tmpdir, build_path, queue, lock, failed_files): - """Takes filenames out of queue and runs clang-tidy on them.""" - while True: - name = queue.get() - invocation = get_tidy_invocation( - name, - clang_tidy_binary, - args.checks, - tmpdir, - build_path, - args.header_filter, - args.allow_enabling_alpha_checkers, - args.extra_arg, - args.extra_arg_before, - args.quiet, - args.config_file, - args.config, - args.line_filter, - args.use_color, - args.plugins, - args.warnings_as_errors, - args.exclude_header_filter, - args.allow_no_checks, - ) +# FIXME Python 3.12: This can be simplified out with run_with_semaphore[T](...). +T = TypeVar("T") + + +async def run_with_semaphore( + semaphore: asyncio.Semaphore, + f: Callable[..., Awaitable[T]], + *args: Any, + **kwargs: Any, +) -> T: + async with semaphore: + return await f(*args, **kwargs) + + +@dataclass +class ClangTidyResult: + filename: str + invocation: List[str] + returncode: int + stdout: str + stderr: str + elapsed: float + + +async def run_tidy( + args: argparse.Namespace, + name: str, + clang_tidy_binary: str, + tmpdir: str, + build_path: str, +) -> ClangTidyResult: + """ + Runs clang-tidy on a single file and returns the result. + """ + invocation = get_tidy_invocation( + name, + clang_tidy_binary, + args.checks, + tmpdir, + build_path, + args.header_filter, + args.allow_enabling_alpha_checkers, + args.extra_arg, + args.extra_arg_before, + args.quiet, + args.config_file, + args.config, + args.line_filter, + args.use_color, + args.plugins, + args.warnings_as_errors, + args.exclude_header_filter, + args.allow_no_checks, + ) - proc = subprocess.Popen( - invocation, stdout=subprocess.PIPE, stderr=subprocess.PIPE + try: + process = await asyncio.create_subprocess_exec( + *invocation, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) - output, err = proc.communicate() - if proc.returncode != 0: - if proc.returncode < 0: - msg = "%s: terminated by signal %d\n" % (name, -proc.returncode) - err += msg.encode("utf-8") - failed_files.append(name) - with lock: - sys.stdout.write(" ".join(invocation) + "\n" + output.decode("utf-8")) - if len(err) > 0: - sys.stdout.flush() - sys.stderr.write(err.decode("utf-8")) - queue.task_done() - - -def main(): + start = time.time() + stdout, stderr = await process.communicate() + end = time.time() + except asyncio.CancelledError: + process.terminate() + await process.wait() + raise + + assert process.returncode is not None + return ClangTidyResult( + name, + invocation, + process.returncode, + stdout.decode("UTF-8"), + stderr.decode("UTF-8"), + end - start, + ) + + +async def main() -> None: parser = argparse.ArgumentParser( description="Runs clang-tidy over all files " "in a compilation database. Requires " @@ -432,7 +464,7 @@ def main(): ) combine_fixes = False - export_fixes_dir = None + export_fixes_dir: Optional[str] = None delete_fixes_dir = False if args.export_fixes is not None: # if a directory is given, create it if it does not exist @@ -490,10 +522,10 @@ def main(): sys.exit(1) # Load the database and extract all files. - database = json.load(open(os.path.join(build_path, db_path))) - files = set( - [make_absolute(entry["file"], entry["directory"]) for entry in database] - ) + with open(os.path.join(build_path, db_path)) as f: + database = json.load(f) + files = {os.path.abspath(os.path.join(e["directory"], e["file"])) for e in database} + number_files_in_database = len(files) # Filter source files from compilation database. if args.source_filter: @@ -514,70 +546,81 @@ def main(): # Build up a big regexy filter from all command line arguments. file_name_re = re.compile("|".join(args.files)) + files = {f for f in files if file_name_re.search(f)} + + print( + "Running clang-tidy for", + len(files), + "files out of", + number_files_in_database, + "in compilation database ...", + ) - return_code = 0 - try: - # Spin up a bunch of tidy-launching threads. - task_queue = queue.Queue(max_task) - # List of files with a non-zero return code. - failed_files = [] - lock = threading.Lock() - for _ in range(max_task): - t = threading.Thread( - target=run_tidy, - args=( - args, - clang_tidy_binary, - export_fixes_dir, - build_path, - task_queue, - lock, - failed_files, - ), + returncode = 0 + semaphore = asyncio.Semaphore(max_task) + tasks = [ + asyncio.create_task( + run_with_semaphore( + semaphore, + run_tidy, + args, + f, + clang_tidy_binary, + export_fixes_dir, + build_path, ) - t.daemon = True - t.start() - - # Fill the queue with files. - for name in files: - if file_name_re.search(name): - task_queue.put(name) - - # Wait for all threads to be done. - task_queue.join() - if len(failed_files): - return_code = 1 - - except KeyboardInterrupt: - # This is a sad hack. Unfortunately subprocess goes - # bonkers with ctrl-c and we start forking merrily. + ) + for f in files + ] + + try: + for i, coro in enumerate(asyncio.as_completed(tasks)): + result = await coro + if result.returncode != 0: + returncode = 1 + if result.returncode < 0: + result.stderr += f"{result.filename}: terminated by signal {-result.returncode}\n" + progress = f"[{i + 1: >{len(f'{len(files)}')}}/{len(files)}]" + runtime = f"[{result.elapsed:.1f}s]" + print(f"{progress}{runtime} {' '.join(result.invocation)}") + if result.stdout: + print(result.stdout, end=("" if result.stderr else "\n")) + if result.stderr: + print(result.stderr) + except asyncio.CancelledError: print("\nCtrl-C detected, goodbye.") + for task in tasks: + task.cancel() if delete_fixes_dir: + assert export_fixes_dir shutil.rmtree(export_fixes_dir) - os.kill(0, 9) + return if combine_fixes: - print("Writing fixes to " + args.export_fixes + " ...") + print(f"Writing fixes to {args.export_fixes} ...") try: + assert export_fixes_dir merge_replacement_files(export_fixes_dir, args.export_fixes) except: print("Error exporting fixes.\n", file=sys.stderr) traceback.print_exc() - return_code = 1 + returncode = 1 if args.fix: print("Applying fixes ...") try: + assert export_fixes_dir apply_fixes(args, clang_apply_replacements_binary, export_fixes_dir) except: print("Error applying fixes.\n", file=sys.stderr) traceback.print_exc() - return_code = 1 + returncode = 1 if delete_fixes_dir: + assert export_fixes_dir shutil.rmtree(export_fixes_dir) - sys.exit(return_code) + sys.exit(returncode) if __name__ == "__main__": - main() + asyncio.run(main()) diff --git a/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp b/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp index fd5dadc9b01db..0cdc7d08abc99 100644 --- a/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp +++ b/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp @@ -96,7 +96,7 @@ bool areStatementsIdentical(const Stmt *FirstStmt, const Stmt *SecondStmt, if (FirstStmt == SecondStmt) return true; - if (FirstStmt->getStmtClass() != FirstStmt->getStmtClass()) + if (FirstStmt->getStmtClass() != SecondStmt->getStmtClass()) return false; if (isa(FirstStmt) && isa(SecondStmt)) { diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp index 6ae46e2b1262a..9bfb7e2677533 100644 --- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp +++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp @@ -141,7 +141,10 @@ bool isStandardPointerConvertible(QualType From, QualType To) { if (RD->isCompleteDefinition() && isBaseOf(From->getPointeeType().getTypePtr(), To->getPointeeType().getTypePtr())) { - return true; + // If B is an inaccessible or ambiguous base class of D, a program + // that necessitates this conversion is ill-formed + return isUnambiguousPublicBaseClass(From->getPointeeType().getTypePtr(), + To->getPointeeType().getTypePtr()); } } @@ -375,10 +378,7 @@ bool ExceptionAnalyzer::ExceptionInfo::filterByCatch( isPointerOrPointerToMember(ExceptionCanTy->getTypePtr())) { // A standard pointer conversion not involving conversions to pointers to // private or protected or ambiguous classes ... - if (isStandardPointerConvertible(ExceptionCanTy, HandlerCanTy) && - isUnambiguousPublicBaseClass( - ExceptionCanTy->getTypePtr()->getPointeeType().getTypePtr(), - HandlerCanTy->getTypePtr()->getPointeeType().getTypePtr())) { + if (isStandardPointerConvertible(ExceptionCanTy, HandlerCanTy)) { TypesToDelete.push_back(ExceptionTy); } // A function pointer conversion ... diff --git a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp index e2daa5010e2ae..aba4d17ccd035 100644 --- a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp @@ -39,12 +39,6 @@ static constexpr const char ArgName[] = "ArgName"; namespace clang::tidy::utils { -static bool operator==(const UseRangesCheck::Indexes &L, - const UseRangesCheck::Indexes &R) { - return std::tie(L.BeginArg, L.EndArg, L.ReplaceArg) == - std::tie(R.BeginArg, R.EndArg, R.ReplaceArg); -} - static std::string getFullPrefix(ArrayRef Signature) { std::string Output; llvm::raw_string_ostream OS(Output); @@ -54,15 +48,6 @@ static std::string getFullPrefix(ArrayRef Signature) { return Output; } -static llvm::hash_code hash_value(const UseRangesCheck::Indexes &Indexes) { - return llvm::hash_combine(Indexes.BeginArg, Indexes.EndArg, - Indexes.ReplaceArg); -} - -static llvm::hash_code hash_value(const UseRangesCheck::Signature &Sig) { - return llvm::hash_combine_range(Sig.begin(), Sig.end()); -} - namespace { AST_MATCHER(Expr, hasSideEffects) { @@ -123,24 +108,26 @@ makeMatcherPair(StringRef State, const UseRangesCheck::Indexes &Indexes, } void UseRangesCheck::registerMatchers(MatchFinder *Finder) { - Replaces = getReplacerMap(); + auto Replaces = getReplacerMap(); ReverseDescriptor = getReverseDescriptor(); auto BeginEndNames = getFreeBeginEndMethods(); llvm::SmallVector BeginNames{ llvm::make_first_range(BeginEndNames)}; llvm::SmallVector EndNames{ llvm::make_second_range(BeginEndNames)}; - llvm::DenseSet> Seen; + Replacers.clear(); + llvm::DenseSet SeenRepl; for (auto I = Replaces.begin(), E = Replaces.end(); I != E; ++I) { - const ArrayRef &Signatures = - I->getValue()->getReplacementSignatures(); - if (!Seen.insert(Signatures).second) + auto Replacer = I->getValue(); + if (!SeenRepl.insert(Replacer.get()).second) continue; - assert(!Signatures.empty() && - llvm::all_of(Signatures, [](auto Index) { return !Index.empty(); })); + Replacers.push_back(Replacer); + assert(!Replacer->getReplacementSignatures().empty() && + llvm::all_of(Replacer->getReplacementSignatures(), + [](auto Index) { return !Index.empty(); })); std::vector Names(1, I->getKey()); for (auto J = std::next(I); J != E; ++J) - if (J->getValue()->getReplacementSignatures() == Signatures) + if (J->getValue() == Replacer) Names.push_back(J->getKey()); std::vector TotalMatchers; @@ -148,7 +135,7 @@ void UseRangesCheck::registerMatchers(MatchFinder *Finder) { // signatures in order of length(longest to shortest). This way any // signature that is a subset of another signature will be matched after the // other. - SmallVector SigVec(Signatures); + SmallVector SigVec(Replacer->getReplacementSignatures()); llvm::sort(SigVec, [](auto &L, auto &R) { return R.size() < L.size(); }); for (const auto &Signature : SigVec) { std::vector Matchers; @@ -163,7 +150,8 @@ void UseRangesCheck::registerMatchers(MatchFinder *Finder) { } Finder->addMatcher( callExpr( - callee(functionDecl(hasAnyName(std::move(Names))).bind(FuncDecl)), + callee(functionDecl(hasAnyName(std::move(Names))) + .bind((FuncDecl + Twine(Replacers.size() - 1).str()))), ast_matchers::internal::DynTypedMatcher::constructVariadic( ast_matchers::internal::DynTypedMatcher::VO_AnyOf, ASTNodeKind::getFromNodeKind(), @@ -205,21 +193,33 @@ static void removeFunctionArgs(DiagnosticBuilder &Diag, const CallExpr &Call, } void UseRangesCheck::check(const MatchFinder::MatchResult &Result) { - const auto *Function = Result.Nodes.getNodeAs(FuncDecl); - std::string Qualified = "::" + Function->getQualifiedNameAsString(); - auto Iter = Replaces.find(Qualified); - assert(Iter != Replaces.end()); + Replacer *Replacer = nullptr; + const FunctionDecl *Function = nullptr; + for (auto [Node, Value] : Result.Nodes.getMap()) { + StringRef NodeStr(Node); + if (!NodeStr.consume_front(FuncDecl)) + continue; + Function = Value.get(); + size_t Index; + if (NodeStr.getAsInteger(10, Index)) { + llvm_unreachable("Unable to extract replacer index"); + } + assert(Index < Replacers.size()); + Replacer = Replacers[Index].get(); + break; + } + assert(Replacer && Function); SmallString<64> Buffer; - for (const Signature &Sig : Iter->getValue()->getReplacementSignatures()) { + for (const Signature &Sig : Replacer->getReplacementSignatures()) { Buffer.assign({BoundCall, getFullPrefix(Sig)}); const auto *Call = Result.Nodes.getNodeAs(Buffer); if (!Call) continue; auto Diag = createDiag(*Call); - if (auto ReplaceName = Iter->getValue()->getReplaceName(*Function)) + if (auto ReplaceName = Replacer->getReplaceName(*Function)) Diag << FixItHint::CreateReplacement(Call->getCallee()->getSourceRange(), *ReplaceName); - if (auto Include = Iter->getValue()->getHeaderInclusion(*Function)) + if (auto Include = Replacer->getHeaderInclusion(*Function)) Diag << Inserter.createIncludeInsertion( Result.SourceManager->getFileID(Call->getBeginLoc()), *Include); llvm::SmallVector ToRemove; diff --git a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.h b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.h index 927e9694b0ec7..3a454bcf0cf07 100644 --- a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.h +++ b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.h @@ -85,7 +85,7 @@ class UseRangesCheck : public ClangTidyCheck { std::optional getCheckTraversalKind() const override; private: - ReplacerMap Replaces; + std::vector> Replacers; std::optional ReverseDescriptor; IncludeInserter Inserter; }; diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp index dc5b7ec95db5f..e34706172f0bf 100644 --- a/clang-tools-extra/clangd/IncludeCleaner.cpp +++ b/clang-tools-extra/clangd/IncludeCleaner.cpp @@ -401,6 +401,26 @@ computeIncludeCleanerFindings(ParsedAST &AST, bool AnalyzeAngledIncludes) { Ref.RT != include_cleaner::RefType::Explicit) return; + // Check if we have any headers with the same spelling, in edge cases + // like `#include_next "foo.h"`, the user can't ever include the + // physical foo.h, but can have a spelling that refers to it. + // We postpone this check because spelling a header for every usage is + // expensive. + std::string Spelling = include_cleaner::spellHeader( + {Providers.front(), AST.getPreprocessor().getHeaderSearchInfo(), + MainFile}); + for (auto *Inc : + ConvertedIncludes.match(include_cleaner::Header{Spelling})) { + Satisfied = true; + auto HeaderID = + AST.getIncludeStructure().getID(&Inc->Resolved->getFileEntry()); + assert(HeaderID.has_value() && + "ConvertedIncludes only contains resolved includes."); + Used.insert(*HeaderID); + } + if (Satisfied) + return; + // We actually always want to map usages to their spellings, but // spelling locations can point into preamble section. Using these // offsets could lead into crashes in presence of stale preambles. Hence diff --git a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp index 7027232460354..0ee748c1ed2d0 100644 --- a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp +++ b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp @@ -644,6 +644,28 @@ TEST(IncludeCleaner, ResourceDirIsIgnored) { EXPECT_THAT(Findings.MissingIncludes, IsEmpty()); } +TEST(IncludeCleaner, DifferentHeaderSameSpelling) { + // `foo` is declared in foo_inner/foo.h, but there's no way to spell it + // directly. Make sure we don't generate unusued/missing include findings in + // such cases. + auto TU = TestTU::withCode(R"cpp( + #include + void baz() { + foo(); + } + )cpp"); + TU.AdditionalFiles["foo/foo.h"] = guard("#include_next "); + TU.AdditionalFiles["foo_inner/foo.h"] = guard(R"cpp( + void foo(); + )cpp"); + TU.ExtraArgs.push_back("-Ifoo"); + TU.ExtraArgs.push_back("-Ifoo_inner"); + + auto AST = TU.build(); + auto Findings = computeIncludeCleanerFindings(AST); + EXPECT_THAT(Findings.UnusedIncludes, IsEmpty()); + EXPECT_THAT(Findings.MissingIncludes, IsEmpty()); +} } // namespace } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 697b514ae1572..642ad39cc0c1c 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -48,10 +48,6 @@ Major New Features Improvements to clangd ---------------------- -- Introduced exmperimental support for C++20 Modules. The experimental support can - be enabled by `-experimental-modules-support` option. It is in an early development - stage and may not perform efficiently in real-world scenarios. - Inlay hints ^^^^^^^^^^^ @@ -73,9 +69,6 @@ Code completion Code actions ^^^^^^^^^^^^ -- The tweak for turning unscoped into scoped enums now removes redundant prefixes - from the enum values. - Signature help ^^^^^^^^^^^^^^ @@ -88,23 +81,12 @@ Objective-C Miscellaneous ^^^^^^^^^^^^^ -- Added a boolean option `AnalyzeAngledIncludes` to `Includes` config section, - which allows to enable unused includes detection for all angled ("system") headers. - At this moment umbrella headers are not supported, so enabling this option - may result in false-positives. - Improvements to clang-doc ------------------------- Improvements to clang-query --------------------------- -- Added the `file` command to dynamically load a list of commands and matchers - from an external file, allowing the cost of reading the compilation database - and building the AST to be imposed just once for faster prototyping. - -- Removed support for ``enable output srcloc``. Fixes #GH82591 - Improvements to clang-rename ---------------------------- @@ -113,423 +95,21 @@ The improvements are... Improvements to clang-tidy -------------------------- -- Improved :program:`run-clang-tidy.py` script. Added argument `-source-filter` - to filter source files from the compilation database, via a RegEx. In a - similar fashion to what `-header-filter` does for header files. - -- Improved :program:`check_clang_tidy.py` script. Added argument `-export-fixes` - to aid in clang-tidy and test development. - -- Fixed bug where big values for unsigned check options overflowed into negative values - when being printed with `--dump-config`. - -- Fixed `--verify-config` option not properly parsing checks when using the - literal operator in the `.clang-tidy` config. - -- Added argument `--exclude-header-filter` and config option `ExcludeHeaderFilterRegex` - to exclude headers from analysis via a RegEx. - -- Added argument `--allow-no-checks` to suppress "no checks enabled" error - when disabling all of the checks by `--checks='-*'`. - New checks ^^^^^^^^^^ -- New :doc:`boost-use-ranges - ` check. - - Detects calls to standard library iterator algorithms that could be replaced - with a Boost ranges version instead. - -- New :doc:`bugprone-crtp-constructor-accessibility - ` check. - - Detects error-prone Curiously Recurring Template Pattern usage, when the CRTP - can be constructed outside itself and the derived class. - -- New :doc:`bugprone-pointer-arithmetic-on-polymorphic-object - ` check. - - Finds pointer arithmetic performed on classes that contain a virtual function. - -- New :doc:`bugprone-return-const-ref-from-parameter - ` check. - - Detects return statements that return a constant reference parameter as constant - reference. This may cause use-after-free errors if the caller uses xvalues as - arguments. - -- New :doc:`bugprone-suspicious-stringview-data-usage - ` check. - - Identifies suspicious usages of ``std::string_view::data()`` that could lead - to reading out-of-bounds data due to inadequate or incorrect string null - termination. - -- New :doc:`misc-use-internal-linkage - ` check. - - Detects variables and functions that can be marked as static or moved into - an anonymous namespace to enforce internal linkage. - -- New :doc:`modernize-min-max-use-initializer-list - ` check. - - Replaces nested ``std::min`` and ``std::max`` calls with an initializer list - where applicable. - -- New :doc:`modernize-use-designated-initializers - ` check. - - Finds initializer lists for aggregate types that could be - written as designated initializers instead. - -- New :doc:`modernize-use-ranges - ` check. - - Detects calls to standard library iterator algorithms that could be replaced - with a ranges version instead. - -- New :doc:`modernize-use-std-format - ` check. - - Converts calls to ``absl::StrFormat``, or other functions via - configuration options, to C++20's ``std::format``, or another function - via a configuration option, modifying the format string appropriately and - removing now-unnecessary calls to ``std::string::c_str()`` and - ``std::string::data()``. - -- New :doc:`readability-enum-initial-value - ` check. - - Enforces consistent style for enumerators' initialization, covering three - styles: none, first only, or all initialized explicitly. - -- New :doc:`readability-math-missing-parentheses - ` check. - - Check for missing parentheses in mathematical expressions that involve - operators of different priorities. - -- New :doc:`readability-use-std-min-max - ` check. - - Replaces certain conditional statements with equivalent calls to - ``std::min`` or ``std::max``. - New check aliases ^^^^^^^^^^^^^^^^^ -- New alias :doc:`cert-ctr56-cpp ` to - :doc:`bugprone-pointer-arithmetic-on-polymorphic-object - ` - was added. - -- New alias :doc:`cert-int09-c ` to - :doc:`readability-enum-initial-value ` - was added. - Changes in existing checks ^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Improved :doc:`bugprone-assert-side-effect - ` check by detecting side - effect from calling a method with non-const reference parameters. - -- Improved :doc:`bugprone-assignment-in-if-condition - ` check by ignoring - assignments in the C++20 ``requires`` clause. - -- Improved :doc:`bugprone-casting-through-void - ` check by ignoring casts - where source is already a ``void``` pointer, making middle ``void`` pointer - casts bug-free. - -- Improved :doc:`bugprone-forwarding-reference-overload - ` - check to ignore deleted constructors which won't hide other overloads. - -- Improved :doc:`bugprone-implicit-widening-of-multiplication-result - ` check - by adding an option to ignore constant expressions of signed integer types - that fit in the source expression type. - -- Improved :doc:`bugprone-inc-dec-in-conditions - ` check to ignore code - within unevaluated contexts, such as ``decltype``. - -- Improved :doc:`bugprone-lambda-function-name` - check by ignoring ``__func__`` macro in lambda captures, initializers of - default parameters and nested function declarations. - -- Improved :doc:`bugprone-multi-level-implicit-pointer-conversion - ` check - by ignoring implicit pointer conversions that are part of a cast expression. - -- Improved :doc:`bugprone-non-zero-enum-to-bool-conversion - ` check by - eliminating false positives resulting from direct usage of bitwise operators - within parentheses. - -- Improved :doc:`bugprone-optional-value-conversion - ` check by eliminating - false positives resulting from use of optionals in unevaluated context. - -- Improved :doc:`bugprone-sizeof-expression - ` check by clarifying the - diagnostics, eliminating some false positives and adding a new - (off-by-default) option `WarnOnSizeOfPointer` that reports all - ``sizeof(pointer)`` expressions (except for a few that are idiomatic). - -- Improved :doc:`bugprone-suspicious-include - ` check by replacing the local - options `HeaderFileExtensions` and `ImplementationFileExtensions` by the - global options of the same name. - -- Improved :doc:`bugprone-too-small-loop-variable - ` check by incorporating - better support for ``const`` loop boundaries. - -- Improved :doc:`bugprone-unused-local-non-trivial-variable - ` check by - ignoring local variable with ``[maybe_unused]`` attribute. - -- Improved :doc:`bugprone-unused-return-value - ` check by updating the - parameter `CheckedFunctions` to support regexp, avoiding false positive for - function with the same prefix as the default argument, e.g. ``std::unique_ptr`` - and ``std::unique``, avoiding false positive for assignment operator overloading. - -- Improved :doc:`bugprone-use-after-move - ` check to also handle - calls to ``std::forward``. Fixed sequencing of designated initializers. Fixed - sequencing of callees: In C++17 and later, the callee of a function is guaranteed - to be sequenced before the arguments, so don't warn if the use happens in the - callee and the move happens in one of the arguments. - -- Improved :doc:`cppcoreguidelines-avoid-non-const-global-variables - ` check - with a new option `AllowInternalLinkage` to disable the warning for variables - with internal linkage. - -- Improved :doc:`cppcoreguidelines-macro-usage - ` check by ignoring macro with - hash preprocessing token. - -- Improved :doc:`cppcoreguidelines-missing-std-forward - ` check by no longer - giving false positives for deleted functions, by fixing false negatives when only - a few parameters are forwarded and by ignoring parameters without a name (unused - arguments). - -- Improved :doc:`cppcoreguidelines-owning-memory - ` check to properly handle - return type in lambdas and in nested functions. - -- Improved :doc:`cppcoreguidelines-prefer-member-initializer - ` check - by removing enforcement of rule `C.48 - `_, - which was deprecated since :program:`clang-tidy` 17. This rule is now covered - by :doc:`cppcoreguidelines-use-default-member-init - `. Fixed - incorrect hints when using list-initialization. - -- Improved :doc:`cppcoreguidelines-special-member-functions - ` check with a - new option `AllowImplicitlyDeletedCopyOrMove`, which removes the requirement - for explicit copy or move special member functions when they are already - implicitly deleted. - -- Improved :doc:`google-build-namespaces - ` check by replacing the local - option `HeaderFileExtensions` by the global option of the same name. - -- Improved :doc:`google-explicit-constructor - ` check to better handle - C++20 `explicit(bool)`. - -- Improved :doc:`google-global-names-in-headers - ` check by replacing the local - option `HeaderFileExtensions` by the global option of the same name. - -- Improved :doc:`google-runtime-int ` - check performance through optimizations. - -- Improved :doc:`hicpp-signed-bitwise ` - check by ignoring false positives involving positive integer literals behind - implicit casts when `IgnorePositiveIntegerLiterals` is enabled. - -- Improved :doc:`hicpp-ignored-remove-result ` - check by ignoring other functions with same prefixes as the target specific - functions. - -- Improved :doc:`linuxkernel-must-check-errs - ` check documentation to - consistently use the check's proper name. - -- Improved :doc:`llvm-header-guard - ` check by replacing the local - option `HeaderFileExtensions` by the global option of the same name. - -- Improved :doc:`misc-const-correctness - ` check by avoiding infinite recursion - for recursive functions with forwarding reference parameters and reference - variables which refer to themselves. - -- Improved :doc:`misc-definitions-in-headers - ` check by replacing the local - option `HeaderFileExtensions` by the global option of the same name. - Additionally, the option `UseHeaderFileExtensions` is removed, so that the - check uses the `HeaderFileExtensions` option unconditionally. - -- Improved :doc:`misc-header-include-cycle - ` check by avoiding crash for self - include cycles. - -- Improved :doc:`misc-unused-using-decls - ` check by replacing the local - option `HeaderFileExtensions` by the global option of the same name. - -- Improved :doc:`misc-use-anonymous-namespace - ` check by replacing the local - option `HeaderFileExtensions` by the global option of the same name. - -- Improved :doc:`modernize-avoid-c-arrays - ` check by introducing the new - `AllowStringArrays` option, enabling the exclusion of array types with deduced - length initialized from string literals. - -- Improved :doc:`modernize-loop-convert - ` check by ensuring that fix-its - don't remove parentheses used in ``sizeof`` calls when they have array index - accesses as arguments. - -- Improved :doc:`modernize-use-constraints - ` check by fixing a crash that - occurred in some scenarios and excluding system headers from analysis. - -- Improved :doc:`modernize-use-nullptr - ` check to include support for C23, - which also has introduced the ``nullptr`` keyword. - -- Improved :doc:`modernize-use-override - ` check to also remove any trailing - whitespace when deleting the ``virtual`` keyword. - -- Improved :doc:`modernize-use-starts-ends-with - ` check to also handle - calls to ``compare`` method. - -- Improved :doc:`modernize-use-std-print - ` check to not crash if the - format string parameter of the function to be replaced is not of the - expected type. - -- Improved :doc:`modernize-use-using ` - check by adding support for detection of typedefs declared on function level. - -- Improved :doc:`performance-inefficient-vector-operation - ` fixing false - negatives caused by different variable definition type and variable initial - value type in loop initialization expression. - -- Improved :doc:`performance-move-const-arg - ` check by ignoring - ``std::move()`` calls when their target is used as an rvalue. - -- Improved :doc:`performance-unnecessary-copy-initialization - ` check by - detecting more cases of constant access. In particular, pointers can be - analyzed, so the check now handles the common patterns - `const auto e = (*vector_ptr)[i]` and `const auto e = vector_ptr->at(i);`. - Calls to mutable function where there exists a `const` overload are also - handled. Fix crash in the case of a non-member operator call. - -- Improved :doc:`performance-unnecessary-value-param - ` check - detecting more cases for template functions including lambdas with ``auto``. - E.g., ``std::sort(a.begin(), a.end(), [](auto x, auto y) { return a > b; });`` - will be detected for expensive to copy types. - -- Improved :doc:`readability-avoid-return-with-void-value - ` check by adding - fix-its. - -- Improved :doc:`readability-const-return-type - ` check to eliminate false - positives when returning types with const not at the top level. - -- Improved :doc:`readability-container-size-empty - ` check to prevent false - positives when utilizing ``size`` or ``length`` methods that accept parameter. - Fixed crash when facing template user defined literals. - -- Improved :doc:`readability-duplicate-include - ` check by excluding include - directives that form the filename using macro. - -- Improved :doc:`readability-else-after-return - ` check to ignore - `if consteval` statements, for which the `else` branch must not be removed. - -- Improved :doc:`readability-identifier-naming - ` check in `GetConfigPerFile` - mode by resolving symbolic links to header files. Fixed handling of Hungarian - Prefix when configured to `LowerCase`. Added support for renaming designated - initializers. Added support for renaming macro arguments. Fixed renaming - conflicts arising from out-of-line member function template definitions. - -- Improved :doc:`readability-implicit-bool-conversion - ` check to provide - valid fix suggestions for ``static_cast`` without a preceding space and - fixed problem with duplicate parentheses in double implicit casts. Corrected - the fix suggestions for C23 and later by using C-style casts instead of - ``static_cast``. Fixed false positives in C++20 spaceship operator by ignoring - casts in implicit and defaulted functions. - -- Improved :doc:`readability-redundant-inline-specifier - ` check to properly - emit warnings for static data member with an in-class initializer. - -- Improved :doc:`readability-redundant-member-init - ` check to avoid - false-positives when type of the member does not match the type of the - initializer. - -- Improved :doc:`readability-static-accessed-through-instance - ` check to - support calls to overloaded operators as base expression and provide fixes to - expressions with side-effects. - -- Improved :doc:`readability-simplify-boolean-expr - ` check to avoid to emit - warning for macro when IgnoreMacro option is enabled and improve messages - when auto-fix does not work. - -- Improved :doc:`readability-static-definition-in-anonymous-namespace - ` - check by resolving fix-it overlaps in template code by disregarding implicit - instances. - -- Improved :doc:`readability-string-compare - ` check to also detect - usages of ``std::string_view::compare``. Added a `StringLikeClasses` option - to detect usages of ``compare`` method in custom string-like classes. - Removed checks ^^^^^^^^^^^^^^ -- Removed `cert-dcl21-cpp`, which was deprecated since :program:`clang-tidy` 17, - since the rule DCL21-CPP has been removed from the CERT guidelines. - Miscellaneous ^^^^^^^^^^^^^ -- Fixed incorrect formatting in :program:`clang-apply-replacements` when no - `--format` option is specified. Now :program:`clang-apply-replacements` - applies formatting only with the option. - Improvements to include-fixer ----------------------------- diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-return-value.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-return-value.rst index 9205ba98729c4..10ae0fe3243a0 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-return-value.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-return-value.rst @@ -16,23 +16,26 @@ Options This parameter supports regexp. The function is checked if the name and scope matches, with any arguments. By default the following functions are checked: - ``::std::async$, ::std::launder$, ::std::remove$, ::std::remove_if$, ::std::unique$, - ::std::unique_ptr::release$, ::std::basic_string::empty$, ::std::vector::empty$, - ::std::back_inserter$, ::std::distance$, ::std::find$, ::std::find_if$, ::std::inserter$, - ::std::lower_bound$, ::std::make_pair$, ::std::map::count$, ::std::map::find$, - ::std::map::lower_bound$, ::std::multimap::equal_range$, ::std::multimap::upper_bound$, - ::std::set::count$, ::std::set::find$, ::std::setfill$, ::std::setprecision$, - ::std::setw$, ::std::upper_bound$, ::std::vector::at$, ::bsearch$, ::ferror$, - ::feof$, ::isalnum$, ::isalpha$, ::isblank$, ::iscntrl$, ::isdigit$, ::isgraph$, - ::islower$, ::isprint$, ::ispunct$, ::isspace$, ::isupper$, ::iswalnum$, ::iswprint$, - ::iswspace$, ::isxdigit$, ::memchr$, ::memcmp$, ::strcmp$, ::strcoll$, ::strncmp$, - ::strpbrk$, ::strrchr$, ::strspn$, ::strstr$, ::wcscmp$, ::access$, ::bind$, - ::connect$, ::difftime$, ::dlsym$, ::fnmatch$, ::getaddrinfo$, ::getopt$, - ::htonl$, ::htons$, ::iconv_open$, ::inet_addr$, isascii$, isatty$, ::mmap$, - ::newlocale$, ::openat$, ::pathconf$, ::pthread_equal$, ::pthread_getspecific$, - ::pthread_mutex_trylock$, ::readdir$, ::readlink$, ::recvmsg$, ::regexec$, ::scandir$, - ::semget$, ::setjmp$, ::shm_open$, ::shmget$, ::sigismember$, ::strcasecmp$, ::strsignal$, - ::ttyname$`` + ``^::std::async$, ^::std::launder$, ^::std::remove$, ^::std::remove_if$, + ^::std::unique$, ^::std::unique_ptr::release$, ^::std::basic_string::empty$, + ^::std::vector::empty$, ^::std::back_inserter$, ^::std::distance$, + ^::std::find$, ^::std::find_if$, ^::std::inserter$, ^::std::lower_bound$, + ^::std::make_pair$, ^::std::map::count$, ^::std::map::find$, + ^::std::map::lower_bound$, ^::std::multimap::equal_range$, + ^::std::multimap::upper_bound$, ^::std::set::count$, ^::std::set::find$, + ^::std::setfill$, ^::std::setprecision$, ^::std::setw$, ^::std::upper_bound$, + ^::std::vector::at$, ^::bsearch$, ^::ferror$, ^::feof$, ^::isalnum$, + ^::isalpha$, ^::isblank$, ^::iscntrl$, ^::isdigit$, ^::isgraph$, ^::islower$, + ^::isprint$, ^::ispunct$, ^::isspace$, ^::isupper$, ^::iswalnum$, + ^::iswprint$, ^::iswspace$, ^::isxdigit$, ^::memchr$, ^::memcmp$, ^::strcmp$, + ^::strcoll$, ^::strncmp$, ^::strpbrk$, ^::strrchr$, ^::strspn$, ^::strstr$, + ^::wcscmp$, ^::access$, ^::bind$, ^::connect$, ^::difftime$, ^::dlsym$, + ^::fnmatch$, ^::getaddrinfo$, ^::getopt$, ^::htonl$, ^::htons$, + ^::iconv_open$, ^::inet_addr$, isascii$, isatty$, ^::mmap$, ^::newlocale$, + ^::openat$, ^::pathconf$, ^::pthread_equal$, ^::pthread_getspecific$, + ^::pthread_mutex_trylock$, ^::readdir$, ^::readlink$, ^::recvmsg$, + ^::regexec$, ^::scandir$, ^::semget$, ^::setjmp$, ^::shm_open$, ^::shmget$, + ^::sigismember$, ^::strcasecmp$, ^::strsignal$, ^::ttyname$`` - ``std::async()``. Not using the return value makes the call synchronous. - ``std::launder()``. Not using the return value usually means that the @@ -54,7 +57,8 @@ Options Semicolon-separated list of function return types to check. By default the following function return types are checked: - `::std::error_code`, `::std::error_condition`, `::std::errc`, `::std::expected`, `::boost::system::error_code` + `^::std::error_code$`, `^::std::error_condition$`, `^::std::errc$`, + `^::std::expected$`, `^::boost::system::error_code$` .. option:: AllowCastToVoid diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.Move.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.Move.rst index e723f21f6bc60..f478598bb4e6c 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.Move.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.Move.rst @@ -1,9 +1,13 @@ .. title:: clang-tidy - clang-analyzer-cplusplus.Move +.. meta:: + :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-move clang-analyzer-cplusplus.Move ============================= Find use-after-move bugs in C++. -The clang-analyzer-cplusplus.Move check is an alias of -Clang Static Analyzer cplusplus.Move. +The `clang-analyzer-cplusplus.Move` 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.taint.TaintedAlloc.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.taint.TaintedAlloc.rst new file mode 100644 index 0000000000000..9732333c61aa7 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.taint.TaintedAlloc.rst @@ -0,0 +1,14 @@ +.. title:: clang-tidy - clang-analyzer-optin.taint.TaintedAlloc +.. meta:: + :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#optin-taint-taintedalloc + +clang-analyzer-optin.taint.TaintedAlloc +======================================= + +Check for memory allocations, where the size parameter might be a tainted +(attacker controlled) value. + +The `clang-analyzer-optin.taint.TaintedAlloc` 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.PutenvStackArray.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.PutenvStackArray.rst new file mode 100644 index 0000000000000..0a5feff8d3ca8 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.PutenvStackArray.rst @@ -0,0 +1,10 @@ +.. title:: clang-tidy - clang-analyzer-security.PutenvStackArray + +clang-analyzer-security.PutenvStackArray +======================================== + +Finds calls to the function 'putenv' which pass a pointer to an automatic +(stack-allocated) array as the argument. + +The clang-analyzer-security.PutenvStackArray check is an alias of +Clang Static Analyzer security.PutenvStackArray. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/unix.BlockInCriticalSection.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/unix.BlockInCriticalSection.rst new file mode 100644 index 0000000000000..40d2d3d8b8aac --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/unix.BlockInCriticalSection.rst @@ -0,0 +1,13 @@ +.. title:: clang-tidy - clang-analyzer-unix.BlockInCriticalSection +.. meta:: + :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#unix-blockincriticalsection + +clang-analyzer-unix.BlockInCriticalSection +========================================== + +Check for calls to blocking functions inside a critical section. + +The `clang-analyzer-unix.BlockInCriticalSection` check is an alias, please see +`Clang Static Analyzer Available Checkers +`_ +for more information. diff --git a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-const-or-ref-data-members.rst b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-const-or-ref-data-members.rst index 5783280478dc1..57c4829431e76 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-const-or-ref-data-members.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-const-or-ref-data-members.rst @@ -35,7 +35,7 @@ Examples: int* x; std::unique_ptr x; std::shared_ptr x; - gsl::not_null x; + gsl::not_null x; }; // Bad, rvalue reference member diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index dd2887edb0f8d..a931ebf025a10 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -118,6 +118,7 @@ Clang-Tidy Checks :doc:`bugprone-not-null-terminated-result `, "Yes" :doc:`bugprone-optional-value-conversion `, "Yes" :doc:`bugprone-parent-virtual-call `, "Yes" + :doc:`bugprone-pointer-arithmetic-on-polymorphic-object `, :doc:`bugprone-posix-return `, "Yes" :doc:`bugprone-redundant-branch-condition `, "Yes" :doc:`bugprone-reserved-identifier `, "Yes" @@ -158,7 +159,6 @@ Clang-Tidy Checks :doc:`bugprone-unused-raii `, "Yes" :doc:`bugprone-unused-return-value `, :doc:`bugprone-use-after-move `, - :doc:`bugprone-pointer-arithmetic-on-polymorphic-object `, :doc:`bugprone-virtual-near-miss `, "Yes" :doc:`cert-dcl50-cpp `, :doc:`cert-dcl58-cpp `, @@ -269,7 +269,7 @@ Clang-Tidy Checks :doc:`misc-unused-parameters `, "Yes" :doc:`misc-unused-using-decls `, "Yes" :doc:`misc-use-anonymous-namespace `, - :doc:`misc-use-internal-linkage `, + :doc:`misc-use-internal-linkage `, "Yes" :doc:`modernize-avoid-bind `, "Yes" :doc:`modernize-avoid-c-arrays `, :doc:`modernize-concat-nested-namespaces `, "Yes" @@ -409,6 +409,7 @@ Check aliases :doc:`bugprone-narrowing-conversions `, :doc:`cppcoreguidelines-narrowing-conversions `, :doc:`cert-con36-c `, :doc:`bugprone-spuriously-wake-up-functions `, :doc:`cert-con54-cpp `, :doc:`bugprone-spuriously-wake-up-functions `, + :doc:`cert-ctr56-cpp `, :doc:`bugprone-pointer-arithmetic-on-polymorphic-object `, :doc:`cert-dcl03-c `, :doc:`misc-static-assert `, "Yes" :doc:`cert-dcl16-c `, :doc:`readability-uppercase-literal-suffix `, "Yes" :doc:`cert-dcl37-c `, :doc:`bugprone-reserved-identifier `, "Yes" @@ -448,7 +449,7 @@ Check aliases :doc:`clang-analyzer-core.uninitialized.UndefReturn `, `Clang Static Analyzer core.uninitialized.UndefReturn `_, :doc:`clang-analyzer-cplusplus.ArrayDelete `, `Clang Static Analyzer cplusplus.ArrayDelete `_, :doc:`clang-analyzer-cplusplus.InnerPointer `, `Clang Static Analyzer cplusplus.InnerPointer `_, - :doc:`clang-analyzer-cplusplus.Move `, Clang Static Analyzer cplusplus.Move, + :doc:`clang-analyzer-cplusplus.Move `, `Clang Static Analyzer cplusplus.Move `_, :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 `_, @@ -471,6 +472,7 @@ Check aliases :doc:`clang-analyzer-optin.performance.GCDAntipattern `, `Clang Static Analyzer optin.performance.GCDAntipattern `_, :doc:`clang-analyzer-optin.performance.Padding `, `Clang Static Analyzer optin.performance.Padding `_, :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 `_, @@ -501,6 +503,7 @@ Check aliases :doc:`clang-analyzer-osx.coreFoundation.containers.OutOfBounds `, `Clang Static Analyzer osx.coreFoundation.containers.OutOfBounds `_, :doc:`clang-analyzer-osx.coreFoundation.containers.PointerSizedValues `, `Clang Static Analyzer osx.coreFoundation.containers.PointerSizedValues `_, :doc:`clang-analyzer-security.FloatLoopCounter `, `Clang Static Analyzer security.FloatLoopCounter `_, + :doc:`clang-analyzer-security.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 `_, @@ -517,6 +520,7 @@ Check aliases :doc:`clang-analyzer-security.insecureAPI.strcpy `, `Clang Static Analyzer security.insecureAPI.strcpy `_, :doc:`clang-analyzer-security.insecureAPI.vfork `, `Clang Static Analyzer security.insecureAPI.vfork `_, :doc:`clang-analyzer-unix.API `, `Clang Static Analyzer unix.API `_, + :doc:`clang-analyzer-unix.BlockInCriticalSection `, `Clang Static Analyzer unix.BlockInCriticalSection `_, :doc:`clang-analyzer-unix.Errno `, `Clang Static Analyzer unix.Errno `_, :doc:`clang-analyzer-unix.Malloc `, `Clang Static Analyzer unix.Malloc `_, :doc:`clang-analyzer-unix.MallocSizeof `, `Clang Static Analyzer unix.MallocSizeof `_, diff --git a/clang-tools-extra/include-cleaner/lib/Analysis.cpp b/clang-tools-extra/include-cleaner/lib/Analysis.cpp index f1cd72f877ca2..68fe79d6929f6 100644 --- a/clang-tools-extra/include-cleaner/lib/Analysis.cpp +++ b/clang-tools-extra/include-cleaner/lib/Analysis.cpp @@ -105,9 +105,20 @@ analyze(llvm::ArrayRef ASTRoots, } if (!Satisfied && !Providers.empty() && Ref.RT == RefType::Explicit && - !HeaderFilter(Providers.front().resolvedPath())) - Missing.insert(spellHeader( - {Providers.front(), PP.getHeaderSearchInfo(), MainFile})); + !HeaderFilter(Providers.front().resolvedPath())) { + // Check if we have any headers with the same spelling, in edge + // cases like `#include_next "foo.h"`, the user can't ever + // include the physical foo.h, but can have a spelling that + // refers to it. + auto Spelling = spellHeader( + {Providers.front(), PP.getHeaderSearchInfo(), MainFile}); + for (const Include *I : Inc.match(Header{Spelling})) { + Used.insert(I); + Satisfied = true; + } + if (!Satisfied) + Missing.insert(std::move(Spelling)); + } }); AnalysisResults Results; diff --git a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp index 6558b68087684..5696c380758f8 100644 --- a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp @@ -12,6 +12,7 @@ #include "clang-include-cleaner/Record.h" #include "clang-include-cleaner/Types.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/DeclBase.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceLocation.h" @@ -296,6 +297,31 @@ TEST_F(AnalyzeTest, ResourceDirIsIgnored) { EXPECT_THAT(Results.Missing, testing::IsEmpty()); } +TEST_F(AnalyzeTest, DifferentHeaderSameSpelling) { + Inputs.ExtraArgs.push_back("-Ifoo"); + Inputs.ExtraArgs.push_back("-Ifoo_inner"); + // `foo` is declared in foo_inner/foo.h, but there's no way to spell it + // directly. Make sure we don't generate unusued/missing include findings in + // such cases. + Inputs.Code = R"cpp( + #include + void baz() { + foo(); + } + )cpp"; + Inputs.ExtraFiles["foo/foo.h"] = guard("#include_next "); + Inputs.ExtraFiles["foo_inner/foo.h"] = guard(R"cpp( + void foo(); + )cpp"); + TestAST AST(Inputs); + std::vector DeclsInTU; + for (auto *D : AST.context().getTranslationUnitDecl()->decls()) + DeclsInTU.push_back(D); + auto Results = analyze(DeclsInTU, {}, PP.Includes, &PI, AST.preprocessor()); + EXPECT_THAT(Results.Unused, testing::IsEmpty()); + EXPECT_THAT(Results.Missing, testing::IsEmpty()); +} + TEST(FixIncludes, Basic) { llvm::StringRef Code = R"cpp(#include "d.h" #include "a.h" diff --git a/clang-tools-extra/test/clang-doc/basic-project.test b/clang-tools-extra/test/clang-doc/basic-project.test index 51d3ac6ce6dcd..38569d824f1f0 100644 --- a/clang-tools-extra/test/clang-doc/basic-project.test +++ b/clang-tools-extra/test/clang-doc/basic-project.test @@ -1,3 +1,6 @@ +// See https://github.com/llvm/llvm-project/issues/97507. +// UNSUPPORTED: target={{.*}} + // RUN: rm -rf %t && mkdir -p %t/docs %t/build // RUN: sed 's|$test_dir|%/S|g' %S/Inputs/basic-project/database_template.json > %t/build/compile_commands.json // RUN: clang-doc --format=html --output=%t/docs --executor=all-TUs %t/build/compile_commands.json diff --git a/clang-tools-extra/test/clang-doc/test-path-abs.cpp b/clang-tools-extra/test/clang-doc/test-path-abs.cpp new file mode 100644 index 0000000000000..f6cce95bbea0c --- /dev/null +++ b/clang-tools-extra/test/clang-doc/test-path-abs.cpp @@ -0,0 +1,6 @@ +// RUN: rm -rf %t && mkdir %t +// RUN: clang-doc --format=html --executor=standalone %s --output=%t +// RUN: FileCheck %s -input-file=%t/index_json.js -check-prefix=JSON-INDEX +// RUN: rm -rf %t + +// JSON-INDEX: var RootPath = "{{.*}}test-path-abs.cpp.tmp"; \ No newline at end of file diff --git a/clang-tools-extra/test/clang-tidy/check_clang_tidy.py b/clang-tools-extra/test/clang-tidy/check_clang_tidy.py index e92179ac82c6a..5e39c05f76d86 100755 --- a/clang-tools-extra/test/clang-tidy/check_clang_tidy.py +++ b/clang-tools-extra/test/clang-tidy/check_clang_tidy.py @@ -205,9 +205,11 @@ def run_clang_tidy(self): self.temp_file_name, ] + [ - "-fix" - if self.export_fixes is None - else "--export-fixes=" + self.export_fixes + ( + "-fix" + if self.export_fixes is None + else "--export-fixes=" + self.export_fixes + ) ] + [ "--checks=-*," + self.check_name, @@ -299,19 +301,37 @@ def run(self): self.check_notes(clang_tidy_output) +CPP_STANDARDS = [ + "c++98", + "c++11", + ("c++14", "c++1y"), + ("c++17", "c++1z"), + ("c++20", "c++2a"), + ("c++23", "c++2b"), + ("c++26", "c++2c"), +] +C_STANDARDS = ["c99", ("c11", "c1x"), "c17", ("c23", "c2x"), "c2y"] + + def expand_std(std): - if std == "c++98-or-later": - return ["c++98", "c++11", "c++14", "c++17", "c++20", "c++23", "c++2c"] - if std == "c++11-or-later": - return ["c++11", "c++14", "c++17", "c++20", "c++23", "c++2c"] - if std == "c++14-or-later": - return ["c++14", "c++17", "c++20", "c++23", "c++2c"] - if std == "c++17-or-later": - return ["c++17", "c++20", "c++23", "c++2c"] - if std == "c++20-or-later": - return ["c++20", "c++23", "c++2c"] - if std == "c++23-or-later": - return ["c++23", "c++2c"] + split_std, or_later, _ = std.partition("-or-later") + + if not or_later: + return [split_std] + + for standard_list in (CPP_STANDARDS, C_STANDARDS): + item = next( + ( + i + for i, v in enumerate(standard_list) + if (split_std in v if isinstance(v, (list, tuple)) else split_std == v) + ), + None, + ) + if item is not None: + return [split_std] + [ + x if isinstance(x, str) else x[0] for x in standard_list[item + 1 :] + ] return [std] diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape.cpp index f5e74df1621ce..26c443b139629 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape.cpp @@ -756,3 +756,21 @@ struct test_implicit_throw { }; }} + +void pointer_exception_can_not_escape_with_const_void_handler() noexcept { + // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'pointer_exception_can_not_escape_with_const_void_handler' which should not throw exceptions + const int value = 42; + try { + throw &value; + } catch (const void *) { + } +} + +void pointer_exception_can_not_escape_with_void_handler() noexcept { + // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'pointer_exception_can_not_escape_with_void_handler' which should not throw exceptions + int value = 42; + try { + throw &value; + } catch (void *) { + } +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-const-or-ref-data-members.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-const-or-ref-data-members.cpp index 5a5d05bb4e94e..e3864be134da3 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-const-or-ref-data-members.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-const-or-ref-data-members.cpp @@ -18,7 +18,7 @@ struct Ok { const int *pc; std::unique_ptr up; std::shared_ptr sp; - gsl::not_null n; + gsl::not_null n; }; struct ConstMember { @@ -60,7 +60,7 @@ struct Ok2 { const Foo *pc; std::unique_ptr up; std::shared_ptr sp; - gsl::not_null n; + gsl::not_null n; }; struct ConstMember2 { diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp index cb6bfcc1dccba..0d1ff0db58371 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp @@ -3,7 +3,7 @@ // RUN: misc-const-correctness.TransformValues: true, \ // RUN: misc-const-correctness.WarnPointersAsValues: false, \ // RUN: misc-const-correctness.TransformPointersAsValues: false \ -// RUN: }}" -- -fno-delayed-template-parsing +// RUN: }}" -- -fno-delayed-template-parsing -fexceptions // ------- Provide test samples for primitive builtins --------- // - every 'p_*' variable is a 'potential_const_*' variable @@ -56,6 +56,15 @@ void some_function(double np_arg0, wchar_t np_arg1) { np_local6--; } +int function_try_block() try { + int p_local0 = 0; + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const' + // CHECK-FIXES: int const p_local0 + return p_local0; +} catch (...) { + return 0; +} + void nested_scopes() { int p_local0 = 2; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const' diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/use-ranges/fake_std.h b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/use-ranges/fake_std.h index 6596511c7a38b..69ac9954f4afa 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/use-ranges/fake_std.h +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/use-ranges/fake_std.h @@ -7,8 +7,8 @@ template class vector { public: using iterator = T *; using const_iterator = const T *; - using reverse_iterator = T*; - using reverse_const_iterator = const T*; + using reverse_iterator = T *; + using reverse_const_iterator = const T *; constexpr const_iterator begin() const; constexpr const_iterator end() const; @@ -72,8 +72,8 @@ template constexpr auto crend(const Container &Cont) { return Cont.crend(); } // Find -template< class InputIt, class T > -InputIt find( InputIt first, InputIt last, const T& value ); +template +InputIt find(InputIt first, InputIt last, const T &value); // Reverse template void reverse(Iter begin, Iter end); @@ -82,6 +82,7 @@ template void reverse(Iter begin, Iter end); template bool includes(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2); +inline namespace _V1 { // IsPermutation template bool is_permutation(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2); @@ -97,9 +98,10 @@ template bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2); template -bool equal(InputIt1 first1, InputIt1 last1, - InputIt2 first2, InputIt2 last2, BinaryPred p) { - // Need a definition to suppress undefined_internal_type when invoked with lambda +bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, + BinaryPred p) { + // Need a definition to suppress undefined_internal_type when invoked with + // lambda return true; } @@ -108,6 +110,7 @@ void iota(ForwardIt first, ForwardIt last, T value); template ForwardIt rotate(ForwardIt first, ForwardIt middle, ForwardIt last); +} // namespace _V1 } // namespace std diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param.cpp index 0dffaefa213a4..7c7ae43698929 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param.cpp @@ -2,6 +2,31 @@ // CHECK-FIXES: #include +namespace std { +template +struct remove_reference; + +template +struct remove_reference { + typedef _Tp type; +}; + +template +struct remove_reference<_Tp &> { + typedef _Tp type; +}; + +template +struct remove_reference<_Tp &&> { + typedef _Tp type; +}; + +template +constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) { + return static_cast::type &&>(__t); +} +} // namespace std + struct ExpensiveToCopyType { const ExpensiveToCopyType & constReference() const { return *this; @@ -357,3 +382,12 @@ void fun() { ExpensiveToCopyType E; NegativeUsingConstructor S(E); } + +struct B { + static void bar(ExpensiveMovableType a, ExpensiveMovableType b); +}; + +template +void NegativeCallWithDependentAndNondependentArgs(ExpensiveMovableType a, T b) { + B::bar(std::move(a), b); +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/non-const-parameter.c b/clang-tools-extra/test/clang-tidy/checkers/readability/non-const-parameter.c new file mode 100644 index 0000000000000..db50467f3dd94 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/non-const-parameter.c @@ -0,0 +1,11 @@ +// RUN: %check_clang_tidy %s readability-non-const-parameter %t + +static int f(); + +int f(p) + int *p; +// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: pointer parameter 'p' can be pointer to const [readability-non-const-parameter] +// CHECK-FIXES: {{^}} const int *p;{{$}} +{ + return *p; +} diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py index be024da5e005c..2038ef6045c7d 100644 --- a/clang/bindings/python/clang/cindex.py +++ b/clang/bindings/python/clang/cindex.py @@ -43,7 +43,7 @@ Most object information is exposed using properties, when the underlying API call is efficient. """ -from __future__ import absolute_import, division, print_function +from __future__ import annotations # TODO # ==== @@ -64,48 +64,80 @@ from ctypes import * -import collections.abc import os +import sys from enum import Enum +from typing import ( + Any, + Callable, + Generic, + Optional, + Type as TType, + TypeVar, + TYPE_CHECKING, + Union as TUnion, +) + +if TYPE_CHECKING: + from ctypes import _Pointer + from typing_extensions import Protocol, TypeAlias + + StrPath: TypeAlias = TUnion[str, os.PathLike[str]] + LibFunc: TypeAlias = TUnion[ + "tuple[str, Optional[list[Any]]]", + "tuple[str, Optional[list[Any]], Any]", + "tuple[str, Optional[list[Any]], Any, Callable[..., Any]]", + ] + + TSeq = TypeVar("TSeq", covariant=True) + + class NoSliceSequence(Protocol[TSeq]): + def __len__(self) -> int: + ... + + def __getitem__(self, key: int) -> TSeq: + ... + # Python 3 strings are unicode, translate them to/from utf8 for C-interop. class c_interop_string(c_char_p): - def __init__(self, p=None): + def __init__(self, p: str | bytes | None = None): if p is None: p = "" if isinstance(p, str): p = p.encode("utf8") super(c_char_p, self).__init__(p) - def __str__(self): - return self.value + def __str__(self) -> str: + return self.value or "" @property - def value(self): - if super(c_char_p, self).value is None: + def value(self) -> str | None: # type: ignore [override] + val = super(c_char_p, self).value + if val is None: return None - return super(c_char_p, self).value.decode("utf8") + return val.decode("utf8") @classmethod - def from_param(cls, param): + def from_param(cls, param: str | bytes | None) -> c_interop_string: if isinstance(param, str): return cls(param) if isinstance(param, bytes): return cls(param) if param is None: # Support passing null to C functions expecting char arrays - return None + return cls(param) raise TypeError( "Cannot convert '{}' to '{}'".format(type(param).__name__, cls.__name__) ) @staticmethod - def to_python_string(x, *args): + def to_python_string(x: c_interop_string, *args: Any) -> str | None: return x.value -def b(x): +def b(x: str | bytes) -> bytes: if isinstance(x, bytes): return x return x.encode("utf8") @@ -115,9 +147,7 @@ def b(x): # object. This is a problem, because it means that from_parameter will see an # integer and pass the wrong value on platforms where int != void*. Work around # this by marshalling object arguments as void**. -c_object_p = POINTER(c_void_p) - -callbacks = {} +c_object_p: TType[_Pointer[Any]] = POINTER(c_void_p) ### Exception Classes ### @@ -169,8 +199,11 @@ def __init__(self, enumeration, message): ### Structures and Utility Classes ### +TInstance = TypeVar("TInstance") +TResult = TypeVar("TResult") + -class CachedProperty: +class CachedProperty(Generic[TInstance, TResult]): """Decorator that lazy-loads the value of a property. The first time the property is accessed, the original property function is @@ -178,16 +211,20 @@ class CachedProperty: property, replacing the original method. """ - def __init__(self, wrapped): + def __init__(self, wrapped: Callable[[TInstance], TResult]): self.wrapped = wrapped try: self.__doc__ = wrapped.__doc__ except: pass - def __get__(self, instance, instance_type=None): + def __get__(self, instance: TInstance, instance_type: Any = None) -> TResult: if instance is None: - return self + property_name = self.wrapped.__name__ + class_name = instance_type.__name__ + raise TypeError( + f"'{property_name}' is not a static attribute of '{class_name}'" + ) value = self.wrapped(instance) setattr(instance, self.wrapped.__name__, value) @@ -200,13 +237,16 @@ class _CXString(Structure): _fields_ = [("spelling", c_char_p), ("free", c_int)] - def __del__(self): + def __del__(self) -> None: conf.lib.clang_disposeString(self) @staticmethod - def from_result(res, fn=None, args=None): + def from_result(res: _CXString, fn: Any = None, args: Any = None) -> str: assert isinstance(res, _CXString) - return conf.lib.clang_getCString(res) + pystr: str | None = conf.lib.clang_getCString(res) + if pystr is None: + return "" + return pystr class SourceLocation(Structure): @@ -236,7 +276,7 @@ def from_position(tu, file, line, column): Retrieve the source location associated with a given file/line/column in a particular translation unit. """ - return conf.lib.clang_getLocation(tu, file, line, column) + return conf.lib.clang_getLocation(tu, file, line, column) # type: ignore [no-any-return] @staticmethod def from_offset(tu, file, offset): @@ -246,7 +286,7 @@ def from_offset(tu, file, offset): file -- File instance to obtain offset from offset -- Integer character offset within file """ - return conf.lib.clang_getLocationForOffset(tu, file, offset) + return conf.lib.clang_getLocationForOffset(tu, file, offset) # type: ignore [no-any-return] @property def file(self): @@ -271,10 +311,10 @@ def offset(self): @property def is_in_system_header(self): """Returns true if the given source location is in a system header.""" - return conf.lib.clang_Location_isInSystemHeader(self) + return conf.lib.clang_Location_isInSystemHeader(self) # type: ignore [no-any-return] def __eq__(self, other): - return conf.lib.clang_equalLocations(self, other) + return conf.lib.clang_equalLocations(self, other) # type: ignore [no-any-return] def __ne__(self, other): return not self.__eq__(other) @@ -307,7 +347,7 @@ class SourceRange(Structure): # object. @staticmethod def from_locations(start, end): - return conf.lib.clang_getRange(start, end) + return conf.lib.clang_getRange(start, end) # type: ignore [no-any-return] @property def start(self): @@ -315,7 +355,7 @@ def start(self): Return a SourceLocation representing the first character within a source range. """ - return conf.lib.clang_getRangeStart(self) + return conf.lib.clang_getRangeStart(self) # type: ignore [no-any-return] @property def end(self): @@ -323,10 +363,10 @@ def end(self): Return a SourceLocation representing the last character within a source range. """ - return conf.lib.clang_getRangeEnd(self) + return conf.lib.clang_getRangeEnd(self) # type: ignore [no-any-return] def __eq__(self, other): - return conf.lib.clang_equalRanges(self, other) + return conf.lib.clang_equalRanges(self, other) # type: ignore [no-any-return] def __ne__(self, other): return not self.__eq__(other) @@ -389,42 +429,42 @@ def __del__(self): @property def severity(self): - return conf.lib.clang_getDiagnosticSeverity(self) + return conf.lib.clang_getDiagnosticSeverity(self) # type: ignore [no-any-return] @property def location(self): - return conf.lib.clang_getDiagnosticLocation(self) + return conf.lib.clang_getDiagnosticLocation(self) # type: ignore [no-any-return] @property def spelling(self): - return conf.lib.clang_getDiagnosticSpelling(self) + return conf.lib.clang_getDiagnosticSpelling(self) # type: ignore [no-any-return] @property - def ranges(self): + def ranges(self) -> NoSliceSequence[SourceRange]: class RangeIterator: - def __init__(self, diag): + def __init__(self, diag: Diagnostic): self.diag = diag - def __len__(self): + def __len__(self) -> int: return int(conf.lib.clang_getDiagnosticNumRanges(self.diag)) - def __getitem__(self, key): + def __getitem__(self, key: int) -> SourceRange: if key >= len(self): raise IndexError - return conf.lib.clang_getDiagnosticRange(self.diag, key) + return conf.lib.clang_getDiagnosticRange(self.diag, key) # type: ignore [no-any-return] return RangeIterator(self) @property - def fixits(self): + def fixits(self) -> NoSliceSequence[FixIt]: class FixItIterator: - def __init__(self, diag): + def __init__(self, diag: Diagnostic): self.diag = diag - def __len__(self): + def __len__(self) -> int: return int(conf.lib.clang_getDiagnosticNumFixIts(self.diag)) - def __getitem__(self, key): + def __getitem__(self, key: int) -> FixIt: range = SourceRange() value = conf.lib.clang_getDiagnosticFixIt(self.diag, key, byref(range)) if len(value) == 0: @@ -435,15 +475,15 @@ def __getitem__(self, key): return FixItIterator(self) @property - def children(self): + def children(self) -> NoSliceSequence[Diagnostic]: class ChildDiagnosticsIterator: - def __init__(self, diag): + def __init__(self, diag: Diagnostic): self.diag_set = conf.lib.clang_getChildDiagnostics(diag) - def __len__(self): + def __len__(self) -> int: return int(conf.lib.clang_getNumDiagnosticsInSet(self.diag_set)) - def __getitem__(self, key): + def __getitem__(self, key: int) -> Diagnostic: diag = conf.lib.clang_getDiagnosticInSet(self.diag_set, key) if not diag: raise IndexError @@ -454,17 +494,17 @@ def __getitem__(self, key): @property def category_number(self): """The category number for this diagnostic or 0 if unavailable.""" - return conf.lib.clang_getDiagnosticCategory(self) + return conf.lib.clang_getDiagnosticCategory(self) # type: ignore [no-any-return] @property def category_name(self): """The string name of the category for this diagnostic.""" - return conf.lib.clang_getDiagnosticCategoryText(self) + return conf.lib.clang_getDiagnosticCategoryText(self) # type: ignore [no-any-return] @property def option(self): """The command-line option that enables this diagnostic.""" - return conf.lib.clang_getDiagnosticOption(self, None) + return conf.lib.clang_getDiagnosticOption(self, None) # type: ignore [no-any-return] @property def disable_option(self): @@ -484,7 +524,7 @@ def format(self, options=None): options = conf.lib.clang_defaultDiagnosticDisplayOptions() if options & ~Diagnostic._FormatOptionsMask: raise ValueError("Invalid format options") - return conf.lib.clang_formatDiagnostic(self, options) + return conf.lib.clang_formatDiagnostic(self, options) # type: ignore [no-any-return] def __repr__(self): return "" % ( @@ -619,39 +659,39 @@ def get_all_kinds(): def is_declaration(self): """Test if this is a declaration kind.""" - return conf.lib.clang_isDeclaration(self) + return conf.lib.clang_isDeclaration(self) # type: ignore [no-any-return] def is_reference(self): """Test if this is a reference kind.""" - return conf.lib.clang_isReference(self) + return conf.lib.clang_isReference(self) # type: ignore [no-any-return] def is_expression(self): """Test if this is an expression kind.""" - return conf.lib.clang_isExpression(self) + return conf.lib.clang_isExpression(self) # type: ignore [no-any-return] def is_statement(self): """Test if this is a statement kind.""" - return conf.lib.clang_isStatement(self) + return conf.lib.clang_isStatement(self) # type: ignore [no-any-return] def is_attribute(self): """Test if this is an attribute kind.""" - return conf.lib.clang_isAttribute(self) + return conf.lib.clang_isAttribute(self) # type: ignore [no-any-return] def is_invalid(self): """Test if this is an invalid kind.""" - return conf.lib.clang_isInvalid(self) + return conf.lib.clang_isInvalid(self) # type: ignore [no-any-return] def is_translation_unit(self): """Test if this is a translation unit kind.""" - return conf.lib.clang_isTranslationUnit(self) + return conf.lib.clang_isTranslationUnit(self) # type: ignore [no-any-return] def is_preprocessing(self): """Test if this is a preprocessing kind.""" - return conf.lib.clang_isPreprocessing(self) + return conf.lib.clang_isPreprocessing(self) # type: ignore [no-any-return] def is_unexposed(self): """Test if this is an unexposed kind.""" - return conf.lib.clang_isUnexposed(self) + return conf.lib.clang_isUnexposed(self) # type: ignore [no-any-return] ### @@ -1524,7 +1564,7 @@ def from_location(tu, location): return cursor def __eq__(self, other): - return conf.lib.clang_equalCursors(self, other) + return conf.lib.clang_equalCursors(self, other) # type: ignore [no-any-return] def __ne__(self, other): return not self.__eq__(other) @@ -1534,41 +1574,41 @@ def is_definition(self): Returns true if the declaration pointed at by the cursor is also a definition of that entity. """ - return conf.lib.clang_isCursorDefinition(self) + return conf.lib.clang_isCursorDefinition(self) # type: ignore [no-any-return] def is_const_method(self): """Returns True if the cursor refers to a C++ member function or member function template that is declared 'const'. """ - return conf.lib.clang_CXXMethod_isConst(self) + return conf.lib.clang_CXXMethod_isConst(self) # type: ignore [no-any-return] def is_converting_constructor(self): """Returns True if the cursor refers to a C++ converting constructor.""" - return conf.lib.clang_CXXConstructor_isConvertingConstructor(self) + return conf.lib.clang_CXXConstructor_isConvertingConstructor(self) # type: ignore [no-any-return] def is_copy_constructor(self): """Returns True if the cursor refers to a C++ copy constructor.""" - return conf.lib.clang_CXXConstructor_isCopyConstructor(self) + return conf.lib.clang_CXXConstructor_isCopyConstructor(self) # type: ignore [no-any-return] def is_default_constructor(self): """Returns True if the cursor refers to a C++ default constructor.""" - return conf.lib.clang_CXXConstructor_isDefaultConstructor(self) + return conf.lib.clang_CXXConstructor_isDefaultConstructor(self) # type: ignore [no-any-return] def is_move_constructor(self): """Returns True if the cursor refers to a C++ move constructor.""" - return conf.lib.clang_CXXConstructor_isMoveConstructor(self) + return conf.lib.clang_CXXConstructor_isMoveConstructor(self) # type: ignore [no-any-return] def is_default_method(self): """Returns True if the cursor refers to a C++ member function or member function template that is declared '= default'. """ - return conf.lib.clang_CXXMethod_isDefaulted(self) + return conf.lib.clang_CXXMethod_isDefaulted(self) # type: ignore [no-any-return] def is_deleted_method(self): """Returns True if the cursor refers to a C++ member function or member function template that is declared '= delete'. """ - return conf.lib.clang_CXXMethod_isDeleted(self) + return conf.lib.clang_CXXMethod_isDeleted(self) # type: ignore [no-any-return] def is_copy_assignment_operator_method(self): """Returnrs True if the cursor refers to a copy-assignment operator. @@ -1593,7 +1633,7 @@ class Bar { Is not. """ - return conf.lib.clang_CXXMethod_isCopyAssignmentOperator(self) + return conf.lib.clang_CXXMethod_isCopyAssignmentOperator(self) # type: ignore [no-any-return] def is_move_assignment_operator_method(self): """Returnrs True if the cursor refers to a move-assignment operator. @@ -1618,7 +1658,7 @@ class Bar { Is not. """ - return conf.lib.clang_CXXMethod_isMoveAssignmentOperator(self) + return conf.lib.clang_CXXMethod_isMoveAssignmentOperator(self) # type: ignore [no-any-return] def is_explicit_method(self): """Determines if a C++ constructor or conversion function is @@ -1663,41 +1703,41 @@ class Foo { This method will return 0 for the constructor and 1 for the conversion function. """ - return conf.lib.clang_CXXMethod_isExplicit(self) + return conf.lib.clang_CXXMethod_isExplicit(self) # type: ignore [no-any-return] def is_mutable_field(self): """Returns True if the cursor refers to a C++ field that is declared 'mutable'. """ - return conf.lib.clang_CXXField_isMutable(self) + return conf.lib.clang_CXXField_isMutable(self) # type: ignore [no-any-return] def is_pure_virtual_method(self): """Returns True if the cursor refers to a C++ member function or member function template that is declared pure virtual. """ - return conf.lib.clang_CXXMethod_isPureVirtual(self) + return conf.lib.clang_CXXMethod_isPureVirtual(self) # type: ignore [no-any-return] def is_static_method(self): """Returns True if the cursor refers to a C++ member function or member function template that is declared 'static'. """ - return conf.lib.clang_CXXMethod_isStatic(self) + return conf.lib.clang_CXXMethod_isStatic(self) # type: ignore [no-any-return] def is_virtual_method(self): """Returns True if the cursor refers to a C++ member function or member function template that is declared 'virtual'. """ - return conf.lib.clang_CXXMethod_isVirtual(self) + return conf.lib.clang_CXXMethod_isVirtual(self) # type: ignore [no-any-return] def is_abstract_record(self): """Returns True if the cursor refers to a C++ record declaration that has pure virtual member functions. """ - return conf.lib.clang_CXXRecord_isAbstract(self) + return conf.lib.clang_CXXRecord_isAbstract(self) # type: ignore [no-any-return] def is_scoped_enum(self): """Returns True if the cursor refers to a scoped enum declaration.""" - return conf.lib.clang_EnumDecl_isScoped(self) + return conf.lib.clang_EnumDecl_isScoped(self) # type: ignore [no-any-return] def get_definition(self): """ @@ -1707,7 +1747,7 @@ def get_definition(self): """ # TODO: Should probably check that this is either a reference or # declaration prior to issuing the lookup. - return conf.lib.clang_getCursorDefinition(self) + return conf.lib.clang_getCursorDefinition(self) # type: ignore [no-any-return] def get_usr(self): """Return the Unified Symbol Resolution (USR) for the entity referenced @@ -1718,13 +1758,13 @@ def get_usr(self): program. USRs can be compared across translation units to determine, e.g., when references in one translation refer to an entity defined in another translation unit.""" - return conf.lib.clang_getCursorUSR(self) + return conf.lib.clang_getCursorUSR(self) # type: ignore [no-any-return] def get_included_file(self): """Returns the File that is included by the current inclusion cursor.""" assert self.kind == CursorKind.INCLUSION_DIRECTIVE - return conf.lib.clang_getIncludedFile(self) + return conf.lib.clang_getIncludedFile(self) # type: ignore [no-any-return] @property def kind(self): @@ -1994,12 +2034,12 @@ def referenced(self): @property def brief_comment(self): """Returns the brief comment text associated with that Cursor""" - return conf.lib.clang_Cursor_getBriefCommentText(self) + return conf.lib.clang_Cursor_getBriefCommentText(self) # type: ignore [no-any-return] @property def raw_comment(self): """Returns the raw comment text associated with that Cursor""" - return conf.lib.clang_Cursor_getRawCommentText(self) + return conf.lib.clang_Cursor_getRawCommentText(self) # type: ignore [no-any-return] def get_arguments(self): """Return an iterator for accessing the arguments of this cursor.""" @@ -2009,24 +2049,24 @@ def get_arguments(self): def get_num_template_arguments(self): """Returns the number of template args associated with this cursor.""" - return conf.lib.clang_Cursor_getNumTemplateArguments(self) + return conf.lib.clang_Cursor_getNumTemplateArguments(self) # type: ignore [no-any-return] def get_template_argument_kind(self, num): """Returns the TemplateArgumentKind for the indicated template argument.""" - return conf.lib.clang_Cursor_getTemplateArgumentKind(self, num) + return conf.lib.clang_Cursor_getTemplateArgumentKind(self, num) # type: ignore [no-any-return] def get_template_argument_type(self, num): """Returns the CXType for the indicated template argument.""" - return conf.lib.clang_Cursor_getTemplateArgumentType(self, num) + return conf.lib.clang_Cursor_getTemplateArgumentType(self, num) # type: ignore [no-any-return] def get_template_argument_value(self, num): """Returns the value of the indicated arg as a signed 64b integer.""" - return conf.lib.clang_Cursor_getTemplateArgumentValue(self, num) + return conf.lib.clang_Cursor_getTemplateArgumentValue(self, num) # type: ignore [no-any-return] def get_template_argument_unsigned_value(self, num): """Returns the value of the indicated arg as an unsigned 64b integer.""" - return conf.lib.clang_Cursor_getTemplateArgumentUnsignedValue(self, num) + return conf.lib.clang_Cursor_getTemplateArgumentUnsignedValue(self, num) # type: ignore [no-any-return] def get_children(self): """Return an iterator for accessing the children of this cursor.""" @@ -2042,8 +2082,8 @@ def visitor(child, parent, children): children.append(child) return 1 # continue - children = [] - conf.lib.clang_visitChildren(self, callbacks["cursor_visit"](visitor), children) + children: list[Cursor] = [] + conf.lib.clang_visitChildren(self, cursor_visit_callback(visitor), children) return iter(children) def walk_preorder(self): @@ -2066,7 +2106,7 @@ def get_tokens(self): def get_field_offsetof(self): """Returns the offsetof the FIELD_DECL pointed by this Cursor.""" - return conf.lib.clang_Cursor_getOffsetOfField(self) + return conf.lib.clang_Cursor_getOffsetOfField(self) # type: ignore [no-any-return] def is_anonymous(self): """ @@ -2074,19 +2114,19 @@ def is_anonymous(self): """ if self.kind == CursorKind.FIELD_DECL: return self.type.get_declaration().is_anonymous() - return conf.lib.clang_Cursor_isAnonymous(self) + return conf.lib.clang_Cursor_isAnonymous(self) # type: ignore [no-any-return] def is_bitfield(self): """ Check if the field is a bitfield. """ - return conf.lib.clang_Cursor_isBitField(self) + return conf.lib.clang_Cursor_isBitField(self) # type: ignore [no-any-return] def get_bitfield_width(self): """ Retrieve the width of a bitfield. """ - return conf.lib.clang_getFieldDeclBitWidth(self) + return conf.lib.clang_getFieldDeclBitWidth(self) # type: ignore [no-any-return] @staticmethod def from_result(res, fn, args): @@ -2223,7 +2263,7 @@ class TypeKind(BaseEnumeration): @property def spelling(self): """Retrieve the spelling of this TypeKind.""" - return conf.lib.clang_getTypeKindSpelling(self.value) + return conf.lib.clang_getTypeKindSpelling(self.value) # type: ignore [no-any-return] INVALID = 0 UNEXPOSED = 1 @@ -2379,25 +2419,25 @@ def kind(self): """Return the kind of this type.""" return TypeKind.from_id(self._kind_id) - def argument_types(self): + def argument_types(self) -> NoSliceSequence[Type]: """Retrieve a container for the non-variadic arguments for this type. The returned object is iterable and indexable. Each item in the container is a Type instance. """ - class ArgumentsIterator(collections.abc.Sequence): - def __init__(self, parent): + class ArgumentsIterator: + def __init__(self, parent: Type): self.parent = parent - self.length = None + self.length: int | None = None - def __len__(self): + def __len__(self) -> int: if self.length is None: self.length = conf.lib.clang_getNumArgTypes(self.parent) return self.length - def __getitem__(self, key): + def __getitem__(self, key: int) -> Type: # FIXME Support slice objects. if not isinstance(key, int): raise TypeError("Must supply a non-negative int.") @@ -2411,7 +2451,7 @@ def __getitem__(self, key): "%d > %d" % (key, len(self)) ) - result = conf.lib.clang_getArgType(self.parent, key) + result: Type = conf.lib.clang_getArgType(self.parent, key) if result.kind == TypeKind.INVALID: raise IndexError("Argument could not be retrieved.") @@ -2470,10 +2510,10 @@ def from_result(res, fn, args): return res def get_num_template_arguments(self): - return conf.lib.clang_Type_getNumTemplateArguments(self) + return conf.lib.clang_Type_getNumTemplateArguments(self) # type: ignore [no-any-return] def get_template_argument_type(self, num): - return conf.lib.clang_Type_getTemplateArgumentAsType(self, num) + return conf.lib.clang_Type_getTemplateArgumentAsType(self, num) # type: ignore [no-any-return] def get_canonical(self): """ @@ -2485,7 +2525,7 @@ def get_canonical(self): example, if 'T' is a typedef for 'int', the canonical type for 'T' would be 'int'. """ - return conf.lib.clang_getCanonicalType(self) + return conf.lib.clang_getCanonicalType(self) # type: ignore [no-any-return] def is_const_qualified(self): """Determine whether a Type has the "const" qualifier set. @@ -2493,7 +2533,7 @@ def is_const_qualified(self): This does not look through typedefs that may have added "const" at a different level. """ - return conf.lib.clang_isConstQualifiedType(self) + return conf.lib.clang_isConstQualifiedType(self) # type: ignore [no-any-return] def is_volatile_qualified(self): """Determine whether a Type has the "volatile" qualifier set. @@ -2501,7 +2541,7 @@ def is_volatile_qualified(self): This does not look through typedefs that may have added "volatile" at a different level. """ - return conf.lib.clang_isVolatileQualifiedType(self) + return conf.lib.clang_isVolatileQualifiedType(self) # type: ignore [no-any-return] def is_restrict_qualified(self): """Determine whether a Type has the "restrict" qualifier set. @@ -2509,83 +2549,83 @@ def is_restrict_qualified(self): This does not look through typedefs that may have added "restrict" at a different level. """ - return conf.lib.clang_isRestrictQualifiedType(self) + return conf.lib.clang_isRestrictQualifiedType(self) # type: ignore [no-any-return] def is_function_variadic(self): """Determine whether this function Type is a variadic function type.""" assert self.kind == TypeKind.FUNCTIONPROTO - return conf.lib.clang_isFunctionTypeVariadic(self) + return conf.lib.clang_isFunctionTypeVariadic(self) # type: ignore [no-any-return] def get_address_space(self): - return conf.lib.clang_getAddressSpace(self) + return conf.lib.clang_getAddressSpace(self) # type: ignore [no-any-return] def get_typedef_name(self): - return conf.lib.clang_getTypedefName(self) + return conf.lib.clang_getTypedefName(self) # type: ignore [no-any-return] def is_pod(self): """Determine whether this Type represents plain old data (POD).""" - return conf.lib.clang_isPODType(self) + return conf.lib.clang_isPODType(self) # type: ignore [no-any-return] def get_pointee(self): """ For pointer types, returns the type of the pointee. """ - return conf.lib.clang_getPointeeType(self) + return conf.lib.clang_getPointeeType(self) # type: ignore [no-any-return] def get_declaration(self): """ Return the cursor for the declaration of the given type. """ - return conf.lib.clang_getTypeDeclaration(self) + return conf.lib.clang_getTypeDeclaration(self) # type: ignore [no-any-return] def get_result(self): """ Retrieve the result type associated with a function type. """ - return conf.lib.clang_getResultType(self) + return conf.lib.clang_getResultType(self) # type: ignore [no-any-return] def get_array_element_type(self): """ Retrieve the type of the elements of the array type. """ - return conf.lib.clang_getArrayElementType(self) + return conf.lib.clang_getArrayElementType(self) # type: ignore [no-any-return] def get_array_size(self): """ Retrieve the size of the constant array. """ - return conf.lib.clang_getArraySize(self) + return conf.lib.clang_getArraySize(self) # type: ignore [no-any-return] def get_class_type(self): """ Retrieve the class type of the member pointer type. """ - return conf.lib.clang_Type_getClassType(self) + return conf.lib.clang_Type_getClassType(self) # type: ignore [no-any-return] def get_named_type(self): """ Retrieve the type named by the qualified-id. """ - return conf.lib.clang_Type_getNamedType(self) + return conf.lib.clang_Type_getNamedType(self) # type: ignore [no-any-return] def get_align(self): """ Retrieve the alignment of the record. """ - return conf.lib.clang_Type_getAlignOf(self) + return conf.lib.clang_Type_getAlignOf(self) # type: ignore [no-any-return] def get_size(self): """ Retrieve the size of the record. """ - return conf.lib.clang_Type_getSizeOf(self) + return conf.lib.clang_Type_getSizeOf(self) # type: ignore [no-any-return] def get_offset(self, fieldname): """ Retrieve the offset of a field in the record. """ - return conf.lib.clang_Type_getOffsetOf(self, fieldname) + return conf.lib.clang_Type_getOffsetOf(self, fieldname) # type: ignore [no-any-return] def get_ref_qualifier(self): """ @@ -2604,10 +2644,8 @@ def visitor(field, children): fields.append(field) return 1 # continue - fields = [] - conf.lib.clang_Type_visitFields( - self, callbacks["fields_visit"](visitor), fields - ) + fields: list[Cursor] = [] + conf.lib.clang_Type_visitFields(self, fields_visit_callback(visitor), fields) return iter(fields) def get_exception_specification_kind(self): @@ -2622,13 +2660,13 @@ def get_exception_specification_kind(self): @property def spelling(self): """Retrieve the spelling of this Type.""" - return conf.lib.clang_getTypeSpelling(self) + return conf.lib.clang_getTypeSpelling(self) # type: ignore [no-any-return] def __eq__(self, other): if type(other) != type(self): return False - return conf.lib.clang_equalTypes(self, other) + return conf.lib.clang_equalTypes(self, other) # type: ignore [no-any-return] def __ne__(self, other): return not self.__eq__(other) @@ -2712,7 +2750,7 @@ def __repr__(self): def spelling(self): if self.__kindNumber in SpellingCache: return SpellingCache[self.__kindNumber] - return conf.lib.clang_getCompletionChunkText(self.cs, self.key) + return conf.lib.clang_getCompletionChunkText(self.cs, self.key) # type: ignore [no-any-return] # We do not use @CachedProperty here, as the manual implementation is # apparently still significantly faster. Please profile carefully if you @@ -2795,7 +2833,7 @@ def __len__(self): @CachedProperty def num_chunks(self): - return conf.lib.clang_getNumCompletionChunks(self.obj) + return conf.lib.clang_getNumCompletionChunks(self.obj) # type: ignore [no-any-return] def __getitem__(self, key): if self.num_chunks <= key: @@ -2804,7 +2842,7 @@ def __getitem__(self, key): @property def priority(self): - return conf.lib.clang_getCompletionPriority(self.obj) + return conf.lib.clang_getCompletionPriority(self.obj) # type: ignore [no-any-return] @property def availability(self): @@ -2814,7 +2852,7 @@ def availability(self): @property def briefComment(self): if conf.function_exists("clang_getCompletionBriefComment"): - return conf.lib.clang_getCompletionBriefComment(self.obj) + return conf.lib.clang_getCompletionBriefComment(self.obj) # type: ignore [no-any-return] return _CXString() def __repr__(self): @@ -2881,16 +2919,16 @@ def results(self): return self.ptr.contents @property - def diagnostics(self): + def diagnostics(self) -> NoSliceSequence[Diagnostic]: class DiagnosticsItr: - def __init__(self, ccr): + def __init__(self, ccr: CodeCompletionResults): self.ccr = ccr - def __len__(self): + def __len__(self) -> int: return int(conf.lib.clang_codeCompleteGetNumDiagnostics(self.ccr)) - def __getitem__(self, key): - return conf.lib.clang_codeCompleteGetDiagnostic(self.ccr, key) + def __getitem__(self, key: int) -> Diagnostic: + return conf.lib.clang_codeCompleteGetDiagnostic(self.ccr, key) # type: ignore [no-any-return] return DiagnosticsItr(self) @@ -2973,6 +3011,20 @@ class TranslationUnit(ClangObject): # into the set of code completions returned from this translation unit. PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION = 128 + @staticmethod + def process_unsaved_files(unsaved_files) -> Array[_CXUnsavedFile] | None: + unsaved_array = None + if len(unsaved_files): + unsaved_array = (_CXUnsavedFile * len(unsaved_files))() + for i, (name, contents) in enumerate(unsaved_files): + if hasattr(contents, "read"): + contents = contents.read() + binary_contents = b(contents) + unsaved_array[i].name = b(os.fspath(name)) + unsaved_array[i].contents = binary_contents + unsaved_array[i].length = len(binary_contents) + return unsaved_array + @classmethod def from_source( cls, filename, args=None, unsaved_files=None, options=0, index=None @@ -3029,16 +3081,7 @@ def from_source( if len(args) > 0: args_array = (c_char_p * len(args))(*[b(x) for x in args]) - unsaved_array = None - if len(unsaved_files) > 0: - unsaved_array = (_CXUnsavedFile * len(unsaved_files))() - for i, (name, contents) in enumerate(unsaved_files): - if hasattr(contents, "read"): - contents = contents.read() - contents = b(contents) - unsaved_array[i].name = b(os.fspath(name)) - unsaved_array[i].contents = contents - unsaved_array[i].length = len(contents) + unsaved_array = cls.process_unsaved_files(unsaved_files) ptr = conf.lib.clang_parseTranslationUnit( index, @@ -3095,12 +3138,12 @@ def __del__(self): @property def cursor(self): """Retrieve the cursor that represents the given translation unit.""" - return conf.lib.clang_getTranslationUnitCursor(self) + return conf.lib.clang_getTranslationUnitCursor(self) # type: ignore [no-any-return] @property def spelling(self): """Get the original translation unit source file name.""" - return conf.lib.clang_getTranslationUnitSpelling(self) + return conf.lib.clang_getTranslationUnitSpelling(self) # type: ignore [no-any-return] def get_includes(self): """ @@ -3119,7 +3162,7 @@ def visitor(fobj, lptr, depth, includes): # Automatically adapt CIndex/ctype pointers to python objects includes = [] conf.lib.clang_getInclusions( - self, callbacks["translation_unit_includes"](visitor), includes + self, translation_unit_includes_callback(visitor), includes ) return iter(includes) @@ -3187,19 +3230,19 @@ def get_extent(self, filename, locations): return SourceRange.from_locations(start_location, end_location) @property - def diagnostics(self): + def diagnostics(self) -> NoSliceSequence[Diagnostic]: """ Return an iterable (and indexable) object containing the diagnostics. """ class DiagIterator: - def __init__(self, tu): + def __init__(self, tu: TranslationUnit): self.tu = tu - def __len__(self): + def __len__(self) -> int: return int(conf.lib.clang_getNumDiagnostics(self.tu)) - def __getitem__(self, key): + def __getitem__(self, key: int) -> Diagnostic: diag = conf.lib.clang_getDiagnostic(self.tu, key) if not diag: raise IndexError @@ -3219,16 +3262,7 @@ def reparse(self, unsaved_files=None, options=0): if unsaved_files is None: unsaved_files = [] - unsaved_files_array = 0 - if len(unsaved_files): - unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))() - for i, (name, contents) in enumerate(unsaved_files): - if hasattr(contents, "read"): - contents = contents.read() - contents = b(contents) - unsaved_files_array[i].name = b(os.fspath(name)) - unsaved_files_array[i].contents = contents - unsaved_files_array[i].length = len(contents) + unsaved_files_array = self.process_unsaved_files(unsaved_files) ptr = conf.lib.clang_reparseTranslationUnit( self, len(unsaved_files), unsaved_files_array, options ) @@ -3291,16 +3325,7 @@ def codeComplete( if unsaved_files is None: unsaved_files = [] - unsaved_files_array = 0 - if len(unsaved_files): - unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))() - for i, (name, contents) in enumerate(unsaved_files): - if hasattr(contents, "read"): - contents = contents.read() - contents = b(contents) - unsaved_files_array[i].name = b(os.fspath(name)) - unsaved_files_array[i].contents = contents - unsaved_files_array[i].length = len(contents) + unsaved_files_array = self.process_unsaved_files(unsaved_files) ptr = conf.lib.clang_codeCompleteAt( self, os.fspath(path), @@ -3344,12 +3369,12 @@ def from_name(translation_unit, file_name): @property def name(self): """Return the complete file and path name of the file.""" - return conf.lib.clang_getFileName(self) + return conf.lib.clang_getFileName(self) # type: ignore [no-any-return] @property def time(self): """Return the last modification time of the file.""" - return conf.lib.clang_getFileTime(self) + return conf.lib.clang_getFileTime(self) # type: ignore [no-any-return] def __str__(self): return self.name @@ -3428,12 +3453,12 @@ def __init__(self, cmd, ccmds): @property def directory(self): """Get the working directory for this CompileCommand""" - return conf.lib.clang_CompileCommand_getDirectory(self.cmd) + return conf.lib.clang_CompileCommand_getDirectory(self.cmd) # type: ignore [no-any-return] @property def filename(self): """Get the working filename for this CompileCommand""" - return conf.lib.clang_CompileCommand_getFilename(self.cmd) + return conf.lib.clang_CompileCommand_getFilename(self.cmd) # type: ignore [no-any-return] @property def arguments(self): @@ -3512,7 +3537,7 @@ def getCompileCommands(self, filename): Get an iterable object providing all the CompileCommands available to build filename. Returns None if filename is not found in the database. """ - return conf.lib.clang_CompilationDatabase_getCompileCommands( + return conf.lib.clang_CompilationDatabase_getCompileCommands( # type: ignore [no-any-return] self, os.fspath(filename) ) @@ -3521,7 +3546,7 @@ def getAllCompileCommands(self): Get an iterable object providing all the CompileCommands available from the database. """ - return conf.lib.clang_CompilationDatabase_getAllCompileCommands(self) + return conf.lib.clang_CompilationDatabase_getAllCompileCommands(self) # type: ignore [no-any-return] class Token(Structure): @@ -3542,7 +3567,7 @@ def spelling(self): This is the textual representation of the token in source. """ - return conf.lib.clang_getTokenSpelling(self._tu, self) + return conf.lib.clang_getTokenSpelling(self._tu, self) # type: ignore [no-any-return] @property def kind(self): @@ -3552,12 +3577,12 @@ def kind(self): @property def location(self): """The SourceLocation this Token occurs at.""" - return conf.lib.clang_getTokenLocation(self._tu, self) + return conf.lib.clang_getTokenLocation(self._tu, self) # type: ignore [no-any-return] @property def extent(self): """The SourceRange this Token occupies.""" - return conf.lib.clang_getTokenExtent(self._tu, self) + return conf.lib.clang_getTokenExtent(self._tu, self) # type: ignore [no-any-return] @property def cursor(self): @@ -3619,7 +3644,7 @@ def overwrite_changed_files(self): Returns 1 if any files were not saved successfully, returns 0 otherwise. """ - return conf.lib.clang_CXRewriter_overwriteChangedFiles(self) + return conf.lib.clang_CXRewriter_overwriteChangedFiles(self) # type: ignore [no-any-return] def write_main_file_to_stdout(self): """ @@ -3631,15 +3656,15 @@ def write_main_file_to_stdout(self): # Now comes the plumbing to hook up the C library. -# Register callback types in common container. -callbacks["translation_unit_includes"] = CFUNCTYPE( +# Register callback types +translation_unit_includes_callback = CFUNCTYPE( None, c_object_p, POINTER(SourceLocation), c_uint, py_object ) -callbacks["cursor_visit"] = CFUNCTYPE(c_int, Cursor, Cursor, py_object) -callbacks["fields_visit"] = CFUNCTYPE(c_int, Cursor, py_object) +cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object) +fields_visit_callback = CFUNCTYPE(c_int, Cursor, py_object) # Functions strictly alphabetical order. -functionList = [ +functionList: list[LibFunc] = [ ( "clang_annotateTokens", [TranslationUnit, POINTER(Token), c_uint, POINTER(Cursor)], @@ -3809,7 +3834,7 @@ def write_main_file_to_stdout(self): ("clang_getIncludedFile", [Cursor], c_object_p, File.from_result), ( "clang_getInclusions", - [TranslationUnit, callbacks["translation_unit_includes"], py_object], + [TranslationUnit, translation_unit_includes_callback, py_object], ), ( "clang_getInstantiationLocation", @@ -3894,7 +3919,7 @@ def write_main_file_to_stdout(self): "clang_tokenize", [TranslationUnit, SourceRange, POINTER(POINTER(Token)), POINTER(c_uint)], ), - ("clang_visitChildren", [Cursor, callbacks["cursor_visit"], py_object], c_uint), + ("clang_visitChildren", [Cursor, cursor_visit_callback, py_object], c_uint), ("clang_Cursor_getNumArguments", [Cursor], c_int), ("clang_Cursor_getArgument", [Cursor, c_uint], Cursor, Cursor.from_result), ("clang_Cursor_getNumTemplateArguments", [Cursor], c_int), @@ -3921,19 +3946,19 @@ def write_main_file_to_stdout(self): ("clang_Type_getSizeOf", [Type], c_longlong), ("clang_Type_getCXXRefQualifier", [Type], c_uint), ("clang_Type_getNamedType", [Type], Type, Type.from_result), - ("clang_Type_visitFields", [Type, callbacks["fields_visit"], py_object], c_uint), + ("clang_Type_visitFields", [Type, fields_visit_callback, py_object], c_uint), ] class LibclangError(Exception): - def __init__(self, message): + def __init__(self, message: str): self.m = message - def __str__(self): + def __str__(self) -> str: return self.m -def register_function(lib, item, ignore_errors): +def register_function(lib: CDLL, item: LibFunc, ignore_errors: bool) -> None: # A function may not exist, if these bindings are used with an older or # incompatible version of libclang.so. try: @@ -3957,15 +3982,15 @@ def register_function(lib, item, ignore_errors): func.errcheck = item[3] -def register_functions(lib, ignore_errors): +def register_functions(lib: CDLL, ignore_errors: bool) -> None: """Register function prototypes with a libclang library instance. This must be called as part of library instantiation so Python knows how to call out to the shared library. """ - def register(item): - return register_function(lib, item, ignore_errors) + def register(item: LibFunc) -> None: + register_function(lib, item, ignore_errors) for f in functionList: register(f) @@ -3973,12 +3998,12 @@ def register(item): class Config: library_path = None - library_file = None + library_file: str | None = None compatibility_check = True loaded = False @staticmethod - def set_library_path(path): + def set_library_path(path: StrPath) -> None: """Set the path in which to search for libclang""" if Config.loaded: raise Exception( @@ -3989,7 +4014,7 @@ def set_library_path(path): Config.library_path = os.fspath(path) @staticmethod - def set_library_file(filename): + def set_library_file(filename: StrPath) -> None: """Set the exact location of libclang""" if Config.loaded: raise Exception( @@ -4000,7 +4025,7 @@ def set_library_file(filename): Config.library_file = os.fspath(filename) @staticmethod - def set_compatibility_check(check_status): + def set_compatibility_check(check_status: bool) -> None: """Perform compatibility check when loading libclang The python bindings are only tested and evaluated with the version of @@ -4026,13 +4051,13 @@ def set_compatibility_check(check_status): Config.compatibility_check = check_status @CachedProperty - def lib(self): + def lib(self) -> CDLL: lib = self.get_cindex_library() register_functions(lib, not Config.compatibility_check) Config.loaded = True return lib - def get_filename(self): + def get_filename(self) -> str: if Config.library_file: return Config.library_file @@ -4052,7 +4077,7 @@ def get_filename(self): return file - def get_cindex_library(self): + def get_cindex_library(self) -> CDLL: try: library = cdll.LoadLibrary(self.get_filename()) except OSError as e: @@ -4065,7 +4090,7 @@ def get_cindex_library(self): return library - def function_exists(self, name): + def function_exists(self, name: str) -> bool: try: getattr(self.lib, name) except AttributeError: @@ -4077,6 +4102,7 @@ def function_exists(self, name): conf = Config() __all__ = [ + "AccessSpecifier", "AvailabilityKind", "BinaryOperator", "Config", @@ -4087,12 +4113,16 @@ def function_exists(self, name): "CursorKind", "Cursor", "Diagnostic", + "ExceptionSpecificationKind", "File", "FixIt", "Index", "LinkageKind", + "RefQualifierKind", "SourceLocation", "SourceRange", + "StorageClass", + "TemplateArgumentKind", "TLSKind", "TokenKind", "Token", diff --git a/clang/bindings/python/tests/cindex/test_code_completion.py b/clang/bindings/python/tests/cindex/test_code_completion.py index ca52fc6f73e1d..1d513dbca2536 100644 --- a/clang/bindings/python/tests/cindex/test_code_completion.py +++ b/clang/bindings/python/tests/cindex/test_code_completion.py @@ -53,7 +53,7 @@ def test_code_complete(self): expected = [ "{'int', ResultType} | {'test1', TypedText} || Priority: 50 || Availability: Available || Brief comment: Aaa.", "{'void', ResultType} | {'test2', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 50 || Availability: Available || Brief comment: Bbb.", - "{'return', TypedText} | {';', SemiColon} || Priority: 40 || Availability: Available || Brief comment: None", + "{'return', TypedText} | {';', SemiColon} || Priority: 40 || Availability: Available || Brief comment: ", ] self.check_completion_results(cr, expected) @@ -94,7 +94,7 @@ def test_code_complete_pathlike(self): expected = [ "{'int', ResultType} | {'test1', TypedText} || Priority: 50 || Availability: Available || Brief comment: Aaa.", "{'void', ResultType} | {'test2', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 50 || Availability: Available || Brief comment: Bbb.", - "{'return', TypedText} | {';', SemiColon} || Priority: 40 || Availability: Available || Brief comment: None", + "{'return', TypedText} | {';', SemiColon} || Priority: 40 || Availability: Available || Brief comment: ", ] self.check_completion_results(cr, expected) @@ -128,19 +128,19 @@ class Q : public P { cr = tu.codeComplete("fake.cpp", 12, 5, unsaved_files=files) expected = [ - "{'const', TypedText} || Priority: 50 || Availability: Available || Brief comment: None", - "{'volatile', TypedText} || Priority: 50 || Availability: Available || Brief comment: None", - "{'operator', TypedText} || Priority: 40 || Availability: Available || Brief comment: None", - "{'P', TypedText} || Priority: 50 || Availability: Available || Brief comment: None", - "{'Q', TypedText} || Priority: 50 || Availability: Available || Brief comment: None", + "{'const', TypedText} || Priority: 50 || Availability: Available || Brief comment: ", + "{'volatile', TypedText} || Priority: 50 || Availability: Available || Brief comment: ", + "{'operator', TypedText} || Priority: 40 || Availability: Available || Brief comment: ", + "{'P', TypedText} || Priority: 50 || Availability: Available || Brief comment: ", + "{'Q', TypedText} || Priority: 50 || Availability: Available || Brief comment: ", ] self.check_completion_results(cr, expected) cr = tu.codeComplete("fake.cpp", 13, 5, unsaved_files=files) expected = [ - "{'P', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: None", - "{'P &', ResultType} | {'operator=', TypedText} | {'(', LeftParen} | {'const P &', Placeholder} | {')', RightParen} || Priority: 79 || Availability: Available || Brief comment: None", - "{'int', ResultType} | {'member', TypedText} || Priority: 35 || Availability: NotAccessible || Brief comment: None", - "{'void', ResultType} | {'~P', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 79 || Availability: Available || Brief comment: None", + "{'P', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: ", + "{'P &', ResultType} | {'operator=', TypedText} | {'(', LeftParen} | {'const P &', Placeholder} | {')', RightParen} || Priority: 79 || Availability: Available || Brief comment: ", + "{'int', ResultType} | {'member', TypedText} || Priority: 35 || Availability: NotAccessible || Brief comment: ", + "{'void', ResultType} | {'~P', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 79 || Availability: Available || Brief comment: ", ] self.check_completion_results(cr, expected) diff --git a/clang/bindings/python/tests/cindex/test_comment.py b/clang/bindings/python/tests/cindex/test_comment.py index 0727c6fa35d95..265c6d3d73de0 100644 --- a/clang/bindings/python/tests/cindex/test_comment.py +++ b/clang/bindings/python/tests/cindex/test_comment.py @@ -53,5 +53,5 @@ def test_comment(self): f = get_cursor(tu, "f") raw = f.raw_comment brief = f.brief_comment - self.assertIsNone(raw) - self.assertIsNone(brief) + self.assertEqual(raw, "") + self.assertEqual(brief, "") diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake index 73ebd36c28496..75ceb799352f9 100644 --- a/clang/cmake/caches/Fuchsia-stage2.cmake +++ b/clang/cmake/caches/Fuchsia-stage2.cmake @@ -309,7 +309,7 @@ foreach(target armv6m-unknown-eabi;armv7m-unknown-eabi;armv8m.main-unknown-eabi) foreach(lang C;CXX;ASM) set(BUILTINS_${target}_CMAKE_${lang}_local_flags "--target=${target} -mthumb") if(${target} STREQUAL "armv8m.main-unknown-eabi") - set(BUILTINS_${target}_CMAKE_${lang}_local_flags "${BUILTINS_${target}_CMAKE_${lang}_local_flags} -mfloat-abi=hard -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" CACHE STRING "") endif() set(BUILTINS_${target}_CMAKE_${lang}_FLAGS "${BUILTINS_${target}_CMAKE_${lang}_local_flags}" CACHE STRING "") endforeach() @@ -327,18 +327,24 @@ foreach(target armv6m-unknown-eabi;armv7m-unknown-eabi;armv8m.main-unknown-eabi) 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}_FLAGS "--target=${target} -mthumb -Wno-atomic-alignment \"-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)\" \"-Dfprintf(stream, format, ...)=printf(format)\" \"-Dtimeval=struct timeval{int tv_sec; int tv_usec;}\" \"-Dgettimeofday(tv, tz)\" -D_LIBCPP_PRINT=1" CACHE STRING "") + 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)\" \"-Dtimeval=struct timeval{int tv_sec; int tv_usec;}\" \"-Dgettimeofday(tv, tz)\" -D_LIBCPP_PRINT=1") + if(${target} STREQUAL "armv8m.main-unknown-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 "") + endif() + set(RUNTIMES_${target}_CMAKE_${lang}_FLAGS "${RUNTIMES_${target}_CMAKE_${lang}_local_flags}" CACHE STRING "") endforeach() foreach(type SHARED;MODULE;EXE) set(RUNTIMES_${target}_CMAKE_${type}_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "") endforeach() set(RUNTIMES_${target}_LLVM_LIBC_FULL_BUILD ON CACHE BOOL "") set(RUNTIMES_${target}_LIBC_ENABLE_USE_BY_CLANG ON CACHE BOOL "") + set(RUNTIMES_${target}_LIBC_USE_NEW_HEADER_GEN OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ABI_VERSION 2 CACHE STRING "") set(RUNTIMES_${target}_LIBCXX_CXX_ABI none CACHE STRING "") set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC ON CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS ON CACHE BOOL "") + set(RUNTIMES_${target}_LIBCXX_LIBC "llvm-libc" CACHE STRING "") set(RUNTIMES_${target}_LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "") @@ -384,11 +390,13 @@ foreach(target riscv32-unknown-elf) endforeach() set(RUNTIMES_${target}_LLVM_LIBC_FULL_BUILD ON CACHE BOOL "") set(RUNTIMES_${target}_LIBC_ENABLE_USE_BY_CLANG ON CACHE BOOL "") + set(RUNTIMES_${target}_LIBC_USE_NEW_HEADER_GEN OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ABI_VERSION 2 CACHE STRING "") set(RUNTIMES_${target}_LIBCXX_CXX_ABI none CACHE STRING "") set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC ON CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS ON CACHE BOOL "") + set(RUNTIMES_${target}_LIBCXX_LIBC "llvm-libc" CACHE STRING "") set(RUNTIMES_${target}_LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "") diff --git a/clang/cmake/caches/Fuchsia.cmake b/clang/cmake/caches/Fuchsia.cmake index 4d3af3ad3f403..2d2dcb9ae6798 100644 --- a/clang/cmake/caches/Fuchsia.cmake +++ b/clang/cmake/caches/Fuchsia.cmake @@ -67,9 +67,6 @@ set(_FUCHSIA_BOOTSTRAP_PASSTHROUGH SWIG_EXECUTABLE CMAKE_FIND_PACKAGE_PREFER_CONFIG CMAKE_SYSROOT - CMAKE_MODULE_LINKER_FLAGS - CMAKE_SHARED_LINKER_FLAGS - CMAKE_EXE_LINKER_FLAGS LLVM_WINSYSROOT LLVM_VFSOVERLAY ) diff --git a/clang/cmake/caches/Release.cmake b/clang/cmake/caches/Release.cmake index 9e6feb479d45f..e5161dd9a27b9 100644 --- a/clang/cmake/caches/Release.cmake +++ b/clang/cmake/caches/Release.cmake @@ -29,9 +29,13 @@ endfunction() # cache file to CMake via -C. e.g. # # cmake -D LLVM_RELEASE_ENABLE_PGO=ON -C Release.cmake +set (DEFAULT_RUNTIMES "compiler-rt;libcxx") +if (NOT WIN32) + list(APPEND DEFAULT_RUNTIMES "libcxxabi" "libunwind") +endif() set(LLVM_RELEASE_ENABLE_LTO THIN CACHE STRING "") set(LLVM_RELEASE_ENABLE_PGO ON CACHE BOOL "") -set(LLVM_RELEASE_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "") +set(LLVM_RELEASE_ENABLE_RUNTIMES ${DEFAULT_RUNTIMES} CACHE STRING "") set(LLVM_RELEASE_ENABLE_PROJECTS "clang;lld;lldb;clang-tools-extra;bolt;polly;mlir;flang" CACHE STRING "") # Note we don't need to add install here, since it is one of the pre-defined # steps. diff --git a/clang/cmake/modules/AddClang.cmake b/clang/cmake/modules/AddClang.cmake index 9d09be1936847..5327b5d2f0892 100644 --- a/clang/cmake/modules/AddClang.cmake +++ b/clang/cmake/modules/AddClang.cmake @@ -147,6 +147,7 @@ endmacro(add_clang_library) macro(add_clang_executable name) add_llvm_executable( ${name} ${ARGN} ) set_clang_windows_version_resource_properties(${name}) + set_target_properties(${name} PROPERTIES XCODE_GENERATE_SCHEME ON) endmacro(add_clang_executable) macro(add_clang_tool name) @@ -181,6 +182,7 @@ macro(add_clang_tool name) set_property(GLOBAL APPEND PROPERTY CLANG_EXPORTS ${name}) endif() endif() + set_target_properties(${name} PROPERTIES XCODE_GENERATE_SCHEME ON) endmacro() macro(add_clang_symlink name dest) diff --git a/clang/docs/ClangNVLinkWrapper.rst b/clang/docs/ClangNVLinkWrapper.rst new file mode 100644 index 0000000000000..2acdb054572f8 --- /dev/null +++ b/clang/docs/ClangNVLinkWrapper.rst @@ -0,0 +1,74 @@ +==================== +Clang nvlink Wrapper +==================== + +.. contents:: + :local: + +.. _clang-nvlink-wrapper: + +Introduction +============ + +This tools works as a wrapper around the NVIDIA ``nvlink`` linker. The purpose +of this wrapper is to provide an interface similar to the ``ld.lld`` linker +while still relying on NVIDIA's proprietary linker to produce the final output. + +``nvlink`` has a number of known quirks that make it difficult to use in a +unified offloading setting. For example, it does not accept ``.o`` files as they +must be named ``.cubin``. Static archives do not work, so passing a ``.a`` will +provide a linker error. ``nvlink`` also does not support link time optimization +and ignores many standard linker arguments. This tool works around these issues. + +Usage +===== + +This tool can be used with the following options. Any arguments not intended +only for the linker wrapper will be forwarded to ``nvlink``. + +.. code-block:: console + + OVERVIEW: A utility that wraps around the NVIDIA 'nvlink' linker. + This enables static linking and LTO handling for NVPTX targets. + + USAGE: clang-nvlink-wrapper [options] + + OPTIONS: + --arch Specify the 'sm_' name of the target architecture. + --cuda-path= Set the system CUDA path + --dry-run Print generated commands without running. + --feature Specify the '+ptx' freature to use for LTO. + -g Specify that this was a debug compile. + -help-hidden Display all available options + -help Display available options (--help-hidden for more) + -L Add to the library search path + -l Search for library + -mllvm Arguments passed to LLVM, including Clang invocations, + for which the '-mllvm' prefix is preserved. Use '-mllvm + --help' for a list of options. + -o Path to file to write output + --plugin-opt=jobs= + Number of LTO codegen partitions + --plugin-opt=lto-partitions= + Number of LTO codegen partitions + --plugin-opt=O + Optimization level for LTO + --plugin-opt=thinlto + Enable the thin-lto backend + --plugin-opt= Arguments passed to LLVM, including Clang invocations, + for which the '-mllvm' prefix is preserved. Use '-mllvm + --help' for a list of options. + --save-temps Save intermediate results + --version Display the version number and exit + -v Print verbose information + +Example +======= + +This tool is intended to be invoked when targeting the NVPTX toolchain directly +as a cross-compiling target. This can be used to create standalone GPU +executables with normal linking semantics similar to standard compilation. + +.. code-block:: console + + clang --target=nvptx64-nvidia-cuda -march=native -flto=full input.c diff --git a/clang/docs/CommandGuide/clang.rst b/clang/docs/CommandGuide/clang.rst index 29154292dc7a5..663aca1f6ddcb 100644 --- a/clang/docs/CommandGuide/clang.rst +++ b/clang/docs/CommandGuide/clang.rst @@ -429,7 +429,8 @@ Code Generation Options :option:`-Ofast` Enables all the optimizations from :option:`-O3` along with other aggressive optimizations that may violate strict compliance with - language standards. + language standards. This is deprecated in favor of :option:`-O3` + in combination with :option:`-ffast-math`. :option:`-Os` Like :option:`-O2` with extra optimizations to reduce code size. diff --git a/clang/docs/HLSL/AvailabilityDiagnostics.rst b/clang/docs/HLSL/AvailabilityDiagnostics.rst index bb9d02f21dde6..c2f260f268e7b 100644 --- a/clang/docs/HLSL/AvailabilityDiagnostics.rst +++ b/clang/docs/HLSL/AvailabilityDiagnostics.rst @@ -52,7 +52,6 @@ If the compilation target is a shader library, only availability based on shader As a result, availability based on specific shader stage will only be diagnosed in code that is reachable from a shader entry point or library export function. It also means that function bodies might be scanned multiple time. When that happens, care should be taken not to produce duplicated diagnostics. -======== Examples ======== @@ -62,7 +61,7 @@ For the example below, the ``WaveActiveCountBits`` API function became available The availability of ``ddx`` function depends on a shader stage. It is available for pixel shaders in shader model 2.1 and higher, for compute, mesh and amplification shaders in shader model 6.6 and higher. For any other shader stages it is not available. Compute shader example -====================== +---------------------- .. code-block:: c++ @@ -94,7 +93,7 @@ With strict diagnostic mode, in addition to the 2 errors above Clang will also e <>:7:13: error: 'WaveActiveCountBits' is only available on Shader Model 6.5 or newer Shader library example -====================== +---------------------- .. code-block:: c++ diff --git a/clang/docs/HLSL/ExpectedDifferences.rst b/clang/docs/HLSL/ExpectedDifferences.rst index a29b6348e0b8e..4782eb3cda754 100644 --- a/clang/docs/HLSL/ExpectedDifferences.rst +++ b/clang/docs/HLSL/ExpectedDifferences.rst @@ -1,4 +1,4 @@ - +=================================== Expected Differences vs DXC and FXC =================================== diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index d09b1f892be22..de0a4fa24f319 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -1546,6 +1546,7 @@ The following type trait primitives are supported by Clang. Those traits marked * ``__array_extent(type, dim)`` (Embarcadero): The ``dim``'th array bound in the type ``type``, or ``0`` if ``dim >= __array_rank(type)``. +* ``__builtin_is_virtual_base_of`` (C++, GNU, Microsoft) * ``__can_pass_in_regs`` (C++) Returns whether a class can be passed in registers under the current ABI. This type can only be applied to unqualified class types. diff --git a/clang/docs/MSVCCompatibility.rst b/clang/docs/MSVCCompatibility.rst index b2486052abf9a..0b6fea597f8d3 100644 --- a/clang/docs/MSVCCompatibility.rst +++ b/clang/docs/MSVCCompatibility.rst @@ -154,3 +154,133 @@ a hint suggesting how to fix the problem. As of this writing, Clang is able to compile a simple ATL hello world application. There are still issues parsing WRL headers for modern Windows 8 apps, but they should be addressed soon. + +__forceinline behavior +====================== + +``__forceinline`` behaves like ``[[clang::always_inline]]``. +Inlining is always attempted regardless of optimization level. + +This differs from MSVC where ``__forceinline`` is only respected once inline expansion is enabled +which allows any function marked implicitly or explicitly ``inline`` or ``__forceinline`` to be expanded. +Therefore functions marked ``__forceinline`` will be expanded when the optimization level is ``/Od`` unlike +MSVC where ``__forceinline`` will not be expanded under ``/Od``. + +SIMD and instruction set intrinsic behavior +=========================================== + +Clang follows the GCC model for intrinsics and not the MSVC model. +There are currently no plans to support the MSVC model. + +MSVC intrinsics always emit the machine instruction the intrinsic models regardless of the compile time options specified. +For example ``__popcnt`` always emits the x86 popcnt instruction even if the compiler does not have the option enabled to emit popcnt on its own volition. + +There are two common cases where code that compiles with MSVC will need reworking to build on clang. +Assume the examples are only built with `-msse2` so we do not have the intrinsics at compile time. + +.. code-block:: c++ + + unsigned PopCnt(unsigned v) { + if (HavePopCnt) + return __popcnt(v); + else + return GenericPopCnt(v); + } + +.. code-block:: c++ + + __m128 dot4_sse3(__m128 v0, __m128 v1) { + __m128 r = _mm_mul_ps(v0, v1); + r = _mm_hadd_ps(r, r); + r = _mm_hadd_ps(r, r); + return r; + } + +Clang expects that either you have compile time support for the target features, `-msse3` and `-mpopcnt`, you mark the function with the expected target feature or use runtime detection with an indirect call. + +.. code-block:: c++ + + __attribute__((__target__("sse3"))) __m128 dot4_sse3(__m128 v0, __m128 v1) { + __m128 r = _mm_mul_ps(v0, v1); + r = _mm_hadd_ps(r, r); + r = _mm_hadd_ps(r, r); + return r; + } + +The SSE3 dot product can be easily fixed by either building the translation unit with SSE3 support or using `__target__` to compile that specific function with SSE3 support. + +.. code-block:: c++ + + unsigned PopCnt(unsigned v) { + if (HavePopCnt) + return __popcnt(v); + else + return GenericPopCnt(v); + } + +The above ``PopCnt`` example must be changed to work with clang. If we mark the function with `__target__("popcnt")` then the compiler is free to emit popcnt at will which we do not want. While this isn't a concern in our small example it is a concern in larger functions with surrounding code around the intrinsics. Similar reasoning for compiling the translation unit with `-mpopcnt`. +We must split each branch into its own function that can be called indirectly instead of using the intrinsic directly. + +.. code-block:: c++ + + __attribute__((__target__("popcnt"))) unsigned hwPopCnt(unsigned v) { return __popcnt(v); } + unsigned (*PopCnt)(unsigned) = HavePopCnt ? hwPopCnt : GenericPopCnt; + +.. code-block:: c++ + + __attribute__((__target__("popcnt"))) unsigned hwPopCnt(unsigned v) { return __popcnt(v); } + unsigned PopCnt(unsigned v) { + if (HavePopCnt) + return hwPopCnt(v); + else + return GenericPopCnt(v); + } + +In the above example ``hwPopCnt`` will not be inlined into ``PopCnt`` since ``PopCnt`` doesn't have the popcnt target feature. +With a larger function that does real work the function call overhead is negligible. However in our popcnt example there is the function call +overhead. There is no analog for this specific MSVC behavior in clang. + +For clang we effectively have to create the dispatch function ourselves to each specfic implementation. + +SIMD vector types +================= + +Clang's simd vector types are builtin types and not user defined types as in MSVC. This does have some observable behavior changes. +We will look at the x86 `__m128` type for the examples below but the statements apply to all vector types including ARM's `float32x4_t`. + +There are no members that can be accessed on the vector types. Vector types are not structs in clang. +You cannot use ``__m128.m128_f32[0]`` to access the first element of the `__m128`. +This also means struct initialization like ``__m128{ { 0.0f, 0.0f, 0.0f, 0.0f } }`` will not compile with clang. + +Since vector types are builtin types, clang implements operators on them natively. + +.. code-block:: c++ + + #ifdef _MSC_VER + __m128 operator+(__m128 a, __m128 b) { return _mm_add_ps(a, b); } + #endif + +The above code will fail to compile since overloaded 'operator+' must have at least one parameter of class or enumeration type. +You will need to fix such code to have the check ``#if defined(_MSC_VER) && !defined(__clang__)``. + +Since `__m128` is not a class type in clang any overloads after a template definition will not be considered. + +.. code-block:: c++ + + template + void foo(T) {} + + template + void bar(T t) { + foo(t); + } + + void foo(__m128) {} + + int main() { + bar(_mm_setzero_ps()); + } + +With MSVC ``foo(__m128)`` will be selected but with clang ``foo<__m128>()`` will be selected since on clang `__m128` is a builtin type. + +In general the takeaway is `__m128` is a builtin type on clang while a class type on MSVC. diff --git a/clang/docs/MemorySanitizer.rst b/clang/docs/MemorySanitizer.rst index bcc6cc808e8ba..05e43a32b9b87 100644 --- a/clang/docs/MemorySanitizer.rst +++ b/clang/docs/MemorySanitizer.rst @@ -8,11 +8,18 @@ MemorySanitizer Introduction ============ -MemorySanitizer is a detector of uninitialized reads. It consists of a +MemorySanitizer is a detector of uninitialized memory use. It consists of a compiler instrumentation module and a run-time library. Typical slowdown introduced by MemorySanitizer is **3x**. +Here is a not comprehensive of list cases when MemorySanitizer will report an error: + +* Uninitialized value was used in a conditional branch. +* Uninitialized pointer was used for memory accesses. +* Uninitialized value was passed or returned from a function call, which is considered an undefined behavior. The check can be disabled with ``-fno-sanitize-memory-param-retval``. +* Uninitialized data was passed into some libc calls. + How to build ============ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 1c1b874273a7c..866adefd5d3c4 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -37,135 +37,28 @@ These changes are ones which we think may surprise users when upgrading to Clang |release| because of the opportunity they pose for disruption to existing code bases. -- Setting the deprecated CMake variable ``GCC_INSTALL_PREFIX`` (which sets the - default ``--gcc-toolchain=``) now leads to a fatal error. - C/C++ Language Potentially Breaking Changes ------------------------------------------- -- Clang now supports raw string literals in ``-std=gnuXY`` mode as an extension in - C99 and later. This behaviour can also be overridden using ``-f[no-]raw-string-literals``. - Support of raw string literals in C++ is not affected. Fixes (#GH85703). - C++ Specific Potentially Breaking Changes ----------------------------------------- -- Clang now diagnoses function/variable templates that shadow their own template parameters, e.g. ``template void T();``. - This error can be disabled via `-Wno-strict-primary-template-shadow` for compatibility with previous versions of clang. - -- The behavior controlled by the `-frelaxed-template-template-args` flag is now - on by default, and the flag is deprecated. Until the flag is finally removed, - it's negative spelling can be used to obtain compatibility with previous - versions of clang. The deprecation warning for the negative spelling can be - disabled with `-Wno-deprecated-no-relaxed-template-template-args`. - -- Clang now rejects pointer to member from parenthesized expression in unevaluated context such as ``decltype(&(foo::bar))``. (#GH40906). - -- Clang now performs semantic analysis for unary operators with dependent operands - that are known to be of non-class non-enumeration type prior to instantiation. - - This change uncovered a bug in libstdc++ 14.1.0 which may cause compile failures - on systems using that version of libstdc++ and Clang 19, with an error that looks - something like this: - - .. code-block:: text - - :4:5: error: expression is not assignable - 4 | ++this; - | ^ ~~~~ - - To fix this, update libstdc++ to version 14.1.1 or greater. ABI Changes in This Version --------------------------- -- Fixed Microsoft name mangling of implicitly defined variables used for thread - safe static initialization of static local variables. This change resolves - incompatibilities with code compiled by MSVC but might introduce - incompatibilities with code compiled by earlier versions of Clang when an - inline member function that contains a static local variable with a dynamic - initializer is declared with ``__declspec(dllimport)``. (#GH83616). - -- Fixed Microsoft name mangling of lifetime extended temporary objects. This - change corrects missing back reference registrations that could result in - incorrect back reference indexes and suprising demangled name results. Since - MSVC uses a different mangling for these objects, compatibility is not affected. - (#GH85423). - -- Fixed Microsoft calling convention for returning certain classes with a - templated constructor. If a class has a templated constructor, it should - be returned indirectly even if it meets all the other requirements for - returning a class in a register. This affects some uses of std::pair. - (#GH86384). - -- Fixed Microsoft calling convention when returning classes that have a deleted - copy assignment operator. Such a class should be returned indirectly. - -- Removed the global alias that was pointing to AArch64 Function Multiversioning - ifuncs. Its purpose was to preserve backwards compatibility when the ".ifunc" - suffix got removed from the name mangling. The alias interacts badly with - GlobalOpt (see the issue #96197). - -- Fixed Microsoft name mangling for auto non-type template arguments of pointer - type for MSVC 1920+. This change resolves incompatibilities with code compiled - by MSVC 1920+ but will introduce incompatibilities with code compiled by - earlier versions of Clang unless such code is built with the compiler option - `-fms-compatibility-version=19.14` to imitate the MSVC 1914 mangling behavior. - -- Fixed Microsoft name mangling for auto non-type template arguments of pointer - to member type for MSVC 1920+. This change resolves incompatibilities with code - compiled by MSVC 1920+ but will introduce incompatibilities with code compiled by - earlier versions of Clang unless such code is built with the compiler option - `-fms-compatibility-version=19.14` to imitate the MSVC 1914 mangling behavior. - (GH#70899). AST Dumping Potentially Breaking Changes ---------------------------------------- -- The text ast-dumper has improved printing of TemplateArguments. -- The text decl-dumper prints template parameters' trailing requires expressions now. - Clang Frontend Potentially Breaking Changes ------------------------------------------- -- Removed support for constructing on-stack ``TemplateArgumentList``\ s; interfaces should instead - use ``ArrayRef`` to pass template arguments. Transitioning internal uses to - ``ArrayRef`` reduces AST memory usage by 0.4% when compiling clang, and is - expected to show similar improvements on other workloads. - -- The ``-Wgnu-binary-literal`` diagnostic group no longer controls any - diagnostics. Binary literals are no longer a GNU extension, they're now a C23 - extension which is controlled via ``-pedantic`` or ``-Wc23-extensions``. Use - of ``-Wno-gnu-binary-literal`` will no longer silence this pedantic warning, - which may break existing uses with ``-Werror``. - -- The normalization of 3 element target triples where ``-none-`` is the middle - element has changed. For example, ``armv7m-none-eabi`` previously normalized - to ``armv7m-none-unknown-eabi``, with ``none`` for the vendor and ``unknown`` - for the operating system. It now normalizes to ``armv7m-unknown-none-eabi``, - which has ``unknown`` vendor and ``none`` operating system. - - The affected triples are primarily for bare metal Arm where it is intended - that ``none`` means that there is no operating system. As opposed to an unknown - type of operating system. - - This change my cause clang to not find libraries, or libraries to be built at - different file system locations. This can be fixed by changing your builds to - use the new normalized triple. However, we recommend instead getting the - normalized triple from clang itself, as this will make your builds more - robust in case of future changes:: - - $ clang --target= -print-target-triple - - -- The ``hasTypeLoc`` AST matcher will no longer match a ``classTemplateSpecializationDecl``; - existing uses should switch to ``templateArgumentLoc`` or ``hasAnyTemplateArgumentLoc`` instead. Clang Python Bindings Potentially Breaking Changes -------------------------------------------------- -- Renamed ``CursorKind`` variant 272 from ``OMP_TEAMS_DISTRIBUTE_DIRECTIVE`` - to ``OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE``. The previous name was incorrect, it was a duplicate - of variant 271. -- Renamed ``TypeKind`` variant 162 from ``OBJCCLASS`` to ``OBJCTYPEPARAM``. - The previous name was incorrect, it was a duplicate of variant 28. -- Refactored enum implementation, switching to the standard library `Enum` type. +- Parts of the interface returning string results will now return + the empty string `""` when no result is available, instead of `None`. +- Calling a property on the `CompletionChunk` or `CompletionString` class + statically now leads to an error, instead of returning a `CachedProperty` object + that is used internally. Properties are only available on instances. What's New in Clang |release|? ============================== @@ -174,909 +67,126 @@ here. Generic improvements to Clang as a whole or to its underlying infrastructure are described first, followed by language-specific sections with improvements to Clang's support for those languages. -- The ``\par`` documentation comment command now supports an optional - argument, which denotes the header of the paragraph started by - an instance of the ``\par`` command comment. The implementation - of the argument handling matches its semantics - `in Doxygen `. - Namely, any text on the same line as the ``\par`` command will become - a header for the paragaph, and if there is no text then the command - will start a new paragraph. - C++ Language Changes -------------------- -- C++17 support is now completed, with the enablement of the - relaxed temlate template argument matching rules introduced in P0522, - which was retroactively applied as a defect report. - While the implementation already existed since Clang 4, it was turned off by - default, and was controlled with the `-frelaxed-template-template-args` flag. - In this release, we implement provisional wording for a core defect on - P0522 (CWG2398), which avoids the most serious compatibility issues caused - by it, allowing us to enable it by default in this release. - The flag is now deprecated, and will be removed in the next release, but can - still be used to turn it off and regain compatibility with previous versions - (#GH36505). -- Implemented ``_BitInt`` literal suffixes ``__wb`` or ``__WB`` as a Clang extension with ``unsigned`` modifiers also allowed. (#GH85223). C++17 Feature Support ^^^^^^^^^^^^^^^^^^^^^ -- Clang now exposes ``__GCC_DESTRUCTIVE_SIZE`` and ``__GCC_CONSTRUCTIVE_SIZE`` - predefined macros to support standard library implementations of - ``std::hardware_destructive_interference_size`` and - ``std::hardware_constructive_interference_size``, respectively. These macros - are predefined in all C and C++ language modes. The values the macros - expand to are not stable between releases of Clang and do not need to match - the values produced by GCC, so these macros should not be used from header - files because they may not be stable across multiple TUs (the values may vary - based on compiler version as well as CPU tuning). #GH60174 C++14 Feature Support ^^^^^^^^^^^^^^^^^^^^^ -- Sized deallocation is enabled by default in C++14 onwards. The user may specify - ``-fno-sized-deallocation`` to disable it if there are some regressions. C++20 Feature Support ^^^^^^^^^^^^^^^^^^^^^ -- Clang won't perform ODR checks for decls in the global module fragment any - more to ease the implementation and improve the user's using experience. - This follows the MSVC's behavior. Users interested in testing the more strict - behavior can use the flag '-Xclang -fno-skip-odr-check-in-gmf'. - (#GH79240). - -- Implemented the `__is_layout_compatible` and `__is_pointer_interconvertible_base_of` - intrinsics to support - `P0466R5: Layout-compatibility and Pointer-interconvertibility Traits `_. - -- Clang now implements [module.import]p7 fully. Clang now will import module - units transitively for the module units coming from the same module of the - current module units. Fixes #GH84002 - -- Initial support for class template argument deduction (CTAD) for type alias - templates (`P1814R0 `_). - (#GH54051). - -- We have sufficient confidence and experience with the concepts implementation - to update the ``__cpp_concepts`` macro to `202002L`. This enables - ```` from libstdc++ to work correctly with Clang. - -- User defined constructors are allowed for copy-list-initialization with CTAD. - (#GH62925). - C++23 Feature Support ^^^^^^^^^^^^^^^^^^^^^ - -- Implemented `P2718R0: Lifetime extension in range-based for loops `_. Also - materialize temporary object which is a prvalue in discarded-value expression. -- Implemented `P1774R8: Portable assumptions `_. - -- Implemented `P2448R2: Relaxing some constexpr restrictions `_. - Note, the ``-Winvalid-constexpr`` diagnostic is now disabled in C++23 mode, - but can be explicitly specified to retain the old diagnostic checking - behavior. - -- Added a ``__reference_converts_from_temporary`` builtin, completing the necessary compiler support for - `P2255R2: Type trait to determine if a reference binds to a temporary `_. - -- Implemented `P2797R0: Static and explicit object member functions with the same parameter-type-lists `_. - This completes the support for "deducing this". +- Removed the restriction to literal types in constexpr functions in C++23 mode. C++2c Feature Support ^^^^^^^^^^^^^^^^^^^^^ -- Implemented `P2662R3 Pack Indexing `_. - -- Implemented `P2573R2: = delete("should have a reason"); `_ - -- Implemented `P0609R3: Attributes for Structured Bindings `_ - -- Implemented `P2748R5 Disallow Binding a Returned Glvalue to a Temporary `_. - -- Implemented `P2809R3: Trivial infinite loops are not Undefined Behavior `_. - -- Implemented `P3144R2 Deleting a Pointer to an Incomplete Type Should be Ill-formed `_. - -- Implemented `P2963R3 Ordering of constraints involving fold expressions `_. - +- Add ``__builtin_is_virtual_base_of`` intrinsic, which supports + `P2985R0 A type trait for detecting virtual base classes `_ Resolutions to C++ Defect Reports ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Substitute template parameter pack, when it is not explicitly specified - in the template parameters, but is deduced from a previous argument. (#GH78449) - -- Type qualifications are now ignored when evaluating layout compatibility - of two types. - (`CWG1719: Layout compatibility and cv-qualification revisited `_). - -- Alignment of members is now respected when evaluating layout compatibility - of structs. - (`CWG2583: Common initial sequence should consider over-alignment `_). - -- ``[[no_unique_address]]`` is now respected when evaluating layout - compatibility of two types. - (`CWG2759: [[no_unique_address] and common initial sequence `_). - -- Clang now diagnoses declarative nested-name-specifiers with pack-index-specifiers. - (`CWG2858: Declarative nested-name-specifiers and pack-index-specifiers `_). - -- Clang now allows attributes on concepts. - (`CWG2428: Deprecating a concept `_). - -- P0522 implementation is enabled by default in all language versions, and - provisional wording for CWG2398 is implemented. - -- Clang now performs type-only lookup for the name in ``using enum`` declaration. - (`CWG2877: Type-only lookup for using-enum-declarator `_). - -- Clang now requires a template argument list after a template keyword. - (`CWG96: Syntactic disambiguation using the template keyword `_). - -- Clang now considers ``noexcept(typeid(expr))`` more carefully, instead of always assuming that ``std::bad_typeid`` can be thrown. - (`CWG2191: Incorrect result for noexcept(typeid(v)) `_). C Language Changes ------------------ C2y Feature Support ^^^^^^^^^^^^^^^^^^^ -- Clang now enables C2y mode with ``-std=c2y``. This sets ``__STDC_VERSION__`` - to ``202400L`` so that it's greater than the value for C23. The value of this - macro is subject to change in the future. C23 Feature Support ^^^^^^^^^^^^^^^^^^^ -- No longer diagnose use of binary literals as an extension in C23 mode. Fixes - #GH72017. - -- Corrected parsing behavior for the ``alignas`` specifier/qualifier in C23. We - previously handled it as an attribute as in C++, but there are parsing - differences. The behavioral differences are: - - .. code-block:: c - - struct alignas(8) /* was accepted, now rejected */ S { - char alignas(8) /* was rejected, now accepted */ C; - }; - int i alignas(8) /* was accepted, now rejected */ ; - - Fixes (#GH81472). - -- Clang now generates predefined macros of the form ``__TYPE_FMTB__`` and - ``__TYPE_FMTb__`` (e.g., ``__UINT_FAST64_FMTB__``) in C23 mode for use with - macros typically exposed from ````, such as ``PRIb8``. (#GH81896) - -- Clang now supports `N3018 The constexpr specifier for object definitions` - `_. - -- Properly promote bit-fields of bit-precise integer types to the field's type - rather than to ``int``. #GH87641 - -- Added the ``INFINITY`` and ``NAN`` macros to Clang's ```` - freestanding implementation; these macros were defined in ```` in C99 - but C23 added them to ```` in - `WG14 N2848 `_. - -- Clang now supports `N3017 `_ - ``#embed`` - a scannable, tooling-friendly binary resource inclusion mechanism. - -- Added the ``FLT_NORM_MAX``, ``DBL_NORM_MAX``, and ``LDBL_NORM_MAX`` to the - freestanding implementation of ```` that ships with Clang. - -- Compiler support for `N2653 char8_t: A type for UTF-8 characters and strings` - `_: ``u8`` string - literals are now of type ``char8_t[N]`` in C23 and expose - ``__CLANG_ATOMIC_CHAR8_T_LOCK_FREE``/``__GCC_ATOMIC_CHAR8_T_LOCK_FREE`` to - implement the corresponding macro in ````. - -Non-comprehensive list of changes in this release -------------------------------------------------- - -- Added ``__builtin_readsteadycounter`` for reading fixed frequency hardware - counters. - -- ``__builtin_addc``, ``__builtin_subc``, and the other sizes of those - builtins are now constexpr and may be used in constant expressions. - -- Added ``__builtin_popcountg`` as a type-generic alternative to - ``__builtin_popcount{,l,ll}`` with support for any unsigned integer type. Like - the previous builtins, this new builtin is constexpr and may be used in - constant expressions. - -- Lambda expressions are now accepted in C++03 mode as an extension. - -- Added ``__builtin_clzg`` and ``__builtin_ctzg`` as type-generic alternatives - to ``__builtin_clz{,s,l,ll}`` and ``__builtin_ctz{,s,l,ll}`` respectively, - with support for any unsigned integer type. Like the previous builtins, these - new builtins are constexpr and may be used in constant expressions. - -- ``__typeof_unqual__`` is available in all C modes as an extension, which behaves - like ``typeof_unqual`` from C23, similar to ``__typeof__`` and ``typeof``. - -- ``__builtin_reduce_{add|mul|xor|or|and|min|max}`` builtins now support scalable vectors. - -* Shared libraries linked with either the ``-ffast-math``, ``-Ofast``, or - ``-funsafe-math-optimizations`` flags will no longer enable flush-to-zero - floating-point mode by default. This decision can be overridden with use of - ``-mdaz-ftz``. This behavior now matches GCC's behavior. - (`#57589 `_) - -* ``-fdenormal-fp-math=preserve-sign`` is no longer implied by ``-ffast-math`` - on x86 systems. - -- Builtins ``__builtin_shufflevector()`` and ``__builtin_convertvector()`` may - now be used within constant expressions. - -- When compiling a constexpr function, Clang will check to see whether the - function can *never* be used in a constant expression context and issues a - diagnostic under the ``-Winvalid-constexpr`` diagostic flag (which defaults - to an error). This check can be expensive because the mere presence of a - function marked ``constexpr`` will cause us to undergo constant expression - evaluation, even if the function is not called within the translation unit - being compiled. Due to the expense, Clang no longer checks constexpr function - bodies when the function is defined in a system header file or when - ``-Winvalid-constexpr`` is not enabled for the function definition, which - should result in mild compile-time performance improvements. - -- Added ``__is_bitwise_cloneable`` which is used to check whether a type - can be safely copied by memcpy/memmove. - -- ``#pragma GCC diagnostic warning "-Wfoo"`` can now downgrade ``-Werror=foo`` - errors and certain default-to-error ``-W`` diagnostics to warnings. - -- Support importing C++20 modules in clang-repl. - -- Added support for ``TypeLoc::dump()`` for easier debugging, and improved - textual and JSON dumping for various ``TypeLoc``-related nodes. New Compiler Flags ------------------ -- ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and - sign change. -- ``-fsanitize=implicit-integer-conversion`` a group that replaces the previous - group ``-fsanitize=implicit-conversion``. - -- ``-Wmissing-designated-field-initializers``, grouped under ``-Wmissing-field-initializers``. - This diagnostic can be disabled to make ``-Wmissing-field-initializers`` behave - like it did before Clang 18.x. Fixes #GH56628 - -- ``-fexperimental-modules-reduced-bmi`` enables the Reduced BMI for C++20 named modules. - See the document of standard C++ modules for details. - -- ``-fexperimental-late-parse-attributes`` enables an experimental feature to - allow late parsing certain attributes in specific contexts where they would - not normally be late parsed. Currently this allows late parsing the - `counted_by` attribute in C. See `Attribute Changes in Clang`_. - -- ``-fseparate-named-sections`` uses separate unique sections for global - symbols in named special sections (i.e. symbols annotated with - ``__attribute__((section(...)))``. This enables linker GC to collect unused - symbols without having to use a per-symbol section. - -- ``-fms-define-stdc`` and its clang-cl counterpart ``/Zc:__STDC__``. - Matches MSVC behaviour by defining ``__STDC__`` to ``1`` when - MSVC compatibility mode is used. It has no effect for C++ code. - -- ``-Wc++23-compat`` group was added to help migrating existing codebases - to C++23. - -- ``-Wc++2c-compat`` group was added to help migrating existing codebases - to upcoming C++26. - -- ``-fdisable-block-signature-string`` instructs clang not to emit the signature - string for blocks. Disabling the string can potentially break existing code - that relies on it. Users should carefully consider this possibiilty when using - the flag. - -- For the ARM target, added ``-Warm-interrupt-vfp-clobber`` that will emit a - diagnostic when an interrupt handler is declared and VFP is enabled. Deprecated Compiler Flags ------------------------- Modified Compiler Flags ----------------------- -- Added a new diagnostic flag ``-Wreturn-mismatch`` which is grouped under - ``-Wreturn-type``, and moved some of the diagnostics previously controlled by - ``-Wreturn-type`` under this new flag. Fixes #GH72116. -- ``-fsanitize=implicit-conversion`` is now a group for both - ``-fsanitize=implicit-integer-conversion`` and - ``-fsanitize=implicit-bitfield-conversion``. - -- Added ``-Wcast-function-type-mismatch`` under the ``-Wcast-function-type`` - warning group. Moved the diagnostic previously controlled by - ``-Wcast-function-type`` to the new warning group and added - ``-Wcast-function-type-mismatch`` to ``-Wextra``. #GH76872 - - .. code-block:: c - - int x(long); - typedef int (f2)(void*); - typedef int (f3)(); - - void func(void) { - // Diagnoses under -Wcast-function-type, -Wcast-function-type-mismatch, - // -Wcast-function-type-strict, -Wextra - f2 *b = (f2 *)x; - // Diagnoses under -Wcast-function-type, -Wcast-function-type-strict - f3 *c = (f3 *)x; - } - -- Carved out ``-Wformat`` warning about scoped enums into a subwarning and - make it controlled by ``-Wformat-pedantic``. Fixes #GH88595. - -- Trivial infinite loops (i.e loops with a constant controlling expresion - evaluating to ``true`` and an empty body such as ``while(1);``) - are considered infinite, even when the ``-ffinite-loop`` flag is set. - -- Diagnostics groups about compatibility with a particular C++ Standard version - now include dianostics about C++26 features that are not present in older - versions. - -- Removed the "arm interrupt calling convention" warning that was included in - ``-Wextra`` without its own flag. This warning suggested adding - ``__attribute__((interrupt))`` to functions that are called from interrupt - handlers to prevent clobbering VFP registers. Following this suggestion leads - to unpredictable behavior by causing multiple exception returns from one - exception. Fixes #GH34876. Removed Compiler Flags ------------------------- -- The ``-freroll-loops`` flag has been removed. It had no effect since Clang 13. -- ``-m[no-]unaligned-access`` is removed for RISC-V and LoongArch. - ``-m[no-]strict-align``, also supported by GCC, should be used instead. (#GH85350) - Attribute Changes in Clang -------------------------- -- Introduced a new function attribute ``__attribute__((amdgpu_max_num_work_groups(x, y, z)))`` or - ``[[clang::amdgpu_max_num_work_groups(x, y, z)]]`` for the AMDGPU target. This attribute can be - attached to HIP or OpenCL kernel function definitions to provide an optimization hint. The parameters - ``x``, ``y``, and ``z`` specify the maximum number of workgroups for the respective dimensions, - and each must be a positive integer when provided. The parameter ``x`` is required, while ``y`` and - ``z`` are optional with default value of 1. - -- The ``swiftasynccc`` attribute is now considered to be a Clang extension - rather than a language standard feature. Please use - ``__has_extension(swiftasynccc)`` to check the availability of this attribute - for the target platform instead of ``__has_feature(swiftasynccc)``. Also, - added a new extension query ``__has_extension(swiftcc)`` corresponding to the - ``__attribute__((swiftcc))`` attribute. - -- The ``_Nullable`` and ``_Nonnull`` family of type attributes can now apply - to certain C++ class types, such as smart pointers: - ``void useObject(std::unique_ptr _Nonnull obj);``. - - This works for standard library types including ``unique_ptr``, ``shared_ptr``, - and ``function``. See - `the attribute reference documentation `_ - for the full list. - -- The ``_Nullable`` attribute can be applied to C++ class declarations: - ``template class _Nullable MySmartPointer {};``. - - This allows the ``_Nullable`` and ``_Nonnull`` family of type attributes to - apply to this class. - -- Clang now warns that the ``exclude_from_explicit_instantiation`` attribute - is ignored when applied to a local class or a member thereof. - -- The ``clspv_libclc_builtin`` attribute has been added to allow clspv - (`OpenCL-C to Vulkan SPIR-V compiler `_) to identify functions coming from libclc - (`OpenCL-C builtin library `_). -- The ``counted_by`` attribute is now allowed on pointers that are members of a - struct in C. - -- The ``counted_by`` attribute can now be late parsed in C when - ``-fexperimental-late-parse-attributes`` is passed but only when attribute is - used in the declaration attribute position. This allows using the - attribute on existing code where it previously impossible to do so without - re-ordering struct field declarations would break ABI as shown below. - - .. code-block:: c - - struct BufferTy { - /* Refering to `count` requires late parsing */ - char* buffer __counted_by(count); - /* Swapping `buffer` and `count` to avoid late parsing would break ABI */ - size_t count; - }; - -- The attributes ``sized_by``, ``counted_by_or_null`` and ``sized_by_or_null``` - have been added as variants on ``counted_by``, each with slightly different semantics. - ``sized_by`` takes a byte size parameter instead of an element count, allowing pointees - with unknown size. The ``counted_by_or_null`` and ``sized_by_or_null`` variants are equivalent - to their base variants, except the pointer can be null regardless of count/size value. - If the pointer is null the size is effectively 0. ``sized_by_or_null`` is needed to properly - annotate allocator functions like ``malloc`` that return a buffer of a given byte size, but can - also return null. - -- The ``guarded_by``, ``pt_guarded_by``, ``acquired_after``, ``acquired_before`` - attributes now support referencing struct members in C. The arguments are also - now late parsed when ``-fexperimental-late-parse-attributes`` is passed like - for ``counted_by``. - -- Introduced new function type attributes ``[[clang::nonblocking]]``, ``[[clang::nonallocating]]``, - ``[[clang::blocking]]``, and ``[[clang::allocating]]``, with GNU-style variants as well. - The attributes declare constraints about a function's behavior pertaining to blocking and - heap memory allocation. - -Improvements to Clang's diagnostics ------------------------------------ -- Clang now emits an error instead of a warning for ``-Wundefined-internal`` - when compiling with `-pedantic-errors` to conform to the C standard - -- Clang now applies syntax highlighting to the code snippets it - prints. - -- Clang now diagnoses member template declarations with multiple declarators. - -- Clang now diagnoses use of the ``template`` keyword after declarative nested - name specifiers. - -- The ``-Wshorten-64-to-32`` diagnostic is now grouped under ``-Wimplicit-int-conversion`` instead - of ``-Wconversion``. Fixes #GH69444. - -- Clang now uses thousand separators when printing large numbers in integer overflow diagnostics. - Fixes #GH80939. -- Clang now diagnoses friend declarations with an ``enum`` elaborated-type-specifier in language modes after C++98. +- Clang now disallows more than one ``__attribute__((ownership_returns(class, idx)))`` with + different class names attached to one function. -- Added diagnostics for C11 keywords being incompatible with language standards - before C11, under a new warning group: ``-Wpre-c11-compat``. +- Introduced a new format attribute ``__attribute__((format(syslog, 1, 2)))`` from OpenBSD. -- Now diagnoses an enumeration constant whose value is larger than can be - represented by ``unsigned long long``, which can happen with a large constant - using the ``wb`` or ``uwb`` suffix. The maximal underlying type is currently - ``unsigned long long``, but this behavior may change in the future when Clang - implements - `WG14 N3029 `_. - (#GH69352). +- The ``hybrid_patchable`` attribute is now supported on ARM64EC targets. It can be used to specify + that a function requires an additional x86-64 thunk, which may be patched at runtime. -- Clang now diagnoses extraneous template parameter lists as a language extension. - -- Clang now diagnoses declarative nested name specifiers that name alias templates. - -- Clang now diagnoses lambda function expressions being implicitly cast to boolean values, under ``-Wpointer-bool-conversion``. - Fixes #GH82512. - -- Clang now provides improved warnings for the ``cleanup`` attribute to detect misuse scenarios, - such as attempting to call ``free`` on an unallocated object. Fixes #GH79443. - -- Clang no longer warns when the ``bitand`` operator is used with boolean - operands, distinguishing it from potential typographical errors or unintended - bitwise operations. Fixes #GH77601. - -- Clang now correctly diagnoses no arguments to a variadic macro parameter as a C23/C++20 extension. - Fixes #GH84495. - -- Clang no longer emits a ``-Wexit-time destructors`` warning on static variables explicitly - annotated with the ``clang::always_destroy`` attribute. - Fixes #GH68686, #GH86486 - -- ``-Wmicrosoft``, ``-Wgnu``, or ``-pedantic`` is now required to diagnose C99 - flexible array members in a union or alone in a struct. Fixes GH#84565. - -- Clang now no longer diagnoses type definitions in ``offsetof`` in C23 mode. - Fixes #GH83658. - -- New ``-Wformat-signedness`` diagnostic that warn if the format string requires an - unsigned argument and the argument is signed and vice versa. - -- Clang now emits ``unused argument`` warning when the -fmodule-output flag is used - with an input that is not of type c++-module. - -- Clang emits a ``-Wreturn-stack-address`` warning if a function returns a pointer or - reference to a struct literal. Fixes #GH8678 - -- Clang emits a ``-Wunused-but-set-variable`` warning on C++ variables whose declaration - (with initializer) entirely consist the condition expression of a if/while/for construct - but are not actually used in the body of the if/while/for construct. Fixes #GH41447 - -- Clang emits a diagnostic when a tentative array definition is assumed to have - a single element, but that diagnostic was never given a diagnostic group. - Added the ``-Wtentative-definition-array`` warning group to cover this. - Fixes #GH87766 - -- Clang now uses the correct type-parameter-key (``class`` or ``typename``) when printing - template template parameter declarations. - -- Clang now diagnoses requires expressions with explicit object parameters. +Improvements to Clang's diagnostics +----------------------------------- -- Clang now looks up members of the current instantiation in the template definition context - if the current instantiation has no dependent base classes. +- Some template related diagnostics have been improved. .. code-block:: c++ - template - struct A { - int f() { - return this->x; // error: no member named 'x' in 'A' - } - }; - -- Clang emits a ``-Wparentheses`` warning for expressions with consecutive comparisons like ``x < y < z``. - Fixes #GH20456. - -- Clang no longer emits a "declared here" note for a builtin function that has no declaration in source. - Fixes #GH93369. - -- Clang now has an improved error message for captures that refer to a class member. - Fixes #GH94764. + void foo() { template int i; } // error: templates can only be declared in namespace or class scope -- Clang now diagnoses unsupported class declarations for ``std::initializer_list`` when they are - used rather than when they are needed for constant evaluation or when code is generated for them. - The check is now stricter to prevent crashes for some unsupported declarations (Fixes #GH95495). - -- Clang now diagnoses dangling cases where a pointer is assigned to a temporary - that will be destroyed at the end of the full expression. - Fixes #GH54492. + struct S { + template int i; // error: non-static data member 'i' cannot be declared as a template + }; -- Clang now shows implicit deduction guides when diagnosing overload resolution failure. #GH92393. +- Clang now has improved diagnostics for functions with explicit 'this' parameters. Fixes #GH97878 -- Clang no longer emits a "no previous prototype" warning for Win32 entry points under ``-Wmissing-prototypes``. - Fixes #GH94366. +- Clang now diagnoses dangling references to fields of temporary objects. Fixes #GH81589. -- For the ARM target, calling an interrupt handler from another function is now an error. #GH95359. +- Clang now diagnoses undefined behavior in constant expressions more consistently. This includes invalid shifts, and signed overflow in arithmetic. -- Clang now diagnoses integer constant expressions that are folded to a constant value as an extension in more circumstances. Fixes #GH59863 +- -Wdangling-assignment-gsl is enabled by default. Improvements to Clang's time-trace ---------------------------------- -- Clang now specifies that using ``auto`` in a lambda parameter is a C++14 extension when - appropriate. (`#46059: `_). - Improvements to Coverage Mapping -------------------------------- -- Macros defined in system headers are not expanded in coverage - mapping. Conditional expressions in system header macros are no - longer taken into account for branch coverage. They can be included - with ``-mllvm -system-headers-coverage``. - (`#78920: `_) -- MC/DC Coverage has been improved. - (`#82448: `_) - - - The maximum number of conditions is no longer limited to 6. See - `this ` for - more details. - Bug Fixes in This Version ------------------------- -- Clang's ``-Wundefined-func-template`` no longer warns on pure virtual - functions. (#GH74016) - -- Fixed missing warnings when comparing mismatched enumeration constants - in C (#GH29217) - -- Clang now accepts elaborated-type-specifiers that explicitly specialize - a member class template for an implicit instantiation of a class template. - -- Fixed missing warnings when doing bool-like conversions in C23 (#GH79435). -- Clang's ``-Wshadow`` no longer warns when an init-capture is named the same as - a class field unless the lambda can capture this. - Fixes (#GH71976) - -- Clang now accepts qualified partial/explicit specializations of variable templates that - are not nominable in the lookup context of the specialization. - -- Clang now doesn't produce false-positive warning `-Wconstant-logical-operand` - for logical operators in C23. - Fixes (#GH64356). - -- ``__is_trivially_relocatable`` no longer returns ``false`` for volatile-qualified types. - Fixes (#GH77091). - -- Clang no longer produces a false-positive `-Wunused-variable` warning - for variables created through copy initialization having side-effects in C++17 and later. - Fixes (#GH64356) (#GH79518). - -- Fix value of predefined macro ``__FUNCTION__`` in MSVC compatibility mode. - Fixes (#GH66114). - -- Clang now emits errors for explicit specializations/instatiations of lambda call - operator. - Fixes (#GH83267). - -- Fix crash on ill-formed partial specialization with CRTP. - Fixes (#GH89374). - -- Clang now correctly generates overloads for bit-precise integer types for - builtin operators in C++. Fixes #GH82998. - -- Fix crash when destructor definition is preceded with an equals sign. - Fixes (#GH89544). - -- When performing mixed arithmetic between ``_Complex`` floating-point types and integers, - Clang now correctly promotes the integer to its corresponding real floating-point - type only rather than to the complex type (e.g. ``_Complex float / int`` is now evaluated - as ``_Complex float / float`` rather than ``_Complex float / _Complex float``), as mandated - by the C standard. This significantly improves codegen of `*` and `/` especially. - Fixes #GH31205. - -- Fixes an assertion failure on invalid code when trying to define member - functions in lambdas. - -- Fixed a regression in CTAD that a friend declaration that befriends itself may cause - incorrect constraint substitution. (#GH86769). - -- Fixed an assertion failure on invalid InitListExpr in C89 mode (#GH88008). -- Fixed missing destructor calls when we branch from middle of an expression. - This could happen through a branch in stmt-expr or in an expression containing a coroutine - suspension. Fixes (#GH63818) (#GH88478). - -- Clang will no longer diagnose an erroneous non-dependent ``switch`` condition - during instantiation, and instead will only diagnose it once, during checking - of the function template. - -- Clang now allows the value of unroll count to be zero in ``#pragma GCC unroll`` and ``#pragma unroll``. - The values of 0 and 1 block any unrolling of the loop. This keeps the same behavior with GCC. - Fixes (`#88624 `_). - -- Clang will no longer emit a duplicate -Wunused-value warning for an expression - `(A, B)` which evaluates to glvalue `B` that can be converted to non ODR-use. (#GH45783) - -- Clang now correctly disallows VLA type compound literals, e.g. ``(int[size]){}``, - as the C standard mandates. (#GH89835) - -- ``__is_array`` and ``__is_bounded_array`` no longer return ``true`` for - zero-sized arrays. Fixes (#GH54705). - -- Correctly reject declarations where a statement is required in C. - Fixes #GH92775 - -- Fixed `static_cast` to array of unknown bound. Fixes (#GH62863). - -- Fixed Clang crashing when failing to perform some C++ Initialization Sequences. (#GH98102) - -- ``__is_trivially_equality_comparable`` no longer returns true for types which - have a constrained defaulted comparison operator (#GH89293). - -- Fixed Clang from generating dangling StringRefs when deserializing Exprs & Stmts (#GH98667) - -- ``__has_unique_object_representations`` correctly handles arrays of unknown bounds of - types by ensuring they are complete and instantiating them if needed. Fixes (#GH95311). - -- ``typeof_unqual`` now properly removes type qualifiers from arrays and their element types. (#GH92667) +- Fixed the definition of ``ATOMIC_FLAG_INIT`` in ```` so it can + be used in C++. Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Fix crash when atomic builtins are called with pointer to zero-size struct (#GH90330) - -- Clang now allows pointee types of atomic builtin arguments to be complete template types - that was not instantiated elsewhere. - Bug Fixes to Attribute Support ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Bug Fixes to C++ Support ^^^^^^^^^^^^^^^^^^^^^^^^ -- Fix crash when calling the constructor of an invalid class. - (#GH10518) (#GH67914) (#GH78388) -- Fix crash when using lifetimebound attribute in function with trailing return. - (#GH73619) -- Addressed an issue where constraints involving injected class types are perceived - distinct from its specialization types. (#GH56482) -- Fixed a bug where variables referenced by requires-clauses inside - nested generic lambdas were not properly injected into the constraint scope. (#GH73418) -- Fixed a crash where substituting into a requires-expression that refers to function - parameters during the equivalence determination of two constraint expressions. - (#GH74447) -- Fixed deducing auto& from const int in template parameters of partial - specializations. (#GH77189) -- Fix for crash when using a erroneous type in a return statement. - (#GH63244) (#GH79745) -- Fixed an out-of-bounds error caused by building a recovery expression for ill-formed - function calls while substituting into constraints. (#GH58548) -- Fix incorrect code generation caused by the object argument - of ``static operator()`` and ``static operator[]`` calls not being evaluated. (#GH67976) -- Fix crash and diagnostic with const qualified member operator new. - Fixes (#GH79748) -- Fixed a crash where substituting into a requires-expression that involves parameter packs - during the equivalence determination of two constraint expressions. (#GH72557) -- Fix a crash when specializing an out-of-line member function with a default - parameter where we did an incorrect specialization of the initialization of - the default parameter. (#GH68490) -- Fix a crash when trying to call a varargs function that also has an explicit object parameter. - Fixes (#GH80971) -- Reject explicit object parameters on `new` and `delete` operators. (#GH82249) -- Fix a crash when trying to call a varargs function that also has an explicit object parameter. (#GH80971) -- Fixed a bug where abbreviated function templates would append their invented template parameters to - an empty template parameter lists. -- Fix parsing of abominable function types inside type traits. Fixes #GH77585 -- Clang now classifies aggregate initialization in C++17 and newer as constant - or non-constant more accurately. Previously, only a subset of the initializer - elements were considered, misclassifying some initializers as constant. Partially fixes - #GH80510. -- Clang now ignores top-level cv-qualifiers on function parameters in template partial orderings. (#GH75404) -- No longer reject valid use of the ``_Alignas`` specifier when declaring a - local variable, which is supported as a C11 extension in C++. Previously, it - was only accepted at namespace scope but not at local function scope. -- Clang no longer tries to call consteval constructors at runtime when they appear in a member initializer. (#GH82154) -- Fix crash when using an immediate-escalated function at global scope. (#GH82258) -- Correctly immediate-escalate lambda conversion functions. (#GH82258) -- Fixed an issue where template parameters of a nested abbreviated generic lambda within - a requires-clause lie at the same depth as those of the surrounding lambda. This, - in turn, results in the wrong template argument substitution during constraint checking. - (#GH78524) -- Clang no longer instantiates the exception specification of discarded candidate function - templates when determining the primary template of an explicit specialization. -- Fixed a crash in Microsoft compatibility mode where unqualified dependent base class - lookup searches the bases of an incomplete class. -- Fix a crash when an unresolved overload set is encountered on the RHS of a ``.*`` operator. - (#GH53815) -- In ``__restrict``-qualified member functions, attach ``__restrict`` to the pointer type of - ``this`` rather than the pointee type. - Fixes (#GH82941), (#GH42411) and (#GH18121). -- Clang now properly reports supported C++11 attributes when using - ``__has_cpp_attribute`` and parses attributes with arguments in C++03 (#GH82995) -- Clang now properly diagnoses missing 'default' template arguments on a variety - of templates. Previously we were diagnosing on any non-function template - instead of only on class, alias, and variable templates, as last updated by - CWG2032. Fixes (#GH83461) -- Fixed an issue where an attribute on a declarator would cause the attribute to - be destructed prematurely. This fixes a pair of Chromium that were brought to - our attention by an attempt to fix in (#GH77703). Fixes (#GH83385). -- Fix evaluation of some immediate calls in default arguments. - Fixes (#GH80630) -- Fixed an issue where the ``RequiresExprBody`` was involved in the lambda dependency - calculation. (#GH56556), (#GH82849). -- Fix a bug where overload resolution falsely reported an ambiguity when it was comparing - a member-function against a non member function or a member-function with an - explicit object parameter against a member function with no explicit object parameter - when one of the function had more specialized templates. Fixes #GH82509 and #GH74494 -- Clang now supports direct lambda calls inside of a type alias template declarations. - This addresses (#GH70601), (#GH76674), (#GH79555), (#GH81145) and (#GH82104). -- Allow access to a public template alias declaration that refers to friend's - private nested type. (#GH25708). -- Fixed a crash in constant evaluation when trying to access a - captured ``this`` pointer in a lambda with an explicit object parameter. - Fixes (#GH80997) -- Fix an issue where missing set friend declaration in template class instantiation. - Fixes (#GH84368). -- Fixed a crash while checking constraints of a trailing requires-expression of a lambda, that the - expression references to an entity declared outside of the lambda. (#GH64808) -- Clang's __builtin_bit_cast will now produce a constant value for records with empty bases. See: - (#GH82383) -- Fix a crash when instantiating a lambda that captures ``this`` outside of its context. Fixes (#GH85343). -- Fix an issue where a namespace alias could be defined using a qualified name (all name components - following the first `::` were ignored). -- Fix an out-of-bounds crash when checking the validity of template partial specializations. (part of #GH86757). -- Fix an issue caused by not handling invalid cases when substituting into the parameter mapping of a constraint. Fixes (#GH86757). -- Fixed a bug that prevented member function templates of class templates declared with a deduced return type - from being explicitly specialized for a given implicit instantiation of the class template. -- Fixed a crash when ``this`` is used in a dependent class scope function template specialization - that instantiates to a static member function. -- Fix crash when inheriting from a cv-qualified type. Fixes #GH35603 -- Fix a crash when the using enum declaration uses an anonymous enumeration. Fixes (#GH86790). -- Handled an edge case in ``getFullyPackExpandedSize`` so that we now avoid a false-positive diagnostic. (#GH84220) -- Clang now correctly tracks type dependence of by-value captures in lambdas with an explicit - object parameter. - Fixes (#GH70604), (#GH79754), (#GH84163), (#GH84425), (#GH86054), (#GH86398), and (#GH86399). -- Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329). -- Fix a crash in requires expression with templated base class member function. Fixes (#GH84020). -- Fix a crash caused by defined struct in a type alias template when the structure - has fields with dependent type. Fixes (#GH75221). -- Fix the Itanium mangling of lambdas defined in a member of a local class (#GH88906) -- Fixed a crash when trying to evaluate a user-defined ``static_assert`` message whose ``size()`` - function returns a large or negative value. Fixes (#GH89407). -- Fixed a use-after-free bug in parsing of type constraints with default arguments that involve lambdas. (#GH67235) -- Fixed bug in which the body of a consteval lambda within a template was not parsed as within an - immediate function context. -- Fix CTAD for ``std::initializer_list``. This allows ``std::initializer_list{1, 2, 3}`` to be deduced as - ``std::initializer_list`` as intended. -- Fix a bug on template partial specialization whose template parameter is `decltype(auto)`. -- Fix a bug on template partial specialization with issue on deduction of nontype template parameter - whose type is `decltype(auto)`. Fixes (#GH68885). -- Clang now correctly treats the noexcept-specifier of a friend function to be a complete-class context. -- Fix an assertion failure when parsing an invalid members of an anonymous class. (#GH85447) -- Fixed a misuse of ``UnresolvedLookupExpr`` for ill-formed templated expressions. Fixes (#GH48673), (#GH63243) - and (#GH88832). -- Clang now defers all substitution into the exception specification of a function template specialization - until the noexcept-specifier is instantiated. -- Fix a crash when an implicitly declared ``operator==`` function with a trailing requires-clause has its - constraints compared to that of another declaration. -- Fix a bug where explicit specializations of member functions/function templates would have substitution - performed incorrectly when checking constraints. Fixes (#GH90349). -- Clang now allows constrained member functions to be explicitly specialized for an implicit instantiation - of a class template. -- Fix a C++23 bug in implementation of P2564R3 which evaluates immediate invocations in place - within initializers for variables that are usable in constant expressions or are constant - initialized, rather than evaluating them as a part of the larger manifestly constant evaluated - expression. -- Fix a bug in access control checking due to dealyed checking of friend declaration. Fixes (#GH12361). -- Correctly treat the compound statement of an ``if consteval`` as an immediate context. Fixes (#GH91509). -- When partial ordering alias templates against template template parameters, - allow pack expansions when the alias has a fixed-size parameter list. Fixes (#GH62529). -- Clang now ignores template parameters only used within the exception specification of candidate function - templates during partial ordering when deducing template arguments from a function declaration or when - taking the address of a function template. -- Fix a bug with checking constrained non-type template parameters for equivalence. Fixes (#GH77377). -- Fix a bug where the last argument was not considered when considering the most viable function for - explicit object argument member functions. Fixes (#GH92188). -- Fix a C++11 crash when a non-const non-static member function is defined out-of-line with - the ``constexpr`` specifier. Fixes (#GH61004). -- Clang no longer transforms dependent qualified names into implicit class member access expressions - until it can be determined whether the name is that of a non-static member. -- Clang now correctly diagnoses when the current instantiation is used as an incomplete base class. -- Clang no longer treats ``constexpr`` class scope function template specializations of non-static members - as implicitly ``const`` in language modes after C++11. -- Fixed a crash when trying to emit captures in a lambda call operator with an explicit object - parameter that is called on a derived type of the lambda. - Fixes (#GH87210), (GH89541). -- Clang no longer tries to check if an expression is immediate-escalating in an unevaluated context. - Fixes (#GH91308). -- Fix a crash caused by a regression in the handling of ``source_location`` - in dependent contexts. Fixes (#GH92680). -- Fixed a crash when diagnosing failed conversions involving template parameter - packs. (#GH93076) -- Fixed a regression introduced in Clang 18 causing a static function overloading a non-static function - with the same parameters not to be diagnosed. (Fixes #GH93456). -- Clang now diagnoses unexpanded parameter packs in attributes. (Fixes #GH93269). -- Clang now allows ``@$``` in raw string literals. Fixes (#GH93130). -- Fix an assertion failure when checking invalid ``this`` usage in the wrong context. (Fixes #GH91536). -- Clang no longer models dependent NTTP arguments as ``TemplateParamObjectDecl`` s. Fixes (#GH84052). -- Fix incorrect merging of modules which contain using declarations which shadow - other declarations. This could manifest as ODR checker false positives. - Fixes (`#80252 `_) -- Fix a regression introduced in Clang 18 causing incorrect overload resolution in the presence of functions only - differering by their constraints when only one of these function was variadic. -- Fix a crash when a variable is captured by a block nested inside a lambda. (Fixes #GH93625). -- Fixed a type constraint substitution issue involving a generic lambda expression. (#GH93821) -- Fix a crash caused by improper use of ``__array_extent``. (#GH80474) -- Fixed several bugs in capturing variables within unevaluated contexts. (#GH63845), (#GH67260), (#GH69307), - (#GH88081), (#GH89496), (#GH90669), (#GH91633) and (#GH97453). -- Fixed a crash in constraint instantiation under nested lambdas with dependent parameters. -- Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368). -- Fixed a failed assertion when attempting to convert an integer representing the difference - between the addresses of two labels (a GNU extension) to a pointer within a constant expression. (#GH95366). -- Fix immediate escalation bugs in the presence of dependent call arguments. (#GH94935) -- Clang now diagnoses explicit specializations with storage class specifiers in all contexts. -- Fix an assertion failure caused by parsing a lambda used as a default argument for the value of a - forward-declared class. (#GH93512). -- Fixed a bug in access checking inside return-type-requirement of compound requirements. (#GH93788). -- Fixed an assertion failure about invalid conversion when calling lambda. (#GH96205). -- Fixed a bug where the first operand of binary ``operator&`` would be transformed as if it was the operand - of the address of operator. (#GH97483). -- Fixed an assertion failure about a constant expression which is a known integer but is not - evaluated to an integer. (#GH96670). -- Fixed a bug where references to lambda capture inside a ``noexcept`` specifier were not correctly - instantiated. (#GH95735). -- Fixed a CTAD substitution bug involving type aliases that reference outer template parameters. (#GH94614). -- Clang now correctly handles unexpanded packs in the template parameter list of a generic lambda expression - (#GH48937) -- Fix a crash when parsing an invalid type-requirement in a requires expression. (#GH51868) -- Fix parsing of built-in type-traits such as ``__is_pointer`` in libstdc++ headers. (#GH95598) -- Fixed failed assertion when resolving context of defaulted comparison method outside of struct. (#GH96043). -- Clang now diagnoses explicit object parameters in member pointers and other contexts where they should not appear. - Fixes (#GH85992). -- Fixed a crash-on-invalid bug involving extraneous template parameter with concept substitution. (#GH73885) +- Fixed a crash when an expression with a dependent ``__typeof__`` type is used as the operand of a unary operator. (#GH97646) +- Fixed a failed assertion when checking invalid delete operator declaration. (#GH96191) +- Fix a crash when checking destructor reference with an invalid initializer. (#GH97230) +- Clang now correctly parses potentially declarative nested-name-specifiers in pointer-to-member declarators. +- Fix a crash when checking the initialzier of an object that was initialized + with a string literal. (#GH82167) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ -- Clang now properly preserves ``FoundDecls`` within a ``ConceptReference``. (#GH82628) -- The presence of the ``typename`` keyword is now stored in ``TemplateTemplateParmDecl``. -- Fixed malformed AST generated for anonymous union access in templates. (#GH90842) -- Improved preservation of qualifiers and sugar in `TemplateNames`, including - template keyword. Miscellaneous Bug Fixes ^^^^^^^^^^^^^^^^^^^^^^^ -- Fixed an infinite recursion in ASTImporter, on return type declared inside - body of C++11 lambda without trailing return (#GH68775). -- Fixed declaration name source location of instantiated function definitions (GH71161). -- Improve diagnostic output to print an expression instead of 'no argument` when comparing Values as template arguments. - Miscellaneous Clang Crashes Fixed ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Do not attempt to dump the layout of dependent types or invalid declarations - when ``-fdump-record-layouts-complete`` is passed. Fixes #GH83684. -- Unhandled StructuralValues in the template differ (#GH93068). +- Fixed a crash in C due to incorrect lookup that members in nested anonymous struct/union + can be found as ordinary identifiers in struct/union definition. (#GH31295) + +- Fixed a crash caused by long chains of ``sizeof`` and other similar operators + that can be followed by a non-parenthesized expression. (#GH45061) OpenACC Specific Changes ------------------------ @@ -1090,131 +200,52 @@ AMDGPU Support X86 Support ^^^^^^^^^^^ -- Remove knl/knm specific ISA supports: AVX512PF, AVX512ER, PREFETCHWT1 -- Support has been removed for the AMD "3DNow!" instruction-set. - Neither modern AMD CPUs, nor any Intel CPUs implement these - instructions, and they were never widely used. - - * The options ``-m3dnow`` and ``-m3dnowa`` are no longer honored, and will emit a warning if used. - * The macros ``__3dNOW__`` and ``__3dNOW_A__`` are no longer ever set by the compiler. - * The header ```` is deprecated, and emits a warning if included. - * The 3dNow intrinsic functions have been removed: ``_m_femms``, - ``_m_pavgusb``, ``_m_pf2id``, ``_m_pfacc``, ``_m_pfadd``, - ``_m_pfcmpeq``, ``_m_pfcmpge``, ``_m_pfcmpgt``, ``_m_pfmax``, - ``_m_pfmin``, ``_m_pfmul``, ``_m_pfrcp``, ``_m_pfrcpit1``, - ``_m_pfrcpit2``, ``_m_pfrsqrt``, ``_m_pfrsqrtit1``, ``_m_pfsub``, - ``_m_pfsubr``, ``_m_pi2fd``, ``_m_pmulhrw``, ``_m_pf2iw``, - ``_m_pfnacc``, ``_m_pfpnacc``, ``_m_pi2fw``, ``_m_pswapdsf``, - ``_m_pswapdsi``. - * The compiler builtins corresponding to each of the above - intrinsics have also been removed (``__builtin_ia32_femms``, and so on). - * "3DNow!" instructions remain supported in assembly code, including - inside inline-assembly. +- The MMX vector intrinsic functions from ``*mmintrin.h`` which + operate on `__m64` vectors, such as ``_mm_add_pi8``, have been + reimplemented to use the SSE2 instruction-set and XMM registers + unconditionally. These intrinsics are therefore *no longer + supported* if MMX is enabled without SSE2 -- either from targeting + CPUs from the Pentium-MMX through the Pentium 3, or explicitly via + passing arguments such as ``-mmmx -mno-sse2``. MMX assembly code + remains supported without requiring SSE2, including inside + inline-assembly. + +- The compiler builtins such as ``__builtin_ia32_paddb`` which + formerly implemented the above MMX intrinsic functions have been + removed. Any uses of these removed functions should migrate to the + functions defined by the ``*mmintrin.h`` headers. A mapping can be + found in the file ``clang/www/builtins.py``. Arm and AArch64 Support ^^^^^^^^^^^^^^^^^^^^^^^ -- ARMv7+ targets now default to allowing unaligned access, except Armv6-M, and - Armv8-M without the Main Extension. Baremetal targets should check that the - new default will work with their system configurations, since it requires - that SCTLR.A is 0, SCTLR.U is 1, and that the memory in question is - configured as "normal" memory. This brings Clang in-line with the default - settings for GCC and Arm Compiler. Aside from making Clang align with other - compilers, changing the default brings major performance and code size - improvements for most targets. We have not changed the default behavior for - ARMv6, but may revisit that decision in the future. Users can restore the old - behavior with -m[no-]unaligned-access. -- An alias identifier (rdma) has been added for targeting the AArch64 - Architecture Extension which uses Rounding Doubling Multiply Accumulate - instructions (rdm). The identifier is available on the command line as - a feature modifier for -march and -mcpu as well as via target attributes - like ``target_version`` or ``target_clones``. -- Support has been added for the following processors (-mcpu identifiers in parenthesis): - * Arm Cortex-R52+ (cortex-r52plus). - * Arm Cortex-R82AE (cortex-r82ae). - * Arm Cortex-A78AE (cortex-a78ae). - * Arm Cortex-A520AE (cortex-a520ae). - * Arm Cortex-A720AE (cortex-a720ae). - * Arm Cortex-A725 (cortex-a725). - * Arm Cortex-X925 (cortex-x925). - * Arm Neoverse-N3 (neoverse-n3). - * Arm Neoverse-V3 (neoverse-v3). - * Arm Neoverse-V3AE (neoverse-v3ae). - Android Support ^^^^^^^^^^^^^^^ Windows Support ^^^^^^^^^^^^^^^ -- The clang-cl ``/Ot`` compiler option ("optimize for speed", also implied by - ``/O2``) now maps to clang's ``-O3`` optimizataztion level instead of ``-O2``. - Users who prefer the old behavior can use ``clang-cl /Ot /clang:-O2 ...``. - -- Clang-cl now supports function targets with intrinsic headers. This allows - for runtime feature detection of intrinsics. Previously under clang-cl - ``immintrin.h`` and similar intrinsic headers would only include the intrinsics - if building with that feature enabled at compile time, e.g. ``avxintrin.h`` - would only be included if AVX was enabled at compile time. This was done to work - around include times from MSVC STL including ``intrin.h`` under clang-cl. - Clang-cl now provides ``intrin0.h`` for MSVC STL and therefore all intrinsic - features without requiring enablement at compile time. Fixes #GH53520 - -- Improved compile times with MSVC STL. MSVC provides ``intrin0.h`` which is a - header that only includes intrinsics that are used by MSVC STL to avoid the - use of ``intrin.h``. MSVC STL when compiled under clang uses ``intrin.h`` - instead. Clang-cl now provides ``intrin0.h`` for the same compiler throughput - purposes as MSVC. Clang-cl also provides ``yvals_core.h`` to redefine - ``_STL_INTRIN_HEADER`` to expand to ``intrin0.h`` instead of ``intrin.h``. - This also means that if all intrinsic features are enabled at compile time - including STL headers will no longer slow down compile times since ``intrin.h`` - is not included from MSVC STL. - -- When the target triple is `*-windows-msvc` strict aliasing is now disabled by default - to ensure compatibility with msvc. Previously strict aliasing was only disabled if the - driver mode was cl. - LoongArch Support ^^^^^^^^^^^^^^^^^ RISC-V Support ^^^^^^^^^^^^^^ -- ``__attribute__((rvv_vector_bits(N)))`` is now supported for RVV vbool*_t types. -- Profile names in ``-march`` option are now supported. -- Passing empty structs/unions as arguments in C++ is now handled correctly. The behavior is similar to GCC's. -- ``-m[no-]scalar-strict-align`` and ``-m[no-]vector-strict-align`` options have - been added to give separate control of whether scalar or vector misaligned - accesses may be created. ``-m[no-]strict-align`` applies to both scalar and - vector. - CUDA/HIP Language Changes ^^^^^^^^^^^^^^^^^^^^^^^^^ -- PTX is no longer included by default when compiling for CUDA. Using - ``--cuda-include-ptx=all`` will return the old behavior. - CUDA Support ^^^^^^^^^^^^ -- Clang now supports CUDA SDK up to 12.5 AIX Support ^^^^^^^^^^^ -- Introduced the ``-maix-small-local-dynamic-tls`` option to produce a faster - access sequence for local-dynamic TLS variables where the offset from the TLS - base is encoded as an immediate operand. - This access sequence is not used for TLS variables larger than 32KB, and is - currently only supported on 64-bit mode. +NetBSD Support +^^^^^^^^^^^^^^ WebAssembly Support ^^^^^^^^^^^^^^^^^^^ -The -mcpu=generic configuration now enables multivalue and reference-types. -These proposals are standardized and available in all major engines. Enabling -multivalue here only enables the language feature but does not turn on the -multivalue ABI (this enables non-ABI uses of multivalue, like exnref). - AVR Support ^^^^^^^^^^^ @@ -1224,134 +255,56 @@ DWARF Support in Clang Floating Point Support in Clang ------------------------------- -- Add ``__builtin__fmaf16`` builtin for floating point types. - Fixed Point Support in Clang ---------------------------- -- Support fixed point precision macros according to ``7.18a.3`` of - `ISO/IEC TR 18037:2008 `_. - AST Matchers ------------ -- Fixes a long-standing performance issue in parent map generation for - ancestry-based matchers such as ``hasParent`` and ``hasAncestor``, making - them significantly faster. -- ``isInStdNamespace`` now supports Decl declared with ``extern "C++"``. -- Add ``isExplicitObjectMemberFunction``. -- Fixed ``forEachArgumentWithParam`` and ``forEachArgumentWithParamType`` to - not skip the explicit object parameter for operator calls. -- Fixed captureVars assertion failure if not capturesVariables. (#GH76425) -- ``forCallable`` now properly preserves binding on successful match. (#GH89657) +- Fixed an issue with the `hasName` and `hasAnyName` matcher when matching + inline namespaces with an enclosing namespace of the same name. clang-format ------------ -- ``AlwaysBreakTemplateDeclarations`` is deprecated and renamed to - ``BreakTemplateDeclarations``. -- ``AlwaysBreakAfterReturnType`` is deprecated and renamed to - ``BreakAfterReturnType``. -- Handles Java switch expressions. -- Adds ``AllowShortCaseExpressionOnASingleLine`` option. -- Adds ``AlignCaseArrows`` suboption to ``AlignConsecutiveShortCaseStatements``. -- Adds ``LeftWithLastLine`` suboption to ``AlignEscapedNewlines``. -- Adds ``KeepEmptyLines`` option to deprecate ``KeepEmptyLinesAtEOF`` - and ``KeepEmptyLinesAtTheStartOfBlocks``. -- Add ``ExceptDoubleParentheses`` sub-option for ``SpacesInParensOptions`` - to override addition of spaces between multiple, non-redundant parentheses - similar to the rules used for ``RemoveParentheses``. - libclang -------- -- ``clang_getSpellingLocation`` now correctly resolves macro expansions; that - is, it returns the spelling location instead of the expansion location. - Static Analyzer --------------- New features ^^^^^^^^^^^^ -- The attribute ``[[clang::suppress]]`` can now be applied to declarations. - (#GH80371) - -- Support C++23 static operator calls. (#GH84972) +- MallocChecker now checks for ``ownership_returns(class, idx)`` and ``ownership_takes(class, idx)`` + attributes with class names different from "malloc". Clang static analyzer now reports an error + if class of allocation and deallocation function mismatches. + `Documentation `__. Crash and bug fixes ^^^^^^^^^^^^^^^^^^^ -- Fixed crashing on loops if the loop variable was declared in switch blocks - but not under any case blocks if ``unroll-loops=true`` analyzer config is - set. (#GH68819) - -- Fixed a crash in ``security.cert.env.InvalidPtr`` checker when accidentally - matched user-defined ``strerror`` and similar library functions. (#GH88181) - -- Fixed a crash when storing through an address that refers to the address of - a label. (#GH89185) - -- Z3 crosschecking (aka. Z3 refutation) is now bounded, and can't consume - more total time than the eymbolic execution itself. (#GH97298) - Improvements ^^^^^^^^^^^^ +- Improved the handling of the ``ownership_returns`` attribute. Now, Clang reports an + error if the attribute is attached to a function that returns a non-pointer value. + Fixes (#GH99501) + Moved checkers ^^^^^^^^^^^^^^ -- Moved ``alpha.cplusplus.ArrayDelete`` out of the ``alpha`` package - to ``cplusplus.ArrayDelete``. (#GH83985) - `Documentation `__. - -- Moved ``alpha.unix.Stream`` out of the ``alpha`` package to - ``unix.Stream``. (#GH89247) - `Documentation `__. - -- Moved ``alpha.unix.BlockInCriticalSection`` out of the ``alpha`` package to - ``unix.BlockInCriticalSection``. (#GH93815) - `Documentation `__. - -- Moved ``alpha.security.cert.pos.34c`` out of the ``alpha`` package to - ``security.PutenvStackArray``. (#GH92424, #GH93815) - `Documentation `__. - -- Moved ``alpha.core.SizeofPtr`` into ``clang-tidy`` - ``bugprone-sizeof-expression``. (#GH95118, #GH94356) - `Documentation `__. - .. _release-notes-sanitizers: Sanitizers ---------- -- ``-fsanitize=signed-integer-overflow`` now instruments signed arithmetic even - when ``-fwrapv`` is enabled. Previously, only division checks were enabled. - - Users with ``-fwrapv`` as well as a sanitizer group like - ``-fsanitize=undefined`` or ``-fsanitize=integer`` enabled may want to - manually disable potentially noisy signed integer overflow checks with - ``-fno-sanitize=signed-integer-overflow`` - -- ``-fsanitize=cfi -fsanitize-cfi-cross-dso`` (cross-DSO CFI instrumentation) - now generates the ``__cfi_check`` function with proper target-specific - attributes, for example allowing unwind table generation. - Python Binding Changes ---------------------- -- Exposed `CXRewriter` API as `class Rewriter`. -- Add some missing kinds from Index.h (CursorKind: 149-156, 272-320, 420-437. - TemplateArgumentKind: 5-9. TypeKind: 161-175 and 178). -- Add support for retrieving binary operator information through - Cursor.binary_operator(). - OpenMP Support -------------- -- Added support for the `[[omp::assume]]` attribute. - Additional Information ====================== diff --git a/clang/docs/StandardCPlusPlusModules.rst b/clang/docs/StandardCPlusPlusModules.rst index cf0528e75e7f2..b87491910e222 100644 --- a/clang/docs/StandardCPlusPlusModules.rst +++ b/clang/docs/StandardCPlusPlusModules.rst @@ -652,6 +652,149 @@ in the future. The expected roadmap for Reduced BMIs as of Clang 19.x is: 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. +Experimental Non-Cascading Changes +---------------------------------- + +This section is primarily for build system vendors. For end compiler users, +if you don't want to read it all, this is helpful to reduce recompilations. +We encourage build system vendors and end users try this out and bring feedback. + +Before Clang 19, a change in BMI of any (transitive) dependency would cause the +outputs of the BMI to change. Starting with Clang 19, changes to non-direct +dependencies should not directly affect the output BMI, unless they affect the +results of the compilations. We expect that there are many more opportunities +for this optimization than we currently have realized and would appreaciate +feedback about missed optimization opportunities. For example, + +.. code-block:: c++ + + // m-partA.cppm + export module m:partA; + + // m-partB.cppm + export module m:partB; + export int getB() { return 44; } + + // m.cppm + export module m; + export import :partA; + export import :partB; + + // useBOnly.cppm + export module useBOnly; + import m; + export int B() { + return getB(); + } + + // Use.cc + import useBOnly; + int get() { + return B(); + } + +To compile the project (for brevity, some commands are omitted.): + +.. code-block:: console + + $ clang++ -std=c++20 m-partA.cppm --precompile -o m-partA.pcm + $ clang++ -std=c++20 m-partB.cppm --precompile -o m-partB.pcm + $ clang++ -std=c++20 m.cppm --precompile -o m.pcm -fprebuilt-module-path=. + $ clang++ -std=c++20 useBOnly.cppm --precompile -o useBOnly.pcm -fprebuilt-module-path=. + $ md5sum useBOnly.pcm + 07656bf4a6908626795729295f9608da useBOnly.pcm + +If the interface of ``m-partA.cppm`` is changed to: + +.. code-block:: c++ + + // m-partA.v1.cppm + export module m:partA; + export int getA() { return 43; } + +and the BMI for ``useBOnly`` is recompiled as in: + +.. code-block:: console + + $ clang++ -std=c++20 m-partA.cppm --precompile -o m-partA.pcm + $ clang++ -std=c++20 m-partB.cppm --precompile -o m-partB.pcm + $ clang++ -std=c++20 m.cppm --precompile -o m.pcm -fprebuilt-module-path=. + $ clang++ -std=c++20 useBOnly.cppm --precompile -o useBOnly.pcm -fprebuilt-module-path=. + $ md5sum useBOnly.pcm + 07656bf4a6908626795729295f9608da useBOnly.pcm + +then the contents of ``useBOnly.pcm`` remain unchanged. +Consequently, if the build system only bases recompilation decisions on directly imported modules, +it becomes possible to skip the recompilation of ``Use.cc``. +It should be fine because the altered interfaces do not affect ``Use.cc`` in any way; +the changes do not cascade. + +When ``Clang`` generates a BMI, it records the hash values of all potentially contributory BMIs +for the BMI being produced. This ensures that build systems are not required to consider +transitively imported modules when deciding whether to recompile. + +What is considered to be a potential contributory BMIs is currently unspecified. +However, it is a severe bug for a BMI to remain unchanged following an observable change +that affects its consumers. + +Build systems may utilize this optimization by doing an update-if-changed operation to the BMI +that is consumed from the BMI that is output by the compiler. + +We encourage build systems to add an experimental mode that +reuses the cached BMI when **direct** dependencies did not change, +even if **transitive** dependencies did change. + +Given there are potential compiler bugs, we recommend that build systems +support this feature as a configurable option so that users +can go back to the transitive change mode safely at any time. + +Interactions with Reduced BMI +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +With reduced BMI, non-cascading changes can be more powerful. For example, + +.. code-block:: c++ + + // A.cppm + export module A; + export int a() { return 44; } + + // B.cppm + export module B; + import A; + export int b() { return a(); } + +.. 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 + $ md5sum B.pcm + 6c2bd452ca32ab418bf35cd141b060b9 B.pcm + +And let's change the implementation for ``A.cppm`` into: + +.. code-block:: c++ + + export module A; + int a_impl() { return 99; } + export int a() { return a_impl(); } + +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 + $ md5sum B.pcm + 6c2bd452ca32ab418bf35cd141b060b9 B.pcm + +We should find the contents of ``B.pcm`` remains the same. In this case, the build system is +allowed to skip recompilations of TUs which solely and directly depend on module ``B``. + +This only happens with a reduced BMI. With reduced BMIs, we won't record the function body +of ``int b()`` in the BMI for ``B`` so that the module ``A`` doesn't contribute to the BMI of ``B`` +and we have less dependencies. + Performance Tips ---------------- diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index 76a9aae170893..55832d20bd27a 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -1703,7 +1703,13 @@ are detected: * Invalid 3rd ("``whence``") argument to ``fseek``. The stream operations are by this checker usually split into two cases, a success -and a failure case. However, in the case of write operations (like ``fwrite``, +and a failure case. +On the success case it also assumes that the current value of ``stdout``, +``stderr``, or ``stdin`` can't be equal to the file pointer returned by ``fopen``. +Operations performed on ``stdout``, ``stderr``, or ``stdin`` are not checked by +this checker in contrast to the streams opened by ``fopen``. + +In the case of write operations (like ``fwrite``, ``fprintf`` and even ``fsetpos``) this behavior could produce a large amount of unwanted reports on projects that don't have error checks around the write operations, so by default the checker assumes that write operations always succeed. @@ -1769,9 +1775,7 @@ are assumed to succeed.) **Limitations** The checker does not track the correspondence between integer file descriptors -and ``FILE *`` pointers. Operations on standard streams like ``stdin`` are not -treated specially and are therefore often not recognized (because these streams -are usually not opened explicitly by the program, and are global variables). +and ``FILE *`` pointers. .. _osx-checkers: @@ -2494,15 +2498,49 @@ Check for pointer arithmetic on locations other than array elements. alpha.core.PointerSub (C) """"""""""""""""""""""""" -Check for pointer subtractions on two pointers pointing to different memory chunks. +Check for pointer subtractions on two pointers pointing to different memory +chunks. According to the C standard §6.5.6 only subtraction of pointers that +point into (or one past the end) the same array object is valid (for this +purpose non-array variables are like arrays of size 1). .. code-block:: c void test() { - int x, y; - int d = &y - &x; // warn + int a, b, c[10], d[10]; + int x = &c[3] - &c[1]; + x = &d[4] - &c[1]; // warn: 'c' and 'd' are different arrays + x = (&a + 1) - &a; + x = &b - &a; // warn: 'a' and 'b' are different variables + x = (&a + 2) - &a; // warn: for a variable it is only valid to have a pointer + // to one past the address of it + x = &c[10] - &c[0]; + x = &c[11] - &c[0]; // warn: index larger than one past the end + x = &c[-1] - &c[0]; // warn: negative index } + struct S { + int x[10]; + int y[10]; + }; + + void test1() { + struct S a[10]; + struct S b; + int d = &a[4] - &a[6]; + d = &a[0].x[3] - &a[0].x[1]; + d = a[0].y - a[0].x; // warn: 'S.b' and 'S.a' are different objects + d = (char *)&b.y - (char *)&b.x; // warn: different members of the same object + d = (char *)&b.y - (char *)&b; // warn: object of type S is not the same array as a member of it + } + +There may be existing applications that use code like above for calculating +offsets of members in a structure, using pointer subtractions. This is still +undefined behavior according to the standard and code like this can be replaced +with the `offsetof` macro. + +The checker only reports cases where stack-allocated objects are involved (no +warnings on pointers to memory allocated by `malloc`). + .. _alpha-core-StackAddressAsyncEscape: alpha.core.StackAddressAsyncEscape (C) diff --git a/clang/docs/analyzer/checkers/mismatched_deallocator_example.cpp b/clang/docs/analyzer/checkers/mismatched_deallocator_example.cpp index 2a4103240fe81..3b7c7d99faef3 100644 --- a/clang/docs/analyzer/checkers/mismatched_deallocator_example.cpp +++ b/clang/docs/analyzer/checkers/mismatched_deallocator_example.cpp @@ -6,6 +6,10 @@ void test() { // C, C++ void __attribute((ownership_returns(malloc))) *user_malloc(size_t); +void __attribute((ownership_takes(malloc, 1))) *user_free(void *); + +void __attribute((ownership_returns(malloc1))) *user_malloc1(size_t); +void __attribute((ownership_takes(malloc1, 1))) *user_free1(void *); void test() { int *p = (int *)user_malloc(sizeof(int)); @@ -24,6 +28,12 @@ void test() { realloc(p, sizeof(long)); // warn } +// C, C++ +void test() { + int *p = user_malloc(10); + user_free1(p); // warn +} + // C, C++ template struct SimpleSmartPointer { diff --git a/clang/docs/index.rst b/clang/docs/index.rst index a35a867b96bd7..9bae0bd83243b 100644 --- a/clang/docs/index.rst +++ b/clang/docs/index.rst @@ -92,6 +92,7 @@ Using Clang Tools ClangFormatStyleOptions ClangFormattedStatus ClangLinkerWrapper + ClangNVLinkWrapper ClangOffloadBundler ClangOffloadPackager ClangRepl diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index fb87ad79f0748..3e37d7ca9e7ba 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2146,6 +2146,14 @@ enum CXCursorKind { */ CXCursor_OMPScopeDirective = 306, + /** OpenMP reverse directive. + */ + CXCursor_OMPReverseDirective = 307, + + /** OpenMP interchange directive. + */ + CXCursor_OMPInterchangeDirective = 308, + /** OpenACC Compute Construct. */ CXCursor_OpenACCComputeConstruct = 320, diff --git a/clang/include/clang/APINotes/APINotesReader.h b/clang/include/clang/APINotes/APINotesReader.h index 37a4ff7a69712..03657352c49a5 100644 --- a/clang/include/clang/APINotes/APINotesReader.h +++ b/clang/include/clang/APINotes/APINotesReader.h @@ -141,6 +141,16 @@ class APINotesReader { ObjCSelectorRef Selector, bool IsInstanceMethod); + /// Look for information regarding the given C++ method in the given C++ tag + /// context. + /// + /// \param CtxID The ID that references the parent context, i.e. a C++ tag. + /// \param Name The name of the C++ method we're looking for. + /// + /// \returns Information about the method, if known. + VersionedInfo lookupCXXMethod(ContextID CtxID, + llvm::StringRef Name); + /// Look for information regarding the given global variable. /// /// \param Name The name of the global variable. @@ -166,6 +176,17 @@ class APINotesReader { /// \returns information about the enumerator, if known. VersionedInfo lookupEnumConstant(llvm::StringRef Name); + /// Look for the context ID of the given C++ tag. + /// + /// \param Name The name of the tag we're looking for. + /// \param ParentCtx The context in which this tag is declared, e.g. a C++ + /// namespace. + /// + /// \returns The ID, if known. + std::optional + lookupTagID(llvm::StringRef Name, + std::optional ParentCtx = std::nullopt); + /// Look for information regarding the given tag /// (struct/union/enum/C++ class). /// diff --git a/clang/include/clang/APINotes/APINotesWriter.h b/clang/include/clang/APINotes/APINotesWriter.h index e82dbc7c9540e..e0fe5eacef725 100644 --- a/clang/include/clang/APINotes/APINotesWriter.h +++ b/clang/include/clang/APINotes/APINotesWriter.h @@ -78,6 +78,14 @@ class APINotesWriter { bool IsInstanceMethod, const ObjCMethodInfo &Info, llvm::VersionTuple SwiftVersion); + /// Add information about a specific C++ method. + /// + /// \param CtxID The context in which this method resides, i.e. a C++ tag. + /// \param Name The name of the method. + /// \param Info Information about this method. + void addCXXMethod(ContextID CtxID, llvm::StringRef Name, + const CXXMethodInfo &Info, llvm::VersionTuple SwiftVersion); + /// Add information about a global variable. /// /// \param Name The name of this global variable. diff --git a/clang/include/clang/APINotes/Types.h b/clang/include/clang/APINotes/Types.h index b389aa8d56f16..c8e5e4df25d17 100644 --- a/clang/include/clang/APINotes/Types.h +++ b/clang/include/clang/APINotes/Types.h @@ -656,6 +656,12 @@ class GlobalFunctionInfo : public FunctionInfo { GlobalFunctionInfo() {} }; +/// Describes API notes data for a C++ method. +class CXXMethodInfo : public FunctionInfo { +public: + CXXMethodInfo() {} +}; + /// Describes API notes data for an enumerator. class EnumConstantInfo : public CommonEntityInfo { public: @@ -789,6 +795,7 @@ enum class ContextKind : uint8_t { ObjCClass = 0, ObjCProtocol = 1, Namespace = 2, + Tag = 3, }; struct Context { diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index aae9dfb719292..ca1a948dcce97 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -738,6 +738,12 @@ class ASTContext : public RefCountedBase { } void Deallocate(void *Ptr) const {} + llvm::StringRef backupStr(llvm::StringRef S) const { + char *Buf = new (*this) char[S.size()]; + std::copy(S.begin(), S.end(), Buf); + return llvm::StringRef(Buf, S.size()); + } + /// Allocates a \c DeclListNode or returns one from the \c ListNodeFreeList /// pool. DeclListNode *AllocateDeclListNode(clang::NamedDecl *ND) { @@ -1292,7 +1298,7 @@ class ASTContext : public RefCountedBase { getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD); /// Return the "other" type-specific discriminator for the given type. - uint16_t getPointerAuthTypeDiscriminator(QualType T) const; + uint16_t getPointerAuthTypeDiscriminator(QualType T); /// Apply Objective-C protocol qualifiers to the given type. /// \param allowOnPointerType specifies if we can apply protocol @@ -1368,7 +1374,7 @@ class ASTContext : public RefCountedBase { bool AsWritten = false); /// Get a function type and produce the equivalent function type where - /// pointer size address spaces in the return type and parameter tyeps are + /// pointer size address spaces in the return type and parameter types are /// replaced with the default address space. QualType getFunctionTypeWithoutPtrSizes(QualType T); diff --git a/clang/include/clang/AST/ASTImporter.h b/clang/include/clang/AST/ASTImporter.h index 4ffd913846575..f851decd0965c 100644 --- a/clang/include/clang/AST/ASTImporter.h +++ b/clang/include/clang/AST/ASTImporter.h @@ -258,7 +258,6 @@ class TypeSourceInfo; FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name); void AddToLookupTable(Decl *ToD); - llvm::Error ImportAttrs(Decl *ToD, Decl *FromD); protected: /// Can be overwritten by subclasses to implement their own import logic. diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h index 616f92691ec32..0546c19ce8119 100644 --- a/clang/include/clang/AST/ASTNodeTraverser.h +++ b/clang/include/clang/AST/ASTNodeTraverser.h @@ -583,7 +583,7 @@ class ASTNodeTraverser void VisitCapturedDecl(const CapturedDecl *D) { Visit(D->getBody()); } void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) { - for (const auto *E : D->varlists()) + for (const auto *E : D->varlist()) Visit(E); } @@ -603,7 +603,7 @@ class ASTNodeTraverser } void VisitOMPAllocateDecl(const OMPAllocateDecl *D) { - for (const auto *E : D->varlists()) + for (const auto *E : D->varlist()) Visit(E); for (const auto *C : D->clauselists()) Visit(C); diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index fb52ac804849d..bf6a5ce92d438 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -1188,10 +1188,6 @@ class CXXRecordDecl : public RecordDecl { /// /// \note This does NOT include a check for union-ness. bool isEmpty() const { return data().Empty; } - /// Marks this record as empty. This is used by DWARFASTParserClang - /// when parsing records with empty fields having [[no_unique_address]] - /// attribute - void markEmpty() { data().Empty = true; } void setInitMethod(bool Val) { data().HasInitMethod = Val; } bool hasInitMethod() const { return data().HasInitMethod; } @@ -1210,6 +1206,13 @@ class CXXRecordDecl : public RecordDecl { return D.HasPublicFields || D.HasProtectedFields || D.HasPrivateFields; } + /// If this is a standard-layout class or union, any and all data members will + /// be declared in the same type. + /// + /// This retrieves the type where any fields are declared, + /// or the current class if there is no class with fields. + const CXXRecordDecl *getStandardLayoutBaseWithFields() const; + /// Whether this class is polymorphic (C++ [class.virtual]), /// which means that the class contains or inherits a virtual function. bool isPolymorphic() const { return data().Polymorphic; } diff --git a/clang/include/clang/AST/DeclOpenMP.h b/clang/include/clang/AST/DeclOpenMP.h index e542c3c8e66b0..868662208efa1 100644 --- a/clang/include/clang/AST/DeclOpenMP.h +++ b/clang/include/clang/AST/DeclOpenMP.h @@ -143,10 +143,10 @@ class OMPThreadPrivateDecl final : public OMPDeclarativeDirective { unsigned varlist_size() const { return Data->getNumChildren(); } bool varlist_empty() const { return Data->getChildren().empty(); } - varlist_range varlists() { + varlist_range varlist() { return varlist_range(varlist_begin(), varlist_end()); } - varlist_const_range varlists() const { + varlist_const_range varlist() const { return varlist_const_range(varlist_begin(), varlist_end()); } varlist_iterator varlist_begin() { return getVars().begin(); } @@ -513,10 +513,10 @@ class OMPAllocateDecl final : public OMPDeclarativeDirective { unsigned clauselist_size() const { return Data->getNumClauses(); } bool clauselist_empty() const { return Data->getClauses().empty(); } - varlist_range varlists() { + varlist_range varlist() { return varlist_range(varlist_begin(), varlist_end()); } - varlist_const_range varlists() const { + varlist_const_range varlist() const { return varlist_const_range(varlist_begin(), varlist_end()); } varlist_iterator varlist_begin() { return getVars().begin(); } diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 05811c46885a3..e2383925f2318 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -4854,15 +4854,7 @@ class CXXFoldExpr : public Expr { CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee, SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc, - std::optional NumExpansions) - : Expr(CXXFoldExprClass, T, VK_PRValue, OK_Ordinary), - LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc), - NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) { - SubExprs[SubExpr::Callee] = Callee; - SubExprs[SubExpr::LHS] = LHS; - SubExprs[SubExpr::RHS] = RHS; - setDependence(computeDependence(this)); - } + std::optional NumExpansions); CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {} diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 325a1baa44614..b029c72fa7d8f 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -316,10 +316,10 @@ template class OMPVarListClause : public OMPClause { unsigned varlist_size() const { return NumVars; } bool varlist_empty() const { return NumVars == 0; } - varlist_range varlists() { + varlist_range varlist() { return varlist_range(varlist_begin(), varlist_end()); } - varlist_const_range varlists() const { + varlist_const_range varlist() const { return varlist_const_range(varlist_begin(), varlist_end()); } diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 0879f519c683d..922b8020c321a 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1772,10 +1772,10 @@ DEF_TRAVERSE_DECL(UsingShadowDecl, {}) DEF_TRAVERSE_DECL(ConstructorUsingShadowDecl, {}) DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, { - for (auto *I : D->varlists()) { + for (auto *I : D->varlist()) { TRY_TO(TraverseStmt(I)); } - }) +}) DEF_TRAVERSE_DECL(OMPRequiresDecl, { for (auto *C : D->clauselists()) { @@ -1801,7 +1801,7 @@ DEF_TRAVERSE_DECL(OMPDeclareMapperDecl, { DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); }) DEF_TRAVERSE_DECL(OMPAllocateDecl, { - for (auto *I : D->varlists()) + for (auto *I : D->varlist()) TRY_TO(TraverseStmt(I)); for (auto *C : D->clauselists()) TRY_TO(TraverseOMPClause(C)); @@ -3047,6 +3047,12 @@ DEF_TRAVERSE_STMT(OMPTileDirective, DEF_TRAVERSE_STMT(OMPUnrollDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPReverseDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPInterchangeDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + DEF_TRAVERSE_STMT(OMPForDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) @@ -3561,7 +3567,7 @@ bool RecursiveASTVisitor::VisitOMPNocontextClause( template template bool RecursiveASTVisitor::VisitOMPClauseList(T *Node) { - for (auto *E : Node->varlists()) { + for (auto *E : Node->varlist()) { TRY_TO(TraverseStmt(E)); } return true; @@ -3935,7 +3941,7 @@ template bool RecursiveASTVisitor::VisitOMPAffinityClause( OMPAffinityClause *C) { TRY_TO(TraverseStmt(C->getModifier())); - for (Expr *E : C->varlists()) + for (Expr *E : C->varlist()) TRY_TO(TraverseStmt(E)); return true; } diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h index f735fa5643aec..f313c480f9a08 100644 --- a/clang/include/clang/AST/StmtOpenMP.h +++ b/clang/include/clang/AST/StmtOpenMP.h @@ -281,15 +281,6 @@ class OMPExecutableDirective : public Stmt { return Data->getClauses(); } - /// Was this directive mapped from an another directive? - /// e.g. 1) omp loop bind(parallel) is mapped to OMPD_for - /// 2) omp loop bind(teams) is mapped to OMPD_distribute - /// 3) omp loop bind(thread) is mapped to OMPD_simd - /// It was necessary to note it down in the Directive because of - /// clang::TreeTransform::TransformOMPExecutableDirective() pass in - /// the frontend. - OpenMPDirectiveKind PrevMappedDirective = llvm::omp::OMPD_unknown; - protected: /// Data, associated with the directive. OMPChildren *Data = nullptr; @@ -354,10 +345,6 @@ class OMPExecutableDirective : public Stmt { return Inst; } - void setMappedDirective(OpenMPDirectiveKind MappedDirective) { - PrevMappedDirective = MappedDirective; - } - public: /// Iterates over expressions/statements used in the construct. class used_clauses_child_iterator @@ -611,8 +598,6 @@ class OMPExecutableDirective : public Stmt { "Expected directive with the associated statement."); return Data->getRawStmt(); } - - OpenMPDirectiveKind getMappedDirective() const { return PrevMappedDirective; } }; /// This represents '#pragma omp parallel' directive. @@ -1007,8 +992,9 @@ class OMPLoopTransformationDirective : public OMPLoopBasedDirective { Stmt *getPreInits() const; static bool classof(const Stmt *T) { - return T->getStmtClass() == OMPTileDirectiveClass || - T->getStmtClass() == OMPUnrollDirectiveClass; + Stmt::StmtClass C = T->getStmtClass(); + return C == OMPTileDirectiveClass || C == OMPUnrollDirectiveClass || + C == OMPReverseDirectiveClass || C == OMPInterchangeDirectiveClass; } }; @@ -1619,8 +1605,7 @@ class OMPSimdDirective : public OMPLoopDirective { SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, Stmt *AssociatedStmt, - const HelperExprs &Exprs, - OpenMPDirectiveKind ParamPrevMappedDirective); + const HelperExprs &Exprs); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -1698,8 +1683,7 @@ class OMPForDirective : public OMPLoopDirective { SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, - Expr *TaskRedRef, bool HasCancel, - OpenMPDirectiveKind ParamPrevMappedDirective); + Expr *TaskRedRef, bool HasCancel); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -4477,8 +4461,7 @@ class OMPDistributeDirective : public OMPLoopDirective { static OMPDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs, - OpenMPDirectiveKind ParamPrevMappedDirective); + Stmt *AssociatedStmt, const HelperExprs &Exprs); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -5711,6 +5694,144 @@ class OMPUnrollDirective final : public OMPLoopTransformationDirective { } }; +/// Represents the '#pragma omp reverse' loop transformation directive. +/// +/// \code +/// #pragma omp reverse +/// for (int i = 0; i < n; ++i) +/// ... +/// \endcode +class OMPReverseDirective final : public OMPLoopTransformationDirective { + friend class ASTStmtReader; + friend class OMPExecutableDirective; + + /// Offsets of child members. + enum { + PreInitsOffset = 0, + TransformedStmtOffset, + }; + + explicit OMPReverseDirective(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPLoopTransformationDirective(OMPReverseDirectiveClass, + llvm::omp::OMPD_reverse, StartLoc, + EndLoc, 1) {} + + void setPreInits(Stmt *PreInits) { + Data->getChildren()[PreInitsOffset] = PreInits; + } + + void setTransformedStmt(Stmt *S) { + Data->getChildren()[TransformedStmtOffset] = S; + } + +public: + /// Create a new AST node representation for '#pragma omp reverse'. + /// + /// \param C Context of the AST. + /// \param StartLoc Location of the introducer (e.g. the 'omp' token). + /// \param EndLoc Location of the directive's end (e.g. the tok::eod). + /// \param AssociatedStmt The outermost associated loop. + /// \param TransformedStmt The loop nest after tiling, or nullptr in + /// dependent contexts. + /// \param PreInits Helper preinits statements for the loop nest. + static OMPReverseDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + Stmt *AssociatedStmt, Stmt *TransformedStmt, Stmt *PreInits); + + /// Build an empty '#pragma omp reverse' AST node for deserialization. + /// + /// \param C Context of the AST. + /// \param NumClauses Number of clauses to allocate. + static OMPReverseDirective *CreateEmpty(const ASTContext &C); + + /// Gets/sets the associated loops after the transformation, i.e. after + /// de-sugaring. + Stmt *getTransformedStmt() const { + return Data->getChildren()[TransformedStmtOffset]; + } + + /// Return preinits statement. + Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPReverseDirectiveClass; + } +}; + +/// Represents the '#pragma omp interchange' loop transformation directive. +/// +/// \code{c} +/// #pragma omp interchange +/// for (int i = 0; i < m; ++i) +/// for (int j = 0; j < n; ++j) +/// .. +/// \endcode +class OMPInterchangeDirective final : public OMPLoopTransformationDirective { + friend class ASTStmtReader; + friend class OMPExecutableDirective; + + /// Offsets of child members. + enum { + PreInitsOffset = 0, + TransformedStmtOffset, + }; + + explicit OMPInterchangeDirective(SourceLocation StartLoc, + SourceLocation EndLoc, unsigned NumLoops) + : OMPLoopTransformationDirective(OMPInterchangeDirectiveClass, + llvm::omp::OMPD_interchange, StartLoc, + EndLoc, NumLoops) { + setNumGeneratedLoops(3 * NumLoops); + } + + void setPreInits(Stmt *PreInits) { + Data->getChildren()[PreInitsOffset] = PreInits; + } + + void setTransformedStmt(Stmt *S) { + Data->getChildren()[TransformedStmtOffset] = S; + } + +public: + /// Create a new AST node representation for '#pragma omp interchange'. + /// + /// \param C Context of the AST. + /// \param StartLoc Location of the introducer (e.g. the 'omp' token). + /// \param EndLoc Location of the directive's end (e.g. the tok::eod). + /// \param Clauses The directive's clauses. + /// \param NumLoops Number of affected loops + /// (number of items in the 'permutation' clause if present). + /// \param AssociatedStmt The outermost associated loop. + /// \param TransformedStmt The loop nest after tiling, or nullptr in + /// dependent contexts. + /// \param PreInits Helper preinits statements for the loop nest. + static OMPInterchangeDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef Clauses, unsigned NumLoops, Stmt *AssociatedStmt, + Stmt *TransformedStmt, Stmt *PreInits); + + /// Build an empty '#pragma omp interchange' AST node for deserialization. + /// + /// \param C Context of the AST. + /// \param NumClauses Number of clauses to allocate. + /// \param NumLoops Number of associated loops to allocate. + static OMPInterchangeDirective * + CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned NumLoops); + + /// Gets the associated loops after the transformation. This is the de-sugared + /// replacement or nullptr in dependent contexts. + Stmt *getTransformedStmt() const { + return Data->getChildren()[TransformedStmtOffset]; + } + + /// Return preinits statement. + Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPInterchangeDirectiveClass; + } +}; + /// This represents '#pragma omp scan' directive. /// /// \code diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 924b19649115e..6339d3adff4e3 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2509,6 +2509,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { bool isFunctionNoProtoType() const { return getAs(); } bool isFunctionProtoType() const { return getAs(); } bool isPointerType() const; + bool isPointerOrReferenceType() const; bool isSignableType() const; bool isAnyPointerType() const; // Any C pointer or ObjC object pointer bool isCountAttributedType() const; @@ -4708,26 +4709,25 @@ class FunctionEffect { }; private: - LLVM_PREFERRED_TYPE(Kind) - unsigned FKind : 3; + Kind FKind; // Expansion: for hypothetical TCB+types, there could be one Kind for TCB, // then ~16(?) bits "SubKind" to map to a specific named TCB. SubKind would // be considered for uniqueness. public: - FunctionEffect() : FKind(unsigned(Kind::None)) {} + FunctionEffect() : FKind(Kind::None) {} - explicit FunctionEffect(Kind K) : FKind(unsigned(K)) {} + explicit FunctionEffect(Kind K) : FKind(K) {} /// The kind of the effect. - Kind kind() const { return Kind(FKind); } + Kind kind() const { return FKind; } /// Return the opposite kind, for effects which have opposites. Kind oppositeKind() const; /// For serialization. - uint32_t toOpaqueInt32() const { return FKind; } + uint32_t toOpaqueInt32() const { return uint32_t(FKind); } static FunctionEffect fromOpaqueInt32(uint32_t Value) { return FunctionEffect(Kind(Value)); } @@ -8007,6 +8007,10 @@ inline bool Type::isPointerType() const { return isa(CanonicalType); } +inline bool Type::isPointerOrReferenceType() const { + return isPointerType() || isReferenceType(); +} + inline bool Type::isAnyPointerType() const { return isPointerType() || isObjCObjectPointerType(); } @@ -8462,7 +8466,7 @@ inline bool Type::isUndeducedType() const { /// Determines whether this is a type for which one can define /// an overloaded operator. inline bool Type::isOverloadableType() const { - if (!CanonicalType->isDependentType()) + if (!isDependentType()) return isRecordType() || isEnumeralType(); return !isArrayType() && !isFunctionType() && !isAnyPointerType() && !isMemberPointerType(); diff --git a/clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h b/clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h index 420f13ce11bfd..5c64e5b094749 100644 --- a/clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h +++ b/clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h @@ -18,6 +18,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/Stmt.h" #include "clang/Analysis/CFG.h" +#include "clang/Analysis/FlowSensitive/ASTOps.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Error.h" @@ -27,6 +28,20 @@ namespace clang { namespace dataflow { +namespace internal { +class StmtToBlockMap { +public: + StmtToBlockMap(const CFG &Cfg); + + const CFGBlock *lookup(const Stmt &S) const { + return StmtToBlock.lookup(&ignoreCFGOmittedNodes(S)); + } + +private: + llvm::DenseMap StmtToBlock; +}; +} // namespace internal + /// Holds CFG with additional information derived from it that is needed to /// perform dataflow analysis. class AdornedCFG { @@ -48,9 +63,10 @@ class AdornedCFG { /// Returns the CFG that is stored in this context. const CFG &getCFG() const { return *Cfg; } - /// Returns a mapping from statements to basic blocks that contain them. - const llvm::DenseMap &getStmtToBlock() const { - return StmtToBlock; + /// Returns the basic block that contains `S`, or null if no basic block + /// containing `S` is found. + const CFGBlock *blockForStmt(const Stmt &S) const { + return StmtToBlock.lookup(S); } /// Returns whether `B` is reachable from the entry block. @@ -73,8 +89,7 @@ class AdornedCFG { private: AdornedCFG( const Decl &D, std::unique_ptr Cfg, - llvm::DenseMap StmtToBlock, - llvm::BitVector BlockReachable, + internal::StmtToBlockMap StmtToBlock, llvm::BitVector BlockReachable, llvm::DenseSet ContainsExprConsumedInDifferentBlock) : ContainingDecl(D), Cfg(std::move(Cfg)), StmtToBlock(std::move(StmtToBlock)), @@ -85,7 +100,7 @@ class AdornedCFG { /// The `Decl` containing the statement used to construct the CFG. const Decl &ContainingDecl; std::unique_ptr Cfg; - llvm::DenseMap StmtToBlock; + internal::StmtToBlockMap StmtToBlock; llvm::BitVector BlockReachable; llvm::DenseSet ContainsExprConsumedInDifferentBlock; }; diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h index 50a7018872061..e6efde091871f 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h @@ -233,7 +233,7 @@ llvm::Expected>>> runDataflowAnalysis(const AdornedCFG &ACFG, AnalysisT &Analysis, const Environment &InitEnv, - CFGEltCallbacks PostAnalysisCallbacks, + CFGEltCallbacks PostAnalysisCallbacks = {}, std::int32_t MaxBlockVisits = kDefaultMaxBlockVisits) { CFGEltCallbacksTypeErased TypeErasedCallbacks; if (PostAnalysisCallbacks.Before) { @@ -286,22 +286,6 @@ runDataflowAnalysis(const AdornedCFG &ACFG, AnalysisT &Analysis, return std::move(BlockStates); } -/// Overload that takes only one post-analysis callback, which is run on the -/// state after visiting the `CFGElement`. This is provided for backwards -/// compatibility; new callers should call the overload taking `CFGEltCallbacks` -/// instead. -template -llvm::Expected>>> -runDataflowAnalysis( - const AdornedCFG &ACFG, AnalysisT &Analysis, const Environment &InitEnv, - CFGEltCallback PostAnalysisCallbackAfterElt = nullptr, - std::int32_t MaxBlockVisits = kDefaultMaxBlockVisits) { - return runDataflowAnalysis(ACFG, Analysis, InitEnv, - {nullptr, PostAnalysisCallbackAfterElt}, - MaxBlockVisits); -} - // Create an analysis class that is derived from `DataflowAnalysis`. This is an // SFINAE adapter that allows us to call two different variants of constructor // (either with or without the optional `Environment` parameter). diff --git a/clang/include/clang/Analysis/FlowSensitive/MapLattice.h b/clang/include/clang/Analysis/FlowSensitive/MapLattice.h index 16b0c978779a7..b2d147e4ae444 100644 --- a/clang/include/clang/Analysis/FlowSensitive/MapLattice.h +++ b/clang/include/clang/Analysis/FlowSensitive/MapLattice.h @@ -49,7 +49,7 @@ template class MapLattice { MapLattice() = default; - explicit MapLattice(Container C) { C = std::move(C); } + explicit MapLattice(Container C) : C{std::move(C)} {}; // The `bottom` element is the empty map. static MapLattice bottom() { return MapLattice(); } diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fcdb0cb0144b3..71180f8765c6b 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -489,6 +489,9 @@ def TargetELF : TargetSpec { def TargetELFOrMachO : TargetSpec { let ObjectFormats = ["ELF", "MachO"]; } +def TargetWindowsArm64EC : TargetSpec { + let CustomCode = [{ Target.getTriple().isWindowsArm64EC() }]; +} def TargetSupportsInitPriority : TargetSpec { let CustomCode = [{ !Target.getTriple().isOSzOS() }]; @@ -943,7 +946,7 @@ def PatchableFunctionEntry : InheritableAttr, TargetSpecificAttr> { + "riscv64", "x86", "x86_64", "ppc", "ppc64"]>> { let Spellings = [GCC<"patchable_function_entry">]; let Subjects = SubjectList<[Function, ObjCMethod]>; let Args = [UnsignedArgument<"Count">, DefaultIntArgument<"Offset", 0>]; @@ -2989,6 +2992,17 @@ def Convergent : InheritableAttr { let SimpleHandler = 1; } +def NoConvergent : InheritableAttr { + let Spellings = [Clang<"noconvergent">, Declspec<"noconvergent">]; + let Subjects = SubjectList<[Function, Stmt], WarnDiag, + "functions and statements">; + let LangOpts = [CUDA]; + let Documentation = [NoConvergentDocs]; + let SimpleHandler = 1; +} + +def : MutualExclusions<[Convergent, NoConvergent]>; + def NoInline : DeclOrStmtAttr { let Spellings = [CustomKeyword<"__noinline__">, GCC<"noinline">, CXX11<"clang", "noinline">, C23<"clang", "noinline">, @@ -5052,6 +5066,12 @@ def SelectAny : InheritableAttr { let SimpleHandler = 1; } +def HybridPatchable : InheritableAttr, TargetSpecificAttr { + let Spellings = [Declspec<"hybrid_patchable">, Clang<"hybrid_patchable">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [HybridPatchableDocs]; +} + def Thread : Attr { let Spellings = [Declspec<"thread">]; let LangOpts = [MicrosoftExt]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index d7f8f6c62a663..482a70949ec76 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -1435,6 +1435,34 @@ Sample usage: }]; } +def NoConvergentDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +This attribute prevents a function from being treated as convergent, which +means that optimizations can only move calls to that function to +control-equivalent blocks. If a statement is marked as ``noconvergent`` and +contains calls, it also prevents those calls from being treated as convergent. +In other words, those calls are not restricted to only being moved to +control-equivalent blocks. + +In languages following SPMD/SIMT programming model, e.g., CUDA/HIP, function +declarations and calls are treated as convergent by default for correctness. +This ``noconvergent`` attribute is helpful for developers to prevent them from +being treated as convergent when it's safe. + +.. code-block:: c + + __device__ float bar(float); + __device__ float foo(float) __attribute__((noconvergent)) {} + + __device__ int example(void) { + float x; + [[clang::noconvergent]] x = bar(x); + } + + }]; +} + def NoSplitStackDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -4068,7 +4096,7 @@ For example: typedef vint8m1_t fixed_vint8m1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen))); #endif -Creates a type ``fixed_vint8m1_t_t`` that is a fixed-length variant of +Creates a type ``fixed_vint8m1_t`` that is a fixed-length variant of ``vint8m1_t`` that contains exactly 512 bits. Unlike ``vint8m1_t``, this type can be used in globals, structs, unions, and arrays, all of which are unsupported for sizeless types. @@ -7511,7 +7539,8 @@ takes precedence over the command line option ``-fpatchable-function-entry=N,M`` ``M`` defaults to 0 if omitted. This attribute is only supported on -aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64 targets. +aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64/ppc/ppc64 targets. +For ppc/ppc64 targets, AIX is still not supported. }]; } @@ -7695,6 +7724,16 @@ For more information see or `msvc documentation `_. }]; } +def HybridPatchableDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``hybrid_patchable`` attribute declares an ARM64EC function with an additional +x86-64 thunk, which may be patched at runtime. + +For more information see +`ARM64EC ABI documentation `_. +}]; } + def WebAssemblyExportNameDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/clang/include/clang/Basic/AttributeCommonInfo.h b/clang/include/clang/Basic/AttributeCommonInfo.h index 5f024b4b5fd78..cdf9dcaff7508 100644 --- a/clang/include/clang/Basic/AttributeCommonInfo.h +++ b/clang/include/clang/Basic/AttributeCommonInfo.h @@ -191,6 +191,12 @@ class AttributeCommonInfo { /// __gnu__::__attr__ will be normalized to gnu::attr). std::string getNormalizedFullName() const; + /// Generate a normalized full name, with syntax, scope and name. + static std::string + normalizeFullNameWithSyntax(const IdentifierInfo *Name, + const IdentifierInfo *Scope, + AttributeCommonInfo::Syntax SyntaxUsed); + bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; } bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; } diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 9e4407eeb0126..78e59050eeb6f 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -83,11 +83,11 @@ class BitInt_Long_LongLongTemplate : // - _Constant: Argument has to constant-fold to an integer constant expression // __fp16 and __float128 builtin variants of libc/libm functions. -def AcosF128 : Builtin { - let Spellings = ["__builtin_acosf128"]; +def AcosF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_acos"]; let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; - let Prototype = "__float128(__float128)"; + let Prototype = "T(T)"; } def AcoshF128 : Builtin { @@ -97,11 +97,11 @@ def AcoshF128 : Builtin { let Prototype = "__float128(__float128)"; } -def AsinF128 : Builtin { - let Spellings = ["__builtin_asinf128"]; +def AsinF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_asin"]; let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; - let Prototype = "__float128(__float128)"; + let Prototype = "T(T)"; } def AsinhF128 : Builtin { @@ -111,11 +111,11 @@ def AsinhF128 : Builtin { let Prototype = "__float128(__float128)"; } -def AtanF128 : Builtin { - let Spellings = ["__builtin_atanf128"]; +def AtanF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_atan"]; let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; - let Prototype = "__float128(__float128)"; + let Prototype = "T(T)"; } def AtanhF128 : Builtin { @@ -143,10 +143,10 @@ def CosF16F128 : Builtin, F16F128MathTemplate { let Prototype = "T(T)"; } -def CoshF128 : Builtin { - let Spellings = ["__builtin_coshf128"]; +def CoshF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_cosh"]; let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; - let Prototype = "__float128(__float128)"; + let Prototype = "T(T)"; } def ErfF128 : Builtin { @@ -468,11 +468,11 @@ def SinF16F128 : Builtin, F16F128MathTemplate { let Prototype = "T(T)"; } -def SinhF128 : Builtin { - let Spellings = ["__builtin_sinhf128"]; +def SinhF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_sinh"]; let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; - let Prototype = "__float128(__float128)"; + let Prototype = "T(T)"; } def SqrtF16F128 : Builtin, F16F128MathTemplate { @@ -489,11 +489,11 @@ def TanF16F128 : Builtin, F16F128MathTemplate { let Prototype = "T(T)"; } -def TanhF128 : Builtin { - let Spellings = ["__builtin_tanhf128"]; +def TanhF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_tanh"]; let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; - let Prototype = "__float128(__float128)"; + let Prototype = "T(T)"; } def TgammaF128 : Builtin { @@ -4654,13 +4654,13 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> { // HLSL def HLSLAll : LangBuiltin<"HLSL_LANG"> { - let Spellings = ["__builtin_hlsl_elementwise_all"]; + let Spellings = ["__builtin_hlsl_all"]; let Attributes = [NoThrow, Const]; let Prototype = "bool(...)"; } def HLSLAny : LangBuiltin<"HLSL_LANG"> { - let Spellings = ["__builtin_hlsl_elementwise_any"]; + let Spellings = ["__builtin_hlsl_any"]; let Attributes = [NoThrow, Const]; let Prototype = "bool(...)"; } diff --git a/clang/include/clang/Basic/BuiltinsAMDGPU.def b/clang/include/clang/Basic/BuiltinsAMDGPU.def index f8c9233d10dab..4f30002772254 100644 --- a/clang/include/clang/Basic/BuiltinsAMDGPU.def +++ b/clang/include/clang/Basic/BuiltinsAMDGPU.def @@ -149,12 +149,18 @@ BUILTIN(__builtin_amdgcn_mqsad_pk_u16_u8, "WUiWUiUiWUi", "nc") BUILTIN(__builtin_amdgcn_mqsad_u32_u8, "V4UiWUiUiV4Ui", "nc") BUILTIN(__builtin_amdgcn_make_buffer_rsrc, "Qbv*sii", "nc") -BUILTIN(__builtin_amdgcn_raw_buffer_store_b8, "vcQbiiIi", "n") -BUILTIN(__builtin_amdgcn_raw_buffer_store_b16, "vsQbiiIi", "n") -BUILTIN(__builtin_amdgcn_raw_buffer_store_b32, "viQbiiIi", "n") -BUILTIN(__builtin_amdgcn_raw_buffer_store_b64, "vV2iQbiiIi", "n") -BUILTIN(__builtin_amdgcn_raw_buffer_store_b96, "vV3iQbiiIi", "n") -BUILTIN(__builtin_amdgcn_raw_buffer_store_b128, "vV4iQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_store_b8, "vUcQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_store_b16, "vUsQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_store_b32, "vUiQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_store_b64, "vV2UiQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_store_b96, "vV3UiQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_store_b128, "vV4UiQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_load_b8, "UcQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_load_b16, "UsQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_load_b32, "UiQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_load_b64, "V2UiQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_load_b96, "V3UiQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_load_b128, "V4UiQbiiIi", "n") //===----------------------------------------------------------------------===// // Ballot builtins. @@ -450,8 +456,12 @@ TARGET_BUILTIN(__builtin_amdgcn_s_get_barrier_state, "Uii", "n", "gfx12-insts") TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b64_v2i32, "V2iV2i*1", "nc", "gfx12-insts,wavefrontsize32") TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v8i16, "V8sV8s*1", "nc", "gfx12-insts,wavefrontsize32") +TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v8f16, "V8hV8h*1", "nc", "gfx12-insts,wavefrontsize32") +TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v8bf16, "V8yV8y*1", "nc", "gfx12-insts,wavefrontsize32") TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b64_i32, "ii*1", "nc", "gfx12-insts,wavefrontsize64") TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v4i16, "V4sV4s*1", "nc", "gfx12-insts,wavefrontsize64") +TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v4f16, "V4hV4h*1", "nc", "gfx12-insts,wavefrontsize64") +TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v4bf16, "V4yV4y*1", "nc", "gfx12-insts,wavefrontsize64") //===----------------------------------------------------------------------===// // WMMA builtins. diff --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def b/clang/include/clang/Basic/BuiltinsWebAssembly.def index 2a45f8a6582a2..df304a71e475e 100644 --- a/clang/include/clang/Basic/BuiltinsWebAssembly.def +++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -201,6 +201,7 @@ TARGET_BUILTIN(__builtin_wasm_loadf16_f32, "fh*", "nU", "half-precision") TARGET_BUILTIN(__builtin_wasm_storef16_f32, "vfh*", "n", "half-precision") TARGET_BUILTIN(__builtin_wasm_splat_f16x8, "V8hf", "nc", "half-precision") TARGET_BUILTIN(__builtin_wasm_extract_lane_f16x8, "fV8hi", "nc", "half-precision") +TARGET_BUILTIN(__builtin_wasm_replace_lane_f16x8, "V8hV8hif", "nc", "half-precision") // Reference Types builtins // Some builtins are custom type-checked - see 't' as part of the third argument, diff --git a/clang/include/clang/Basic/BuiltinsX86.def b/clang/include/clang/Basic/BuiltinsX86.def index a85e7918f4d7e..06ca30d65f5bd 100644 --- a/clang/include/clang/Basic/BuiltinsX86.def +++ b/clang/include/clang/Basic/BuiltinsX86.def @@ -47,107 +47,8 @@ TARGET_BUILTIN(__builtin_ia32_writeeflags_u32, "vUi", "n", "") // doesn't work in the presence of re-declaration of _mm_prefetch for windows. TARGET_BUILTIN(_mm_prefetch, "vcC*i", "nc", "mmx") TARGET_BUILTIN(__builtin_ia32_emms, "v", "n", "mmx") -TARGET_BUILTIN(__builtin_ia32_paddb, "V8cV8cV8c", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_paddw, "V4sV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_paddd, "V2iV2iV2i", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_paddsb, "V8cV8cV8c", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_paddsw, "V4sV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_paddusb, "V8cV8cV8c", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_paddusw, "V4sV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psubb, "V8cV8cV8c", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psubw, "V4sV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psubd, "V2iV2iV2i", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psubsb, "V8cV8cV8c", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psubsw, "V4sV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psubusb, "V8cV8cV8c", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psubusw, "V4sV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pmulhw, "V4sV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pmullw, "V4sV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pmaddwd, "V2iV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pand, "V1OiV1OiV1Oi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pandn, "V1OiV1OiV1Oi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_por, "V1OiV1OiV1Oi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pxor, "V1OiV1OiV1Oi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psllw, "V4sV4sV1Oi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pslld, "V2iV2iV1Oi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psllq, "V1OiV1OiV1Oi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrlw, "V4sV4sV1Oi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrld, "V2iV2iV1Oi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrlq, "V1OiV1OiV1Oi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psraw, "V4sV4sV1Oi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrad, "V2iV2iV1Oi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psllwi, "V4sV4si", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pslldi, "V2iV2ii", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psllqi, "V1OiV1Oii", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrlwi, "V4sV4si", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrldi, "V2iV2ii", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrlqi, "V1OiV1Oii", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrawi, "V4sV4si", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psradi, "V2iV2ii", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_packsswb, "V8cV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_packssdw, "V4sV2iV2i", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_packuswb, "V8cV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_punpckhbw, "V8cV8cV8c", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_punpckhwd, "V4sV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_punpckhdq, "V2iV2iV2i", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_punpcklbw, "V8cV8cV8c", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_punpcklwd, "V4sV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_punpckldq, "V2iV2iV2i", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pcmpeqb, "V8cV8cV8c", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pcmpeqw, "V4sV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pcmpeqd, "V2iV2iV2i", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pcmpgtb, "V8cV8cV8c", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pcmpgtw, "V4sV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pcmpgtd, "V2iV2iV2i", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_maskmovq, "vV8cV8cc*", "nV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_movntq, "vV1Oi*V1Oi", "nV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_vec_init_v2si, "V2iii", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_vec_init_v4hi, "V4sssss", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_vec_init_v8qi, "V8ccccccccc", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_vec_ext_v2si, "iV2ii", "ncV:64:", "mmx") - -// MMX2 (MMX+SSE) intrinsics -TARGET_BUILTIN(__builtin_ia32_cvtpi2ps, "V4fV4fV2i", "ncV:64:", "mmx,sse") -TARGET_BUILTIN(__builtin_ia32_cvtps2pi, "V2iV4f", "ncV:64:", "mmx,sse") -TARGET_BUILTIN(__builtin_ia32_cvttps2pi, "V2iV4f", "ncV:64:", "mmx,sse") -TARGET_BUILTIN(__builtin_ia32_pavgb, "V8cV8cV8c", "ncV:64:", "mmx,sse") -TARGET_BUILTIN(__builtin_ia32_pavgw, "V4sV4sV4s", "ncV:64:", "mmx,sse") -TARGET_BUILTIN(__builtin_ia32_pmaxsw, "V4sV4sV4s", "ncV:64:", "mmx,sse") -TARGET_BUILTIN(__builtin_ia32_pmaxub, "V8cV8cV8c", "ncV:64:", "mmx,sse") -TARGET_BUILTIN(__builtin_ia32_pminsw, "V4sV4sV4s", "ncV:64:", "mmx,sse") -TARGET_BUILTIN(__builtin_ia32_pminub, "V8cV8cV8c", "ncV:64:", "mmx,sse") -TARGET_BUILTIN(__builtin_ia32_pmovmskb, "iV8c", "ncV:64:", "mmx,sse") -TARGET_BUILTIN(__builtin_ia32_pmulhuw, "V4sV4sV4s", "ncV:64:", "mmx,sse") -TARGET_BUILTIN(__builtin_ia32_psadbw, "V4sV8cV8c", "ncV:64:", "mmx,sse") -TARGET_BUILTIN(__builtin_ia32_pshufw, "V4sV4sIc", "ncV:64:", "mmx,sse") -TARGET_BUILTIN(__builtin_ia32_vec_ext_v4hi, "iV4sIi", "ncV:64:", "mmx,sse") -TARGET_BUILTIN(__builtin_ia32_vec_set_v4hi, "V4sV4siIi", "ncV:64:", "mmx,sse") - -// MMX+SSE2 -TARGET_BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "ncV:64:", "mmx,sse2") -TARGET_BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "ncV:64:", "mmx,sse2") -TARGET_BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "ncV:64:", "mmx,sse2") -TARGET_BUILTIN(__builtin_ia32_paddq, "V1OiV1OiV1Oi", "ncV:64:", "mmx,sse2") -TARGET_BUILTIN(__builtin_ia32_pmuludq, "V1OiV2iV2i", "ncV:64:", "mmx,sse2") -TARGET_BUILTIN(__builtin_ia32_psubq, "V1OiV1OiV1Oi", "ncV:64:", "mmx,sse2") - -// MMX+SSSE3 -TARGET_BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "ncV:64:", "mmx,ssse3") -TARGET_BUILTIN(__builtin_ia32_pabsd, "V2iV2i", "ncV:64:", "mmx,ssse3") -TARGET_BUILTIN(__builtin_ia32_pabsw, "V4sV4s", "ncV:64:", "mmx,ssse3") -TARGET_BUILTIN(__builtin_ia32_palignr, "V8cV8cV8cIc", "ncV:64:", "mmx,ssse3") -TARGET_BUILTIN(__builtin_ia32_phaddd, "V2iV2iV2i", "ncV:64:", "mmx,ssse3") -TARGET_BUILTIN(__builtin_ia32_phaddsw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3") -TARGET_BUILTIN(__builtin_ia32_phaddw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3") -TARGET_BUILTIN(__builtin_ia32_phsubd, "V2iV2iV2i", "ncV:64:", "mmx,ssse3") -TARGET_BUILTIN(__builtin_ia32_phsubsw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3") -TARGET_BUILTIN(__builtin_ia32_phsubw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3") -TARGET_BUILTIN(__builtin_ia32_pmaddubsw, "V8cV8cV8c", "ncV:64:", "mmx,ssse3") -TARGET_BUILTIN(__builtin_ia32_pmulhrsw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3") -TARGET_BUILTIN(__builtin_ia32_pshufb, "V8cV8cV8c", "ncV:64:", "mmx,ssse3") -TARGET_BUILTIN(__builtin_ia32_psignw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3") -TARGET_BUILTIN(__builtin_ia32_psignb, "V8cV8cV8c", "ncV:64:", "mmx,ssse3") -TARGET_BUILTIN(__builtin_ia32_psignd, "V2iV2iV2i", "ncV:64:", "mmx,ssse3") +TARGET_BUILTIN(__builtin_ia32_vec_ext_v4hi, "sV4sIi", "ncV:64:", "sse") +TARGET_BUILTIN(__builtin_ia32_vec_set_v4hi, "V4sV4ssIi", "ncV:64:", "sse") // SSE intrinsics. TARGET_BUILTIN(__builtin_ia32_comieq, "iV4fV4f", "ncV:128:", "sse") diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index be2884913355b..2e92c6ae23d7f 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -235,6 +235,7 @@ ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, SRCK_Defa CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions. CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled. +CODEGENOPT(PointerTBAA, 1, 0) ///< Whether or not to use distinct TBAA tags for pointers. CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use struct-path TBAA. CODEGENOPT(NewStructPathTBAA , 1, 0) ///< Whether or not to use enhanced struct-path TBAA. CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels. @@ -431,6 +432,9 @@ CODEGENOPT(ForceAAPCSBitfieldLoad, 1, 0) /// Assume that by-value parameters do not alias any other values. CODEGENOPT(PassByValueIsNoAlias, 1, 0) +/// Whether to store register parameters to stack. +CODEGENOPT(SaveRegParams, 1, 0) + /// Whether to not follow the AAPCS that enforces volatile bit-field access width to be /// according to the field declaring type width. CODEGENOPT(AAPCSBitfieldWidth, 1, 1) diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index fe950ec834d2f..68b0bf529bc93 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -167,6 +167,8 @@ def err_drv_unsupported_rtlib_for_platform : Error< "unsupported runtime library '%0' for platform '%1'">; def err_drv_invalid_unwindlib_name : Error< "invalid unwind library name in argument '%0'">; +def err_drv_unsupported_unwind_for_platform : Error< + "unsupported unwind library '%0' for platform '%1'">; def err_drv_incompatible_unwindlib : Error< "--rtlib=libgcc requires --unwindlib=libgcc">; def err_drv_incompatible_fp_accuracy_options : Error< @@ -505,6 +507,10 @@ def warn_drv_deprecated_arg : Warning< def warn_drv_deprecated_arg_no_relaxed_template_template_args : Warning< "argument '-fno-relaxed-template-template-args' is deprecated">, InGroup; +def warn_drv_deprecated_arg_ofast : Warning< + "argument '-Ofast' is deprecated; use '-O3 -ffast-math' for the same behavior," + " or '-O3' to enable only conforming optimizations">, + InGroup; def warn_drv_deprecated_custom : Warning< "argument '%0' is deprecated, %1">, InGroup; def warn_drv_assuming_mfloat_abi_is : Warning< diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 6bde60b57bf10..2c4220842913a 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -288,6 +288,9 @@ def err_function_needs_feature : Error< let CategoryName = "Codegen ABI Check" in { def err_function_always_inline_attribute_mismatch : Error< "always_inline function %1 and its caller %0 have mismatching %2 attributes">; +def warn_function_always_inline_attribute_mismatch : Warning< + "always_inline function %1 and its caller %0 have mismatching %2 attributes, " + "inlining may change runtime behaviour">, InGroup; def err_function_always_inline_new_za : Error< "always_inline function %0 has new za state">; diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 1777843eb9973..763fa9081b418 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -103,6 +103,7 @@ def EnumConversion : DiagGroup<"enum-conversion", EnumFloatConversion, EnumCompareConditional]>; def DeprecatedNoRelaxedTemplateTemplateArgs : DiagGroup<"deprecated-no-relaxed-template-template-args">; +def DeprecatedOFast : DiagGroup<"deprecated-ofast">; def ObjCSignedCharBoolImplicitIntConversion : DiagGroup<"objc-signed-char-bool-implicit-int-conversion">; def Shorten64To32 : DiagGroup<"shorten-64-to-32">; @@ -230,6 +231,7 @@ def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion, DeprecatedPragma, DeprecatedRegister, DeprecatedNoRelaxedTemplateTemplateArgs, + DeprecatedOFast, DeprecatedThisCapture, DeprecatedType, DeprecatedVolatile, @@ -453,6 +455,7 @@ def LogicalNotParentheses: DiagGroup<"logical-not-parentheses">; def ShiftOpParentheses: DiagGroup<"shift-op-parentheses">; def OverloadedShiftOpParentheses: DiagGroup<"overloaded-shift-op-parentheses">; def DanglingAssignment: DiagGroup<"dangling-assignment">; +def DanglingAssignmentGsl : DiagGroup<"dangling-assignment-gsl">; def DanglingElse: DiagGroup<"dangling-else">; def DanglingField : DiagGroup<"dangling-field">; def DanglingInitializerList : DiagGroup<"dangling-initializer-list">; @@ -461,6 +464,7 @@ def ReturnStackAddress : DiagGroup<"return-stack-address">; // Name of this warning in GCC def : DiagGroup<"return-local-addr", [ReturnStackAddress]>; def Dangling : DiagGroup<"dangling", [DanglingAssignment, + DanglingAssignmentGsl, DanglingField, DanglingInitializerList, DanglingGsl, diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 12aab09f28556..f8d50d12bb935 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1260,6 +1260,9 @@ def warn_pragma_intrinsic_builtin : Warning< def warn_pragma_unused_expected_var : Warning< "expected '#pragma unused' argument to be a variable name">, InGroup; +// - #pragma mc_func +def err_pragma_mc_func_not_supported : + Error<"#pragma mc_func is not supported">; // - #pragma init_seg def warn_pragma_init_seg_unsupported_target : Warning< "'#pragma init_seg' is only supported when targeting a " diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 59e671caf8c68..856a8f676fa45 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1010,6 +1010,9 @@ def warn_ptrauth_auth_null_pointer : InGroup; def err_ptrauth_string_not_literal : Error< "argument must be a string literal%select{| of char type}0">; +def err_ptrauth_type_disc_undiscriminated : Error< + "cannot pass undiscriminated type %0 to " + "'__builtin_ptrauth_type_discriminator'">; def note_ptrauth_virtual_function_pointer_incomplete_arg_ret : Note<"cannot take an address of a virtual member function if its return or " @@ -1017,6 +1020,9 @@ def note_ptrauth_virtual_function_pointer_incomplete_arg_ret : def note_ptrauth_virtual_function_incomplete_arg_ret_type : Note<"%0 is incomplete">; +def err_ptrauth_indirect_goto_addrlabel_arithmetic : Error< + "%select{subtraction|addition}0 of address-of-label expressions is not " + "supported with ptrauth indirect gotos">; /// main() // static main() is not an error in C, just in C++. @@ -3398,10 +3404,16 @@ def err_attribute_invalid_implicit_this_argument : Error< "%0 attribute is invalid for the implicit this argument">; def err_ownership_type : Error< "%0 attribute only applies to %select{pointer|integer}1 arguments">; +def err_ownership_takes_return_type : Error< + "'ownership_returns' attribute only applies to functions that return a pointer">; def err_ownership_returns_index_mismatch : Error< "'ownership_returns' attribute index does not match; here it is %0">; def note_ownership_returns_index_mismatch : Note< "declared with index %0 here">; +def err_ownership_takes_class_mismatch : Error< + "'ownership_takes' attribute class does not match; here it is '%0'">; +def note_ownership_takes_class_mismatch : Note< + "declared with class '%0' here">; def err_format_strftime_third_parameter : Error< "strftime format attribute requires 3rd parameter to be 0">; def err_format_attribute_not : Error<"format argument not a string type">; @@ -3566,7 +3578,7 @@ def err_attr_tlsmodel_arg : Error<"tls_model must be \"global-dynamic\", " def err_attr_codemodel_arg : Error<"code model '%0' is not supported on this target">; -def err_aix_attr_unsupported_tls_model : Error<"TLS model '%0' is not yet supported on AIX">; +def err_aix_attr_unsupported : Error<"%0 attribute is not yet supported on AIX">; def err_tls_var_aligned_over_maximum : Error< "alignment (%0) of thread-local variable %1 is greater than the maximum supported " @@ -3752,6 +3764,9 @@ def err_attribute_weak_static : Error< "weak declaration cannot have internal linkage">; def err_attribute_selectany_non_extern_data : Error< "'selectany' can only be applied to data items with external linkage">; +def warn_attribute_hybrid_patchable_non_extern : Warning< + "'hybrid_patchable' is ignored on functions without external linkage">, + InGroup; def err_declspec_thread_on_thread_variable : Error< "'__declspec(thread)' applied to variable that already has a " "thread-local storage specifier">; @@ -3885,8 +3900,6 @@ def warn_sme_locally_streaming_has_vl_args_returns : Warning< InGroup, DefaultIgnore; def err_conflicting_attributes_arm_state : Error< "conflicting attributes for state '%0'">; -def err_sme_streaming_cannot_be_multiversioned : Error< - "streaming function cannot be multi-versioned">; def err_unknown_arm_state : Error< "unknown state '%0'">; def err_missing_arm_state : Error< @@ -5250,7 +5263,7 @@ def warn_cxx11_compat_variable_template : Warning< InGroup, DefaultIgnore; def err_template_variable_noparams : Error< "extraneous 'template<>' in declaration of variable %0">; -def err_template_member : Error<"member %0 declared as a template">; +def err_template_member : Error<"non-static data member %0 cannot be declared as a template">; def err_member_with_template_arguments : Error<"member %0 cannot have template arguments">; def err_template_member_noparams : Error< "extraneous 'template<>' in declaration of member %0">; @@ -7685,9 +7698,6 @@ def err_nested_non_static_member_use : Error< def warn_cxx98_compat_non_static_member_use : Warning< "use of non-static data member %0 in an unevaluated context is " "incompatible with C++98">, InGroup, DefaultIgnore; -def err_form_ptr_to_member_from_parenthesized_expr : Error< - "cannot form pointer to member from a parenthesized expression; " - "did you mean to remove the parentheses?">; def err_invalid_incomplete_type_use : Error< "invalid use of incomplete type %0">; def err_builtin_func_cast_more_than_one_arg : Error< @@ -10227,6 +10237,9 @@ def warn_dangling_lifetime_pointer : Warning< "object backing the pointer " "will be destroyed at the end of the full-expression">, InGroup; +def warn_dangling_lifetime_pointer_assignment : Warning<"object backing the " + "pointer %0 will be destroyed at the end of the full-expression">, + InGroup; def warn_new_dangling_initializer_list : Warning< "array backing " "%select{initializer list subobject of the allocated object|" diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td index eb27de5921d6a..51d0abbbec252 100644 --- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td @@ -50,14 +50,14 @@ def warn_pch_vfsoverlay_mismatch : Warning< def note_pch_vfsoverlay_files : Note<"%select{PCH|current translation unit}0 has the following VFS overlays:\n%1">; def note_pch_vfsoverlay_empty : Note<"%select{PCH|current translation unit}0 has no VFS overlays">; -def err_pch_version_too_old : Error< - "PCH file uses an older PCH format that is no longer supported">; -def err_pch_version_too_new : Error< - "PCH file uses a newer PCH format that cannot be read">; -def err_pch_different_branch : Error< - "PCH file built from a different branch (%0) than the compiler (%1)">; -def err_pch_with_compiler_errors : Error< - "PCH file contains compiler errors">; +def err_ast_file_version_too_old : Error< + "%select{PCH|module|AST}0 file '%1' uses an older PCH format that is no longer supported">; +def err_ast_file_version_too_new : Error< + "%select{PCH|module|AST}0 file '%1' uses a newer PCH format that cannot be read">; +def err_ast_file_different_branch : Error< + "%select{PCH|module|AST}0 file '%1' built from a different branch (%2) than the compiler (%3)">; +def err_ast_file_with_compiler_errors : Error< + "%select{PCH|module|AST}0 file '%1' contains compiler errors">; def err_module_file_conflict : Error< "module '%0' is defined in both '%1' and '%2'">, DefaultFatal; diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 2f864ff1c0edf..dc71ef8f98692 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -108,9 +108,11 @@ FEATURE(ptrauth_calls, LangOpts.PointerAuthCalls) FEATURE(ptrauth_returns, LangOpts.PointerAuthReturns) FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtrAddressDiscrimination) FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination) +FEATURE(ptrauth_type_info_vtable_pointer_discrimination, LangOpts.PointerAuthTypeInfoVTPtrDiscrimination) FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls) FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini) FEATURE(ptrauth_function_pointer_type_discrimination, LangOpts.PointerAuthFunctionTypeDiscrimination) +FEATURE(ptrauth_indirect_gotos, LangOpts.PointerAuthIndirectGotos) EXTENSION(swiftcc, PP.getTargetInfo().checkCallingConvention(CC_Swift) == clang::TargetInfo::CCCR_OK) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 3ea0dfada1ecd..a68d140bf104a 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -165,9 +165,11 @@ LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library fea LANGOPT(PointerAuthIntrinsics, 1, 0, "pointer authentication intrinsics") LANGOPT(PointerAuthCalls , 1, 0, "function pointer authentication") LANGOPT(PointerAuthReturns, 1, 0, "return pointer authentication") +LANGOPT(PointerAuthIndirectGotos, 1, 0, "indirect gotos pointer authentication") LANGOPT(PointerAuthAuthTraps, 1, 0, "pointer authentication failure traps") LANGOPT(PointerAuthVTPtrAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated vtable pointers") LANGOPT(PointerAuthVTPtrTypeDiscrimination, 1, 0, "incorporate type discrimination in authenticated vtable pointers") +LANGOPT(PointerAuthTypeInfoVTPtrDiscrimination, 1, 0, "incorporate type and address discrimination in authenticated vtable pointers for std::type_info") LANGOPT(PointerAuthInitFini, 1, 0, "sign function pointers in init/fini arrays") BENIGN_LANGOPT(PointerAuthFunctionTypeDiscrimination, 1, 0, "Use type discrimination when signing function pointers") @@ -222,7 +224,6 @@ COMPATIBLE_LANGOPT(GNUInline , 1, 0, "GNU inline semantics") COMPATIBLE_LANGOPT(NoInlineDefine , 1, 0, "__NO_INLINE__ predefined macro") COMPATIBLE_LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro") COMPATIBLE_LANGOPT(FastMath , 1, 0, "fast FP math optimizations, and __FAST_MATH__ predefined macro") -COMPATIBLE_LANGOPT(FiniteMathOnly , 1, 0, "__FINITE_MATH_ONLY__ predefined macro") COMPATIBLE_LANGOPT(UnsafeFPMath , 1, 0, "Unsafe Floating Point Math") COMPATIBLE_LANGOPT(ProtectParens , 1, 0, "optimizer honors parentheses " "when floating-point expressions are evaluated") @@ -361,7 +362,6 @@ LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating poi LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math") BENIGN_LANGOPT(CLNoSignedZero , 1, 0, "Permit Floating Point optimization without regard to signed zeros") COMPATIBLE_LANGOPT(CLUnsafeMath , 1, 0, "Unsafe Floating Point Math") -COMPATIBLE_LANGOPT(CLFiniteMathOnly , 1, 0, "__FINITE_MATH_ONLY__ predefined macro") /// FP_CONTRACT mode (on/off/fast). BENIGN_ENUM_LANGOPT(DefaultFPContractMode, FPModeKind, 2, FPM_Off, "FP contraction type") COMPATIBLE_LANGOPT(ExpStrictFP, 1, false, "Enable experimental strict floating point") @@ -553,6 +553,9 @@ BENIGN_LANGOPT(CheckNew, 1, 0, "Do not assume C++ operator new may not return NU BENIGN_LANGOPT(CheckConstexprFunctionBodies, 1, 1, "Emit diagnostics for a constexpr function body that can never " "be used in a constant expression.") + +LANGOPT(BoundsSafety, 1, 0, "Bounds safety extension for C") + #undef LANGOPT #undef COMPATIBLE_LANGOPT #undef BENIGN_LANGOPT diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index f46a92d5ecfd4..51084913bf102 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -107,6 +107,7 @@ OPENMP_DEVICE_MODIFIER(device_num) OPENMP_DEFAULTMAP_KIND(scalar) OPENMP_DEFAULTMAP_KIND(aggregate) OPENMP_DEFAULTMAP_KIND(pointer) +OPENMP_DEFAULTMAP_KIND(all) // Modifiers for 'defaultmap' clause. OPENMP_DEFAULTMAP_MODIFIER(alloc) diff --git a/clang/include/clang/Basic/PointerAuthOptions.h b/clang/include/clang/Basic/PointerAuthOptions.h index 197d63642ca6d..417b4b00648c7 100644 --- a/clang/include/clang/Basic/PointerAuthOptions.h +++ b/clang/include/clang/Basic/PointerAuthOptions.h @@ -25,6 +25,11 @@ namespace clang { constexpr unsigned PointerAuthKeyNone = -1; +/// Constant discriminator for std::type_info vtable pointers: 0xB1EA/45546 +/// The value is ptrauth_string_discriminator("_ZTVSt9type_info"), i.e., +/// the vtable type discriminator for classes derived from std::type_info. +constexpr uint16_t StdTypeInfoVTablePointerConstantDiscrimination = 0xB1EA; + class PointerAuthSchema { public: enum class Kind : unsigned { @@ -154,6 +159,9 @@ class PointerAuthSchema { }; struct PointerAuthOptions { + /// Do indirect goto label addresses need to be authenticated? + bool IndirectGotos = false; + /// The ABI for C function pointers. PointerAuthSchema FunctionPointers; @@ -175,6 +183,9 @@ struct PointerAuthOptions { /// The ABI for variadic C++ virtual function pointers. PointerAuthSchema CXXVirtualVariadicFunctionPointers; + + /// The ABI for C++ member function pointers. + PointerAuthSchema CXXMemberFunctionPointers; }; } // end namespace clang diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index 542d94f96c7b7..4a4a8892a81a4 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -237,6 +237,8 @@ def OMPSimdDirective : StmtNode; def OMPLoopTransformationDirective : StmtNode; def OMPTileDirective : StmtNode; def OMPUnrollDirective : StmtNode; +def OMPReverseDirective : StmtNode; +def OMPInterchangeDirective : StmtNode; def OMPForDirective : StmtNode; def OMPForSimdDirective : StmtNode; def OMPSectionsDirective : StmtNode; diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index a4efaba796fb0..2f1bf4314e814 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -502,6 +502,7 @@ TYPE_TRAIT_1(__has_trivial_move_assign, HasTrivialMoveAssign, KEYCXX) TYPE_TRAIT_1(__has_trivial_move_constructor, HasTrivialMoveConstructor, KEYCXX) // GNU and MS Type Traits +TYPE_TRAIT_2(__builtin_is_virtual_base_of, IsVirtualBaseOf, KEYCXX) TYPE_TRAIT_1(__has_nothrow_assign, HasNothrowAssign, KEYCXX) TYPE_TRAIT_1(__has_nothrow_copy, HasNothrowCopy, KEYCXX) TYPE_TRAIT_1(__has_nothrow_constructor, HasNothrowConstructor, KEYCXX) @@ -603,6 +604,8 @@ ALIAS("__is_same_as", __is_same, KEYCXX) KEYWORD(__private_extern__ , KEYALL) KEYWORD(__module_private__ , KEYALL) +UNARY_EXPR_OR_TYPE_TRAIT(__builtin_ptrauth_type_discriminator, PtrAuthTypeDiscriminator, KEYALL) + // Extension that will be enabled for Microsoft, Borland and PS4, but can be // disabled via '-fno-declspec'. KEYWORD(__declspec , 0) diff --git a/clang/include/clang/Basic/arm_neon.td b/clang/include/clang/Basic/arm_neon.td index 6390ba3f9fe5e..3098fa67e6a51 100644 --- a/clang/include/clang/Basic/arm_neon.td +++ b/clang/include/clang/Basic/arm_neon.td @@ -289,7 +289,7 @@ def SPLATQ : WInst<"splat_laneq", ".(!Q)I", "UcUsUicsilPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUlhdQhQdPlQPl"> { let isLaneQ = 1; } -let TargetGuard = "bf16" in { +let TargetGuard = "bf16,neon" in { def SPLAT_BF : WInst<"splat_lane", ".(!q)I", "bQb">; def SPLATQ_BF : WInst<"splat_laneq", ".(!Q)I", "bQb"> { let isLaneQ = 1; @@ -323,7 +323,7 @@ def VMLSL : SOpInst<"vmlsl", "(>Q)(>Q)..", "csiUcUsUi", OP_MLSL>; def VQDMULH : SInst<"vqdmulh", "...", "siQsQi">; def VQRDMULH : SInst<"vqrdmulh", "...", "siQsQi">; -let TargetGuard = "v8.1a" in { +let TargetGuard = "v8.1a,neon" in { def VQRDMLAH : SInst<"vqrdmlah", "....", "siQsQi">; def VQRDMLSH : SInst<"vqrdmlsh", "....", "siQsQi">; } @@ -614,7 +614,7 @@ def A64_VQDMULH_LANE : SInst<"vqdmulh_lane", "..(!q)I", "siQsQi">; def A64_VQRDMULH_LANE : SInst<"vqrdmulh_lane", "..(!q)I", "siQsQi">; } -let TargetGuard = "v8.1a" in { +let TargetGuard = "v8.1a,neon" in { def VQRDMLAH_LANE : SOpInst<"vqrdmlah_lane", "...qI", "siQsQi", OP_QRDMLAH_LN>; def VQRDMLSH_LANE : SOpInst<"vqrdmlsh_lane", "...qI", "siQsQi", OP_QRDMLSH_LN>; } @@ -957,7 +957,7 @@ def VQDMLAL_HIGH : SOpInst<"vqdmlal_high", "(>Q)(>Q)QQ", "si", OP_QDMLALHi>; def VQDMLAL_HIGH_N : SOpInst<"vqdmlal_high_n", "(>Q)(>Q)Q1", "si", OP_QDMLALHi_N>; def VQDMLSL_HIGH : SOpInst<"vqdmlsl_high", "(>Q)(>Q)QQ", "si", OP_QDMLSLHi>; def VQDMLSL_HIGH_N : SOpInst<"vqdmlsl_high_n", "(>Q)(>Q)Q1", "si", OP_QDMLSLHi_N>; -let TargetGuard = "aes" in { +let TargetGuard = "aes,neon" in { def VMULL_P64 : SInst<"vmull", "(1>)11", "Pl">; def VMULL_HIGH_P64 : SOpInst<"vmull_high", "(1>)..", "HPl", OP_MULLHi_P64>; } @@ -1091,7 +1091,7 @@ let isLaneQ = 1 in { def VQDMULH_LANEQ : SInst<"vqdmulh_laneq", "..QI", "siQsQi">; def VQRDMULH_LANEQ : SInst<"vqrdmulh_laneq", "..QI", "siQsQi">; } -let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.1a" in { +let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.1a,neon" in { def VQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "...QI", "siQsQi", OP_QRDMLAH_LN> { let isLaneQ = 1; } @@ -1122,14 +1122,14 @@ def VEXT_A64 : WInst<"vext", "...I", "dQdPlQPl">; //////////////////////////////////////////////////////////////////////////////// // Crypto -let ArchGuard = "__ARM_ARCH >= 8", TargetGuard = "aes" in { +let ArchGuard = "__ARM_ARCH >= 8", TargetGuard = "aes,neon" in { def AESE : SInst<"vaese", "...", "QUc">; def AESD : SInst<"vaesd", "...", "QUc">; def AESMC : SInst<"vaesmc", "..", "QUc">; def AESIMC : SInst<"vaesimc", "..", "QUc">; } -let ArchGuard = "__ARM_ARCH >= 8", TargetGuard = "sha2" in { +let ArchGuard = "__ARM_ARCH >= 8", TargetGuard = "sha2,neon" in { def SHA1H : SInst<"vsha1h", "11", "Ui">; def SHA1SU1 : SInst<"vsha1su1", "...", "QUi">; def SHA256SU0 : SInst<"vsha256su0", "...", "QUi">; @@ -1143,7 +1143,7 @@ def SHA256H2 : SInst<"vsha256h2", "....", "QUi">; def SHA256SU1 : SInst<"vsha256su1", "....", "QUi">; } -let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sha3" in { +let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sha3,neon" in { def BCAX : SInst<"vbcax", "....", "QUcQUsQUiQUlQcQsQiQl">; def EOR3 : SInst<"veor3", "....", "QUcQUsQUiQUlQcQsQiQl">; def RAX1 : SInst<"vrax1", "...", "QUl">; @@ -1153,14 +1153,14 @@ def XAR : SInst<"vxar", "...I", "QUl">; } } -let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sha3" in { +let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sha3,neon" in { def SHA512SU0 : SInst<"vsha512su0", "...", "QUl">; def SHA512su1 : SInst<"vsha512su1", "....", "QUl">; def SHA512H : SInst<"vsha512h", "....", "QUl">; def SHA512H2 : SInst<"vsha512h2", "....", "QUl">; } -let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sm4" in { +let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sm4,neon" in { def SM3SS1 : SInst<"vsm3ss1", "....", "QUi">; def SM3TT1A : SInst<"vsm3tt1a", "....I", "QUi">; def SM3TT1B : SInst<"vsm3tt1b", "....I", "QUi">; @@ -1170,7 +1170,7 @@ def SM3PARTW1 : SInst<"vsm3partw1", "....", "QUi">; def SM3PARTW2 : SInst<"vsm3partw2", "....", "QUi">; } -let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sm4" in { +let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sm4,neon" in { def SM4E : SInst<"vsm4e", "...", "QUi">; def SM4EKEY : SInst<"vsm4ekey", "...", "QUi">; } @@ -1227,7 +1227,7 @@ def FRINTZ_S64 : SInst<"vrnd", "..", "dQd">; def FRINTI_S64 : SInst<"vrndi", "..", "dQd">; } -let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.5a" in { +let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.5a,neon" in { def FRINT32X_S32 : SInst<"vrnd32x", "..", "fQf">; def FRINT32Z_S32 : SInst<"vrnd32z", "..", "fQf">; def FRINT64X_S32 : SInst<"vrnd64x", "..", "fQf">; @@ -1401,7 +1401,7 @@ def SCALAR_SQDMULH : SInst<"vqdmulh", "111", "SsSi">; // Scalar Integer Saturating Rounding Doubling Multiply Half High def SCALAR_SQRDMULH : SInst<"vqrdmulh", "111", "SsSi">; -let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.1a" in { +let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.1a,neon" in { //////////////////////////////////////////////////////////////////////////////// // Signed Saturating Rounding Doubling Multiply Accumulate Returning High Half def SCALAR_SQRDMLAH : SInst<"vqrdmlah", "1111", "SsSi">; @@ -1632,7 +1632,7 @@ def SCALAR_SQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "11QI", "SsSi", OP_SCALAR_ let isLaneQ = 1; } -let TargetGuard = "v8.1a" in { +let TargetGuard = "v8.1a,neon" in { // Signed Saturating Rounding Doubling Multiply Accumulate Returning High Half def SCALAR_SQRDMLAH_LANE : SOpInst<"vqrdmlah_lane", "111.I", "SsSi", OP_SCALAR_QRDMLAH_LN>; def SCALAR_SQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "111QI", "SsSi", OP_SCALAR_QRDMLAH_LN> { @@ -1654,7 +1654,7 @@ def SCALAR_VDUP_LANEQ : IInst<"vdup_laneq", "1QI", "ScSsSiSlSfSdSUcSUsSUiSUlSPcS } // ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)" // ARMv8.2-A FP16 vector intrinsics for A32/A64. -let TargetGuard = "fullfp16" in { +let TargetGuard = "fullfp16,neon" in { // ARMv8.2-A FP16 one-operand vector intrinsics. @@ -1679,7 +1679,7 @@ let TargetGuard = "fullfp16" in { def VCVTP_U16 : SInst<"vcvtp_u16", "U.", "hQh">; // Vector rounding - let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_DIRECTED_ROUNDING)", TargetGuard = "fullfp16" in { + let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_DIRECTED_ROUNDING)", TargetGuard = "fullfp16,neon" in { def FRINTZH : SInst<"vrnd", "..", "hQh">; def FRINTNH : SInst<"vrndn", "..", "hQh">; def FRINTAH : SInst<"vrnda", "..", "hQh">; @@ -1728,7 +1728,7 @@ let TargetGuard = "fullfp16" in { // Max/Min def VMAXH : SInst<"vmax", "...", "hQh">; def VMINH : SInst<"vmin", "...", "hQh">; - let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_NUMERIC_MAXMIN)", TargetGuard = "fullfp16" in { + let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_NUMERIC_MAXMIN)", TargetGuard = "fullfp16,neon" in { def FMAXNMH : SInst<"vmaxnm", "...", "hQh">; def FMINNMH : SInst<"vminnm", "...", "hQh">; } @@ -1775,7 +1775,7 @@ def VEXTH : WInst<"vext", "...I", "hQh">; def VREV64H : WOpInst<"vrev64", "..", "hQh", OP_REV64>; // ARMv8.2-A FP16 vector intrinsics for A64 only. -let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "fullfp16" in { +let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "fullfp16,neon" in { // Vector rounding def FRINTIH : SInst<"vrndi", "..", "hQh">; @@ -1872,11 +1872,11 @@ let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)" in { } // v8.2-A dot product instructions. -let TargetGuard = "dotprod" in { +let TargetGuard = "dotprod,neon" in { def DOT : SInst<"vdot", "..(<<)(<<)", "iQiUiQUi">; def DOT_LANE : SOpInst<"vdot_lane", "..(<<)(<; } -let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "dotprod" in { +let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "dotprod,neon" in { // Variants indexing into a 128-bit vector are A64 only. def UDOT_LANEQ : SOpInst<"vdot_laneq", "..(<<)(< { let isLaneQ = 1; @@ -1884,7 +1884,7 @@ let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "d } // v8.2-A FP16 fused multiply-add long instructions. -let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "fp16fml" in { +let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "fp16fml,neon" in { def VFMLAL_LOW : SInst<"vfmlal_low", ">>..", "hQh">; def VFMLSL_LOW : SInst<"vfmlsl_low", ">>..", "hQh">; def VFMLAL_HIGH : SInst<"vfmlal_high", ">>..", "hQh">; @@ -1909,7 +1909,7 @@ let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "f } } -let TargetGuard = "i8mm" in { +let TargetGuard = "i8mm,neon" in { def VMMLA : SInst<"vmmla", "..(<<)(<<)", "QUiQi">; def VUSMMLA : SInst<"vusmmla", "..(<; @@ -1926,7 +1926,7 @@ let TargetGuard = "i8mm" in { } } -let TargetGuard = "bf16" in { +let TargetGuard = "bf16,neon" in { def VDOT_BF : SInst<"vbfdot", "..BB", "fQf">; def VDOT_LANE_BF : SOpInst<"vbfdot_lane", "..B(Bq)I", "fQf", OP_BFDOT_LN>; def VDOT_LANEQ_BF : SOpInst<"vbfdot_laneq", "..B(BQ)I", "fQf", OP_BFDOT_LNQ> { @@ -1970,7 +1970,7 @@ multiclass VCMLA_ROTS { } // v8.3-A Vector complex addition intrinsics -let TargetGuard = "v8.3a,fullfp16" in { +let TargetGuard = "v8.3a,fullfp16,neon" in { def VCADD_ROT90_FP16 : SInst<"vcadd_rot90", "...", "h">; def VCADD_ROT270_FP16 : SInst<"vcadd_rot270", "...", "h">; def VCADDQ_ROT90_FP16 : SInst<"vcaddq_rot90", "QQQ", "h">; @@ -1978,7 +1978,7 @@ let TargetGuard = "v8.3a,fullfp16" in { defm VCMLA_FP16 : VCMLA_ROTS<"h", "uint32x2_t", "uint32x4_t">; } -let TargetGuard = "v8.3a" in { +let TargetGuard = "v8.3a,neon" in { def VCADD_ROT90 : SInst<"vcadd_rot90", "...", "f">; def VCADD_ROT270 : SInst<"vcadd_rot270", "...", "f">; def VCADDQ_ROT90 : SInst<"vcaddq_rot90", "QQQ", "f">; @@ -1986,7 +1986,7 @@ let TargetGuard = "v8.3a" in { defm VCMLA_F32 : VCMLA_ROTS<"f", "uint64x1_t", "uint64x2_t">; } -let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.3a" in { +let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.3a,neon" in { def VCADDQ_ROT90_FP64 : SInst<"vcaddq_rot90", "QQQ", "d">; def VCADDQ_ROT270_FP64 : SInst<"vcaddq_rot270", "QQQ", "d">; @@ -1994,7 +1994,7 @@ let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v } // V8.2-A BFloat intrinsics -let TargetGuard = "bf16" in { +let TargetGuard = "bf16,neon" in { def VCREATE_BF : NoTestOpInst<"vcreate", ".(IU>)", "b", OP_CAST> { let BigEndianSafe = 1; } @@ -2058,14 +2058,14 @@ let TargetGuard = "bf16" in { def SCALAR_CVT_F32_BF16 : SOpInst<"vcvtah_f32", "(1F>)(1!)", "b", OP_CVT_F32_BF16>; } -let ArchGuard = "!defined(__aarch64__) && !defined(__arm64ec__)", TargetGuard = "bf16" in { +let ArchGuard = "!defined(__aarch64__) && !defined(__arm64ec__)", TargetGuard = "bf16,neon" in { def VCVT_BF16_F32_A32_INTERNAL : WInst<"__a32_vcvt_bf16", "BQ", "f">; def VCVT_BF16_F32_A32 : SOpInst<"vcvt_bf16", "BQ", "f", OP_VCVT_BF16_F32_A32>; def VCVT_LOW_BF16_F32_A32 : SOpInst<"vcvt_low_bf16", "BQ", "Qf", OP_VCVT_BF16_F32_LO_A32>; def VCVT_HIGH_BF16_F32_A32 : SOpInst<"vcvt_high_bf16", "BBQ", "Qf", OP_VCVT_BF16_F32_HI_A32>; } -let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "bf16" in { +let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "bf16,neon" in { def VCVT_LOW_BF16_F32_A64_INTERNAL : WInst<"__a64_vcvtq_low_bf16", "BQ", "Hf">; def VCVT_LOW_BF16_F32_A64 : SOpInst<"vcvt_low_bf16", "BQ", "Qf", OP_VCVT_BF16_F32_LO_A64>; def VCVT_HIGH_BF16_F32_A64 : SInst<"vcvt_high_bf16", "BBQ", "Qf">; @@ -2077,14 +2077,14 @@ let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "b def COPYQ_LANEQ_BF16 : IOpInst<"vcopy_laneq", "..I.I", "Qb", OP_COPY_LN>; } -let ArchGuard = "!defined(__aarch64__) && !defined(__arm64ec__)", TargetGuard = "bf16" in { +let ArchGuard = "!defined(__aarch64__) && !defined(__arm64ec__)", TargetGuard = "bf16,neon" in { let BigEndianSafe = 1 in { defm VREINTERPRET_BF : REINTERPRET_CROSS_TYPES< "csilUcUsUiUlhfPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQPcQPsQPl", "bQb">; } } -let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "bf16" in { +let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "bf16,neon" in { let BigEndianSafe = 1 in { defm VVREINTERPRET_BF : REINTERPRET_CROSS_TYPES< "csilUcUsUiUlhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQdQPcQPsQPlQPk", "bQb">; @@ -2092,7 +2092,7 @@ let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "b } // v8.9a/v9.4a LRCPC3 intrinsics -let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "rcpc3" in { +let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "rcpc3,neon" in { def VLDAP1_LANE : WInst<"vldap1_lane", ".(c*!).I", "QUlQlUlldQdPlQPl">; def VSTL1_LANE : WInst<"vstl1_lane", "v*(.!)I", "QUlQlUlldQdPlQPl">; } diff --git a/clang/include/clang/Basic/arm_neon_incl.td b/clang/include/clang/Basic/arm_neon_incl.td index b8155c187d1bc..3b8015daee6d9 100644 --- a/clang/include/clang/Basic/arm_neon_incl.td +++ b/clang/include/clang/Basic/arm_neon_incl.td @@ -265,7 +265,7 @@ class Inst { string Prototype = p; string Types = t; string ArchGuard = ""; - string TargetGuard = ""; + string TargetGuard = "neon"; Operation Operation = o; bit BigEndianSafe = 0; diff --git a/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h b/clang/include/clang/CodeGen/ObjectFilePCHContainerWriter.h similarity index 74% rename from clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h rename to clang/include/clang/CodeGen/ObjectFilePCHContainerWriter.h index 7a02d8725885a..26ee9f22258c1 100644 --- a/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h +++ b/clang/include/clang/CodeGen/ObjectFilePCHContainerWriter.h @@ -1,4 +1,4 @@ -//===-- CodeGen/ObjectFilePCHContainerOperations.h - ------------*- C++ -*-===// +//===-- CodeGen/ObjectFilePCHContainerWriter.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. @@ -29,14 +29,6 @@ class ObjectFilePCHContainerWriter : public PCHContainerWriter { std::shared_ptr Buffer) const override; }; -/// A PCHContainerReader implementation that uses LLVM to -/// wraps Clang modules inside a COFF, ELF, or Mach-O container. -class ObjectFilePCHContainerReader : public PCHContainerReader { - ArrayRef getFormats() const override; - - /// Returns the serialized AST inside the PCH container Buffer. - StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override; -}; } #endif diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h index 1477e7f99d785..68c3ae5591e28 100644 --- a/clang/include/clang/Driver/Driver.h +++ b/clang/include/clang/Driver/Driver.h @@ -639,8 +639,9 @@ class Driver { /// treated before building actions or binding tools. /// /// \return Whether any compilation should be built for this - /// invocation. - bool HandleImmediateArgs(const Compilation &C); + /// invocation. The compilation can only be modified when + /// this function returns false. + bool HandleImmediateArgs(Compilation &C); /// ConstructAction - Construct the appropriate action to do for /// \p Phase on the \p Input, taking in to account arguments diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 4b335becf9736..c0aa9be7752f3 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -940,7 +940,9 @@ def O : Joined<["-"], "O">, Group, def O_flag : Flag<["-"], "O">, Visibility<[ClangOption, CC1Option, FC1Option]>, Alias, AliasArgs<["1"]>; def Ofast : Joined<["-"], "Ofast">, Group, - Visibility<[ClangOption, CC1Option, FlangOption]>; + Visibility<[ClangOption, CC1Option, FlangOption]>, + HelpText<"Deprecated; use '-O3 -ffast-math' for the same behavior," + " or '-O3' to enable only conforming optimizations">; def P : Flag<["-"], "P">, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, Group, @@ -985,15 +987,15 @@ def Wsystem_headers_in_module_EQ : Joined<["-"], "Wsystem-headers-in-module=">, HelpText<"Enable -Wsystem-headers when building ">, MarshallingInfoStringVector>; def Wdeprecated : Flag<["-"], "Wdeprecated">, Group, - Visibility<[ClangOption, CC1Option]>, + Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>, HelpText<"Enable warnings for deprecated constructs and define __DEPRECATED">; def Wno_deprecated : Flag<["-"], "Wno-deprecated">, Group, Visibility<[ClangOption, CC1Option]>; defm invalid_constexpr : BoolWOption<"invalid-constexpr", LangOpts<"CheckConstexprFunctionBodies">, Default, - NegFlag, - PosFlag, + NegFlag, + PosFlag, BothFlags<[], [ClangOption, CC1Option], " checking of constexpr function bodies for validity within a constant expression context">>; def Wl_COMMA : CommaJoined<["-"], "Wl,">, Visibility<[ClangOption, FlangOption]>, Flags<[LinkerInput, RenderAsInput]>, @@ -1004,7 +1006,7 @@ def Wno_nonportable_cfstrings : Joined<["-"], "Wno-nonportable-cfstrings">, Grou Visibility<[ClangOption, CC1Option]>; def Wnonportable_cfstrings : Joined<["-"], "Wnonportable-cfstrings">, Group, Visibility<[ClangOption, CC1Option]>; -def Wno_sycl_strict : Flag<["-"], "Wno-sycl-strict">, Group, HelpText<"Disable warnings which enforce strict SYCL language compatibility.">; +def Wno_sycl_strict : Flag<["-"], "Wno-sycl-strict">, Group, Flags<[HelpHidden]>, HelpText<"Disable warnings which enforce strict SYCL language compatibility.">; def Wp_COMMA : CommaJoined<["-"], "Wp,">, HelpText<"Pass the comma separated arguments in to the preprocessor">, MetaVarName<"">, Group; @@ -1168,8 +1170,7 @@ def cl_single_precision_constant : Flag<["-"], "cl-single-precision-constant">, MarshallingInfoFlag>; def cl_finite_math_only : Flag<["-"], "cl-finite-math-only">, Group, Visibility<[ClangOption, CC1Option]>, - HelpText<"OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.">, - MarshallingInfoFlag>; + HelpText<"OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.">; def cl_kernel_arg_info : Flag<["-"], "cl-kernel-arg-info">, Group, Visibility<[ClangOption, CC1Option]>, HelpText<"OpenCL only. Generate kernel argument metadata.">, @@ -1216,19 +1217,19 @@ def client__name : JoinedOrSeparate<["-"], "client_name">; def combine : Flag<["-", "--"], "combine">, Flags<[NoXarchOption, Unsupported]>; def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">; def config : Joined<["--"], "config=">, Flags<[NoXarchOption]>, - Visibility<[ClangOption, CLOption, DXCOption]>, MetaVarName<"">, + Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, MetaVarName<"">, HelpText<"Specify configuration file">; -def : Separate<["--"], "config">, Alias; +def : Separate<["--"], "config">, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, Alias; def no_default_config : Flag<["--"], "no-default-config">, - Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption]>, + Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, HelpText<"Disable loading default configuration files">; def config_system_dir_EQ : Joined<["--"], "config-system-dir=">, Flags<[NoXarchOption, HelpHidden]>, - Visibility<[ClangOption, CLOption, DXCOption]>, + Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, HelpText<"System directory for configuration files">; def config_user_dir_EQ : Joined<["--"], "config-user-dir=">, Flags<[NoXarchOption, HelpHidden]>, - Visibility<[ClangOption, CLOption, DXCOption]>, + Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, HelpText<"User directory for configuration files">; def coverage : Flag<["-", "--"], "coverage">, Group, Visibility<[ClangOption, CLOption]>; @@ -1981,6 +1982,14 @@ def fapinotes_swift_version : Joined<["-"], "fapinotes-swift-version=">, MetaVarName<"">, HelpText<"Specify the Swift version to use when filtering API notes">; +defm bounds_safety : BoolFOption< + "experimental-bounds-safety", + LangOpts<"BoundsSafety">, DefaultFalse, + PosFlag, + NegFlag, + BothFlags<[], [CC1Option], + " experimental bounds safety extension for C">>; + defm addrsig : BoolFOption<"addrsig", CodeGenOpts<"Addrsig">, DefaultFalse, PosFlag, @@ -2679,13 +2688,12 @@ defm approx_func : BoolFOption<"approx-func", LangOpts<"ApproxFunc">, DefaultFal "with an approximately equivalent calculation", [funsafe_math_optimizations.KeyPath]>, NegFlag>; -defm finite_math_only : BoolFOption<"finite-math-only", - LangOpts<"FiniteMathOnly">, DefaultFalse, +defm finite_math_only : BoolOptionWithoutMarshalling<"f", "finite-math-only", PosFlag, + [ffast_math.KeyPath]>, NegFlag>; defm signed_zeros : BoolFOption<"signed-zeros", LangOpts<"NoSignedZero">, DefaultFalse, @@ -3302,6 +3310,10 @@ def fimplicit_module_maps : Flag <["-"], "fimplicit-module-maps">, Group, HelpText<"Implicitly search the file system for module map files.">, MarshallingInfoFlag>; +defm modulemap_allow_subdirectory_search : BoolFOption <"modulemap-allow-subdirectory-search", + HeaderSearchOpts<"AllowModuleMapSubdirectorySearch">, DefaultTrue, + PosFlag, + NegFlag, BothFlags<[NoXarchOption], [ClangOption, CC1Option]>>; defm modules : BoolFOption<"modules", LangOpts<"Modules">, Default, PosFlag, Group; def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group; def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group; def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group; +def fno_pointer_tbaa : Flag<["-"], "fno-pointer-tbaa">, Group; def fno_temp_file : Flag<["-"], "fno-temp-file">, Group, Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, HelpText< "Directly create compilation output files. This may lead to incorrect incremental builds if the compiler crashes">, @@ -3605,7 +3618,7 @@ def fopenmp_use_tls : Flag<["-"], "fopenmp-use-tls">, Group, def fnoopenmp_use_tls : Flag<["-"], "fnoopenmp-use-tls">, Group, Flags<[NoArgumentUnused, HelpHidden]>, Visibility<[ClangOption, CC1Option]>; def fopenmp_targets_EQ : CommaJoined<["-"], "fopenmp-targets=">, - Flags<[NoXarchOption]>, Visibility<[ClangOption, CC1Option, FlangOption]>, + Flags<[NoXarchOption]>, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, HelpText<"Specify comma-separated list of triples OpenMP offloading targets to be supported">; def fopenmp_relocatable_target : Flag<["-"], "fopenmp-relocatable-target">, Group, Flags<[NoArgumentUnused, HelpHidden]>, @@ -3976,6 +3989,7 @@ defm strict_vtable_pointers : BoolFOption<"strict-vtable-pointers", " overwriting polymorphic C++ objects">, NegFlag>; def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group; +def fpointer_tbaa : Flag<["-"], "fpointer-tbaa">, Group; def fdriver_only : Flag<["-"], "fdriver-only">, Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption]>, Group, HelpText<"Only run the driver.">; @@ -4079,6 +4093,10 @@ def ftime_trace_granularity_EQ : Joined<["-"], "ftime-trace-granularity=">, Grou HelpText<"Minimum time granularity (in microseconds) traced by time profiler">, Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, MarshallingInfoInt, "500u">; +def ftime_trace_verbose : Joined<["-"], "ftime-trace-verbose">, Group, + HelpText<"Make time trace capture verbose event details (e.g. source filenames). This can increase the size of the output by 2-3 times">, + Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, + MarshallingInfoFlag>; def ftime_trace_EQ : Joined<["-"], "ftime-trace=">, Group, HelpText<"Similar to -ftime-trace. Specify the JSON file or a directory which will contain the JSON file">, Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, @@ -4326,9 +4344,13 @@ defm ptrauth_vtable_pointer_address_discrimination : OptInCC1FFlag<"ptrauth-vtable-pointer-address-discrimination", "Enable address discrimination of vtable pointers">; defm ptrauth_vtable_pointer_type_discrimination : OptInCC1FFlag<"ptrauth-vtable-pointer-type-discrimination", "Enable type discrimination of vtable pointers">; +defm ptrauth_type_info_vtable_pointer_discrimination : + OptInCC1FFlag<"ptrauth-type-info-vtable-pointer-discrimination", "Enable type and address discrimination of vtable pointer of std::type_info">; defm ptrauth_init_fini : OptInCC1FFlag<"ptrauth-init-fini", "Enable signing of function pointers in init/fini arrays">; defm ptrauth_function_pointer_type_discrimination : OptInCC1FFlag<"ptrauth-function-pointer-type-discrimination", "Enable type discrimination on C function pointers">; +defm ptrauth_indirect_gotos : OptInCC1FFlag<"ptrauth-indirect-gotos", + "Enable signing and authentication of indirect goto targets">; } def fenable_matrix : Flag<["-"], "fenable-matrix">, Group, @@ -5162,6 +5184,11 @@ def mspe : Flag<["-"], "mspe">, Group; def mno_spe : Flag<["-"], "mno-spe">, Group; def mefpu2 : Flag<["-"], "mefpu2">, Group; } // let Flags = [TargetSpecific] +def msave_reg_params : Flag<["-"], "msave-reg-params">, Group, + Flags<[TargetSpecific]>, + Visibility<[ClangOption, CC1Option]>, + HelpText<"Save arguments passed by registers to ABI-defined stack positions">, + MarshallingInfoFlag>; def mabi_EQ_quadword_atomics : Flag<["-"], "mabi=quadword-atomics">, Group, Visibility<[ClangOption, CC1Option]>, HelpText<"Enable quadword atomics ABI on AIX (AIX PPC64 only). Uses lqarx/stqcx. instructions.">, @@ -6453,9 +6480,8 @@ def mapx_features_EQ : CommaJoined<["-"], "mapx-features=">, Group, Values<"egpr,push2pop2,ppx,ndd,ccmp,nf,cf,zu">, Visibility<[ClangOption, CLOption, FlangOption]>; def mno_apx_features_EQ : CommaJoined<["-"], "mno-apx-features=">, Group, HelpText<"Disable features of APX">, Values<"egpr,push2pop2,ppx,ndd,ccmp,nf,cf,zu">, Visibility<[ClangOption, CLOption, FlangOption]>; -// For stability, we only add a feature to -mapxf after it passes the validation of llvm-test-suite && cpu2017 on Intel SDE. -def mapxf : Flag<["-"], "mapxf">, Alias, AliasArgs<["egpr","push2pop2","ppx","ndd","ccmp","nf","cf"]>; -def mno_apxf : Flag<["-"], "mno-apxf">, Alias, AliasArgs<["egpr","push2pop2","ppx","ndd","ccmp","nf","cf"]>; +def mapxf : Flag<["-"], "mapxf">, Alias, AliasArgs<["egpr","push2pop2","ppx","ndd","ccmp","nf","cf","zu"]>; +def mno_apxf : Flag<["-"], "mno-apxf">, Alias, AliasArgs<["egpr","push2pop2","ppx","ndd","ccmp","nf","cf","zu"]>; def mapx_inline_asm_use_gpr32 : Flag<["-"], "mapx-inline-asm-use-gpr32">, Group, HelpText<"Enable use of GPR32 in inline assembly for APX">; } // let Flags = [TargetSpecific] @@ -7531,6 +7557,9 @@ def fuse_register_sized_bitfield_access: Flag<["-"], "fuse-register-sized-bitfie def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">, HelpText<"Turn off Type Based Alias Analysis">, MarshallingInfoFlag>; +def pointer_tbaa: Flag<["-"], "pointer-tbaa">, + HelpText<"Turn on Type Based Alias Analysis for pointer accesses">, + MarshallingInfoFlag>; def no_struct_path_tbaa : Flag<["-"], "no-struct-path-tbaa">, HelpText<"Turn off struct-path aware Type Based Alias Analysis">, MarshallingInfoNegativeFlag>; @@ -7873,6 +7902,9 @@ def code_completion_brief_comments : Flag<["-"], "code-completion-brief-comments def code_completion_with_fixits : Flag<["-"], "code-completion-with-fixits">, HelpText<"Include code completion results which require small fix-its.">, MarshallingInfoFlag>; +def skip_function_bodies : Flag<["-"], "skip-function-bodies">, + HelpText<"Skip function bodies when possible">, + MarshallingInfoFlag>; def disable_free : Flag<["-"], "disable-free">, HelpText<"Disable freeing of memory on exit">, MarshallingInfoFlag>; @@ -8157,10 +8189,10 @@ def mreassociate : Flag<["-"], "mreassociate">, MarshallingInfoFlag>, ImpliedByAnyOf<[funsafe_math_optimizations.KeyPath]>; def menable_no_nans : Flag<["-"], "menable-no-nans">, HelpText<"Allow optimization to assume there are no NaNs.">, - MarshallingInfoFlag>, ImpliedByAnyOf<[ffinite_math_only.KeyPath]>; -def menable_no_infinities : Flag<["-"], "menable-no-infs">, + MarshallingInfoFlag>, ImpliedByAnyOf<[ffast_math.KeyPath]>; +def menable_no_infs : Flag<["-"], "menable-no-infs">, HelpText<"Allow optimization to assume there are no infinities.">, - MarshallingInfoFlag>, ImpliedByAnyOf<[ffinite_math_only.KeyPath]>; + MarshallingInfoFlag>, ImpliedByAnyOf<[ffast_math.KeyPath]>; def pic_level : Separate<["-"], "pic-level">, HelpText<"Value for __PIC__">, @@ -8447,6 +8479,13 @@ def source_date_epoch : Separate<["-"], "source-date-epoch">, } // let Visibility = [CC1Option] +defm err_pragma_mc_func_aix : BoolFOption<"err-pragma-mc-func-aix", + PreprocessorOpts<"ErrorOnPragmaMcfuncOnAIX">, DefaultTrue, + PosFlag, + NegFlag>; + //===----------------------------------------------------------------------===// // CUDA Options //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index 5e5034fe01eb5..8241925c98476 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -580,6 +580,11 @@ class FrontendOptions { /// Minimum time granularity (in microseconds) traced by time profiler. unsigned TimeTraceGranularity; + /// Make time trace capture verbose event details (e.g. source filenames). + /// This can increase the size of the output by 2-3 times. + LLVM_PREFERRED_TYPE(bool) + unsigned TimeTraceVerbose : 1; + /// Path which stores the output files for -ftime-trace std::string TimeTracePath; @@ -601,7 +606,8 @@ class FrontendOptions { EmitSymbolGraph(false), EmitExtensionSymbolGraphs(false), EmitSymbolGraphSymbolLabelsForTesting(false), EmitPrettySymbolGraphs(false), GenReducedBMI(false), - UseClangIRPipeline(false), TimeTraceGranularity(500) {} + UseClangIRPipeline(false), TimeTraceGranularity(500), + TimeTraceVerbose(false) {} /// getInputKindForExtension - Return the appropriate input kind for a file /// extension. For example, "c" would return Language::C. diff --git a/clang/include/clang/Lex/HeaderSearchOptions.h b/clang/include/clang/Lex/HeaderSearchOptions.h index 17635146a1614..83a95e9ad90a7 100644 --- a/clang/include/clang/Lex/HeaderSearchOptions.h +++ b/clang/include/clang/Lex/HeaderSearchOptions.h @@ -270,6 +270,12 @@ class HeaderSearchOptions { LLVM_PREFERRED_TYPE(bool) unsigned ModulesIncludeVFSUsage : 1; + /// Whether we should look for a module in module maps only in provided + /// header search paths or if we are allowed to look for module maps in + /// subdirectories of provided paths too. + LLVM_PREFERRED_TYPE(bool) + unsigned AllowModuleMapSubdirectorySearch : 1; + HeaderSearchOptions(StringRef _Sysroot = "/") : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false), ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false), @@ -285,7 +291,8 @@ class HeaderSearchOptions { ModulesSkipHeaderSearchPaths(false), ModulesSkipPragmaDiagnosticMappings(false), ModulesPruneNonAffectingModuleMaps(true), ModulesHashContent(false), - ModulesStrictContextHash(false), ModulesIncludeVFSUsage(false) {} + ModulesStrictContextHash(false), ModulesIncludeVFSUsage(false), + AllowModuleMapSubdirectorySearch(true) {} /// AddPath - Add the \p Path path to the specified \p Group list. void AddPath(StringRef Path, frontend::IncludeDirGroup Group, diff --git a/clang/include/clang/Lex/PPEmbedParameters.h b/clang/include/clang/Lex/PPEmbedParameters.h index 51bf908524e7a..c4fb8d02f6f35 100644 --- a/clang/include/clang/Lex/PPEmbedParameters.h +++ b/clang/include/clang/Lex/PPEmbedParameters.h @@ -75,7 +75,6 @@ struct LexEmbedParametersResult { std::optional MaybeIfEmptyParam; std::optional MaybePrefixParam; std::optional MaybeSuffixParam; - SourceRange ParamRange; int UnrecognizedParams; size_t PrefixTokenCount() const { diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 4de86884adfd4..46daa11f381af 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -1161,6 +1161,11 @@ class Preprocessor { /// invoked (at which point the last position is popped). std::vector BacktrackPositions; + /// Stack of cached tokens/initial number of cached tokens pairs, allowing + /// nested unannotated backtracks. + std::vector> + UnannotatedBacktrackTokens; + /// True if \p Preprocessor::SkipExcludedConditionalBlock() is running. /// This is used to guard against calling this function recursively. /// @@ -1723,8 +1728,16 @@ class Preprocessor { /// at some point after EnableBacktrackAtThisPos. If you don't, caching of /// tokens will continue indefinitely. /// - void EnableBacktrackAtThisPos(); + /// \param Unannotated Whether token annotations are reverted upon calling + /// Backtrack(). + void EnableBacktrackAtThisPos(bool Unannotated = false); + +private: + std::pair LastBacktrackPos(); + + CachedTokensTy PopUnannotatedBacktrackTokens(); +public: /// Disable the last EnableBacktrackAtThisPos call. void CommitBacktrackedTokens(); @@ -1736,6 +1749,12 @@ class Preprocessor { /// caching of tokens is on. bool isBacktrackEnabled() const { return !BacktrackPositions.empty(); } + /// True if EnableBacktrackAtThisPos() was called and + /// caching of unannotated tokens is on. + bool isUnannotatedBacktrackEnabled() const { + return !UnannotatedBacktrackTokens.empty(); + } + /// Lex the next token for this preprocessor. void Lex(Token &Result); @@ -1842,8 +1861,9 @@ class Preprocessor { void RevertCachedTokens(unsigned N) { assert(isBacktrackEnabled() && "Should only be called when tokens are cached for backtracking"); - assert(signed(CachedLexPos) - signed(N) >= signed(BacktrackPositions.back()) - && "Should revert tokens up to the last backtrack position, not more"); + assert(signed(CachedLexPos) - signed(N) >= + signed(LastBacktrackPos().first) && + "Should revert tokens up to the last backtrack position, not more"); assert(signed(CachedLexPos) - signed(N) >= 0 && "Corrupted backtrack positions ?"); CachedLexPos -= N; diff --git a/clang/include/clang/Lex/PreprocessorOptions.h b/clang/include/clang/Lex/PreprocessorOptions.h index fc98c15c3fc9b..cadec5ef83dec 100644 --- a/clang/include/clang/Lex/PreprocessorOptions.h +++ b/clang/include/clang/Lex/PreprocessorOptions.h @@ -212,6 +212,10 @@ class PreprocessorOptions { /// If set, the UNIX timestamp specified by SOURCE_DATE_EPOCH. std::optional SourceDateEpoch; + /// If set, the preprocessor reports an error when processing #pragma mc_func + /// on AIX. + bool ErrorOnPragmaMcfuncOnAIX = true; + public: PreprocessorOptions() : PrecompiledPreambleBytes(0, false) {} @@ -249,6 +253,7 @@ class PreprocessorOptions { PrecompiledPreambleBytes.first = 0; PrecompiledPreambleBytes.second = false; RetainExcludedConditionalBlocks = false; + ErrorOnPragmaMcfuncOnAIX = true; } }; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index ed28c736b9505..1518ae96e0aca 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -221,6 +221,7 @@ class Parser : public CodeCompletionHandler { std::unique_ptr MaxTokensHerePragmaHandler; std::unique_ptr MaxTokensTotalPragmaHandler; std::unique_ptr RISCVPragmaHandler; + std::unique_ptr MCFuncPragmaHandler; std::unique_ptr CommentSemaHandler; @@ -1024,6 +1025,8 @@ class Parser : public CodeCompletionHandler { /// .... /// TPA.Revert(); /// + /// If the Unannotated parameter is true, any token annotations created + /// during the tentative parse are reverted. class TentativeParsingAction { Parser &P; PreferredTypeBuilder PrevPreferredType; @@ -1033,7 +1036,7 @@ class Parser : public CodeCompletionHandler { bool isActive; public: - explicit TentativeParsingAction(Parser &p) + explicit TentativeParsingAction(Parser &p, bool Unannotated = false) : P(p), PrevPreferredType(P.PreferredType) { PrevTok = P.Tok; PrevTentativelyDeclaredIdentifierCount = @@ -1041,7 +1044,7 @@ class Parser : public CodeCompletionHandler { PrevParenCount = P.ParenCount; PrevBracketCount = P.BracketCount; PrevBraceCount = P.BraceCount; - P.PP.EnableBacktrackAtThisPos(); + P.PP.EnableBacktrackAtThisPos(Unannotated); isActive = true; } void Commit() { @@ -1072,13 +1075,11 @@ class Parser : public CodeCompletionHandler { class RevertingTentativeParsingAction : private Parser::TentativeParsingAction { public: - RevertingTentativeParsingAction(Parser &P) - : Parser::TentativeParsingAction(P) {} + using TentativeParsingAction::TentativeParsingAction; + ~RevertingTentativeParsingAction() { Revert(); } }; - class UnannotatedTentativeParsingAction; - /// ObjCDeclContextSwitch - An object used to switch context from /// an objective-c decl context to its enclosing decl context and /// back. @@ -1984,7 +1985,8 @@ class Parser : public CodeCompletionHandler { CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHasErrors, bool EnteringContext, bool *MayBePseudoDestructor = nullptr, bool IsTypename = false, const IdentifierInfo **LastII = nullptr, - bool OnlyNamespace = false, bool InUsingDeclaration = false); + bool OnlyNamespace = false, bool InUsingDeclaration = false, + bool Disambiguation = false); //===--------------------------------------------------------------------===// // C++11 5.1.2: Lambda expressions @@ -3896,6 +3898,8 @@ class Parser : public CodeCompletionHandler { // __builtin_field_type, __builtin_base_type ExprResult ParseSYCLBuiltinType(); + ExprResult ParseBuiltinPtrauthTypeDiscriminator(); + //===--------------------------------------------------------------------===// // Preprocessor code-completion pass-through void CodeCompleteDirective(bool InConditional) override; diff --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h index 9d8b797af6663..d6a6cee62a752 100644 --- a/clang/include/clang/Sema/Overload.h +++ b/clang/include/clang/Sema/Overload.h @@ -984,7 +984,7 @@ class Sema; unsigned getNumParams() const { if (IsSurrogate) { QualType STy = Surrogate->getConversionType(); - while (STy->isPointerType() || STy->isReferenceType()) + while (STy->isPointerOrReferenceType()) STy = STy->getPointeeType(); return STy->castAs()->getNumParams(); } @@ -998,7 +998,9 @@ class Sema; private: friend class OverloadCandidateSet; OverloadCandidate() - : IsSurrogate(false), IsADLCandidate(CallExpr::NotADL), RewriteKind(CRK_None) {} + : IsSurrogate(false), IgnoreObjectArgument(false), + TookAddressOfOverload(false), IsADLCandidate(CallExpr::NotADL), + RewriteKind(CRK_None) {} }; /// OverloadCandidateSet - A set of overload candidates, used in C++ diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 296703e931b7f..a77135ce1c2a4 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2215,6 +2215,7 @@ class Sema final : public SemaBase { FST_FreeBSDKPrintf, FST_OSTrace, FST_OSLog, + FST_Syslog, FST_Unknown }; static FormatStringType GetFormatStringType(const FormatAttr *Format); @@ -3464,6 +3465,8 @@ class Sema final : public SemaBase { TemplateIdAnnotation *TemplateId, bool IsMemberSpecialization); + bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range); + bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key); /// Diagnose function specifiers on a declaration of an identifier that @@ -15090,6 +15093,44 @@ class Sema final : public SemaBase { void ProcessAPINotes(Decl *D); ///@} + + // + // + // ------------------------------------------------------------------------- + // + // + + /// \name Bounds Safety + /// Implementations are in SemaBoundsSafety.cpp + ///@{ +public: + /// Check if applying the specified attribute variant from the "counted by" + /// family of attributes to FieldDecl \p FD is semantically valid. If + /// semantically invalid diagnostics will be emitted explaining the problems. + /// + /// \param FD The FieldDecl to apply the attribute to + /// \param E The count expression on the attribute + /// \param[out] Decls If the attribute is semantically valid \p Decls + /// is populated with TypeCoupledDeclRefInfo objects, each + /// describing Decls referred to in \p E. + /// \param CountInBytes If true the attribute is from the "sized_by" family of + /// attributes. If the false the attribute is from + /// "counted_by" family of attributes. + /// \param OrNull If true the attribute is from the "_or_null" suffixed family + /// of attributes. If false the attribute does not have the + /// suffix. + /// + /// Together \p CountInBytes and \p OrNull decide the attribute variant. E.g. + /// \p CountInBytes and \p OrNull both being true indicates the + /// `counted_by_or_null` attribute. + /// + /// \returns false iff semantically valid. + bool CheckCountedByAttrOnField( + FieldDecl *FD, Expr *E, + llvm::SmallVectorImpl &Decls, bool CountInBytes, + bool OrNull); + + ///@} }; DeductionFailureInfo diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h index 3edf1cc7c12f2..aa61dae9415e2 100644 --- a/clang/include/clang/Sema/SemaOpenMP.h +++ b/clang/include/clang/Sema/SemaOpenMP.h @@ -398,8 +398,7 @@ class SemaOpenMP : public SemaBase { StmtResult ActOnOpenMPExecutableDirective( OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef Clauses, - Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - OpenMPDirectiveKind PrevMappedDirective = llvm::omp::OMPD_unknown); + Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc); /// Called on well-formed '\#pragma omp parallel' after parsing /// of the associated statement. StmtResult ActOnOpenMPParallelDirective(ArrayRef Clauses, @@ -423,6 +422,15 @@ class SemaOpenMP : public SemaBase { StmtResult ActOnOpenMPUnrollDirective(ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc); + /// Called on well-formed '#pragma omp reverse'. + StmtResult ActOnOpenMPReverseDirective(Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc); + /// Called on well-formed '#pragma omp interchange' after parsing of its + /// clauses and the associated statement. + StmtResult ActOnOpenMPInterchangeDirective(ArrayRef Clauses, + Stmt *AStmt, + SourceLocation StartLoc, + SourceLocation EndLoc); /// Called on well-formed '\#pragma omp for' after parsing /// of the associated statement. StmtResult @@ -1421,26 +1429,6 @@ class SemaOpenMP : public SemaBase { /// All `omp assumes` we encountered so far. SmallVector OMPAssumeGlobal; - - /// OMPD_loop is mapped to OMPD_for, OMPD_distribute or OMPD_simd depending - /// on the parameter of the bind clause. In the methods for the - /// mapped directives, check the parameters of the lastprivate clause. - bool checkLastPrivateForMappedDirectives(ArrayRef Clauses); - /// Depending on the bind clause of OMPD_loop map the directive to new - /// directives. - /// 1) loop bind(parallel) --> OMPD_for - /// 2) loop bind(teams) --> OMPD_distribute - /// 3) loop bind(thread) --> OMPD_simd - /// This is being handled in Sema instead of Codegen because of the need for - /// rigorous semantic checking in the new mapped directives. - bool mapLoopConstruct(llvm::SmallVector &ClausesWithoutBind, - ArrayRef Clauses, - OpenMPBindClauseKind &BindKind, - OpenMPDirectiveKind &Kind, - OpenMPDirectiveKind &PrevMappedDirective, - SourceLocation StartLoc, SourceLocation EndLoc, - const DeclarationNameInfo &DirName, - OpenMPDirectiveKind CancelRegion); }; } // namespace clang diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 199dcfef28287..922fdd409d360 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1900,6 +1900,8 @@ enum StmtCode { STMT_OMP_SIMD_DIRECTIVE, STMT_OMP_TILE_DIRECTIVE, STMT_OMP_UNROLL_DIRECTIVE, + STMT_OMP_REVERSE_DIRECTIVE, + STMT_OMP_INTERCHANGE_DIRECTIVE, STMT_OMP_FOR_DIRECTIVE, STMT_OMP_FOR_SIMD_DIRECTIVE, STMT_OMP_SECTIONS_DIRECTIVE, diff --git a/clang/include/clang/Serialization/ObjectFilePCHContainerReader.h b/clang/include/clang/Serialization/ObjectFilePCHContainerReader.h new file mode 100644 index 0000000000000..6281a3f428869 --- /dev/null +++ b/clang/include/clang/Serialization/ObjectFilePCHContainerReader.h @@ -0,0 +1,25 @@ +//===-- Serialization/ObjectFilePCHContainerReader.h ------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_OBJECTFILEPCHCONTAINERREADER_H +#define LLVM_CLANG_SERIALIZATION_OBJECTFILEPCHCONTAINERREADER_H + +#include "clang/Frontend/PCHContainerOperations.h" + +namespace clang { +/// A PCHContainerReader implementation that uses LLVM to +/// wraps Clang modules inside a COFF, ELF, or Mach-O container. +class ObjectFilePCHContainerReader : public PCHContainerReader { + ArrayRef getFormats() const override; + + /// Returns the serialized AST inside the PCH container Buffer. + StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override; +}; +} // namespace clang + +#endif diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index ec5dbd28a5272..38b55a0eb0a7b 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -1045,18 +1045,6 @@ def MallocOverflowSecurityChecker : Checker<"MallocOverflow">, def MmapWriteExecChecker : Checker<"MmapWriteExec">, HelpText<"Warn on mmap() calls that are both writable and executable">, - CheckerOptions<[ - CmdLineOption, - CmdLineOption - ]>, Documentation; def ReturnPointerRangeChecker : Checker<"ReturnPtrRange">, diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h index 3a4b087257149..def2970d448d4 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h @@ -326,6 +326,10 @@ class LocAsInteger : public NonLoc { static bool classof(SVal V) { return V.getKind() == LocAsIntegerKind; } }; +/// The simplest example of a concrete compound value is nonloc::CompoundVal, +/// which represents a concrete r-value of an initializer-list or a string. +/// Internally, it contains an llvm::ImmutableList of SVal's stored inside the +/// literal. class CompoundVal : public NonLoc { friend class ento::SValBuilder; @@ -346,6 +350,36 @@ class CompoundVal : public NonLoc { static bool classof(SVal V) { return V.getKind() == CompoundValKind; } }; +/// While nonloc::CompoundVal covers a few simple use cases, +/// nonloc::LazyCompoundVal is a more performant and flexible way to represent +/// an rvalue of record type, so it shows up much more frequently during +/// analysis. This value is an r-value that represents a snapshot of any +/// structure "as a whole" at a given moment during the analysis. Such value is +/// already quite far from being referred to as "concrete", as many fields +/// inside it would be unknown or symbolic. nonloc::LazyCompoundVal operates by +/// storing two things: +/// * a reference to the TypedValueRegion being snapshotted (yes, it is always +/// typed), and also +/// * a reference to the whole Store object, obtained from the ProgramState in +/// which the nonloc::LazyCompoundVal was created. +/// +/// Note that the old ProgramState and its Store is kept alive during the +/// analysis because these are immutable functional data structures and each new +/// Store value is represented as "earlier Store" + "additional binding". +/// +/// Essentially, nonloc::LazyCompoundVal is a performance optimization for the +/// analyzer. Because Store is immutable, creating a nonloc::LazyCompoundVal is +/// a very cheap operation. Note that the Store contains all region bindings in +/// the program state, not only related to the region. Later, if necessary, such +/// value can be unpacked -- eg. when it is assigned to another variable. +/// +/// If you ever need to inspect the contents of the LazyCompoundVal, you can use +/// StoreManager::iterBindings(). It'll iterate through all values in the Store, +/// but you're only interested in the ones that belong to +/// LazyCompoundVal::getRegion(); other bindings are immaterial. +/// +/// NOTE: LazyCompoundVal::getRegion() itself is also immaterial (see the actual +/// method docs for details). class LazyCompoundVal : public NonLoc { friend class ento::SValBuilder; @@ -363,6 +397,18 @@ class LazyCompoundVal : public NonLoc { /// It might return null. const void *getStore() const; + /// This function itself is immaterial. It is only an implementation detail. + /// LazyCompoundVal represents only the rvalue, the data (known or unknown) + /// that *was* stored in that region *at some point in the past*. The region + /// should not be used for any purpose other than figuring out what part of + /// the frozen Store you're interested in. The value does not represent the + /// *current* value of that region. Sometimes it may, but this should not be + /// relied upon. Instead, if you want to figure out what region it represents, + /// you typically need to see where you got it from in the first place. The + /// region is absolutely not analogous to the C++ "this" pointer. It is also + /// not a valid way to "materialize" the prvalue into a glvalue in C++, + /// because the region represents the *old* storage (sometimes very old), not + /// the *future* storage. LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion *getRegion() const; diff --git a/clang/lib/APINotes/APINotesFormat.h b/clang/lib/APINotes/APINotesFormat.h index e3aa76df8316c..9d254dcc1c9ef 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 = 26; // SwiftCopyable +const uint16_t VERSION_MINOR = 28; // nested tags const uint8_t kSwiftCopyable = 1; const uint8_t kSwiftNonCopyable = 2; @@ -63,6 +63,10 @@ enum BlockID { /// about the method. OBJC_METHOD_BLOCK_ID, + /// The C++ method data block, which maps C++ (context id, method name) pairs + /// to information about the method. + CXX_METHOD_BLOCK_ID, + /// The Objective-C selector data block, which maps Objective-C /// selector names (# of pieces, identifier IDs) to the selector ID /// used in other tables. @@ -181,6 +185,20 @@ using ObjCMethodDataLayout = >; } // namespace objc_method_block +namespace cxx_method_block { +enum { + CXX_METHOD_DATA = 1, +}; + +using CXXMethodDataLayout = + llvm::BCRecordLayout, // table offset within the blob (see + // below) + llvm::BCBlob // map from C++ (context id, name) + // tuples to C++ method information + >; +} // namespace cxx_method_block + namespace objc_selector_block { enum { OBJC_SELECTOR_DATA = 1, @@ -269,11 +287,16 @@ struct ContextTableKey { : parentContextID(parentContextID), contextKind(contextKind), contextID(contextID) {} - ContextTableKey(std::optional context, IdentifierID nameID) - : parentContextID(context ? context->id.Value : (uint32_t)-1), - contextKind(context ? static_cast(context->kind) - : static_cast(-1)), - contextID(nameID) {} + ContextTableKey(std::optional ParentContextID, ContextKind Kind, + uint32_t ContextID) + : parentContextID(ParentContextID ? ParentContextID->Value : -1), + contextKind(static_cast(Kind)), contextID(ContextID) {} + + ContextTableKey(std::optional ParentContext, ContextKind Kind, + uint32_t ContextID) + : ContextTableKey(ParentContext ? std::make_optional(ParentContext->id) + : std::nullopt, + Kind, ContextID) {} llvm::hash_code hashValue() const { return llvm::hash_value( @@ -286,6 +309,32 @@ inline bool operator==(const ContextTableKey &lhs, const ContextTableKey &rhs) { lhs.contextKind == rhs.contextKind && lhs.contextID == rhs.contextID; } +/// A stored Objective-C or C++ declaration, represented by the ID of its parent +/// context, and the name of the declaration. +struct SingleDeclTableKey { + uint32_t parentContextID; + uint32_t nameID; + + SingleDeclTableKey() : parentContextID(-1), nameID(-1) {} + + SingleDeclTableKey(uint32_t ParentContextID, uint32_t NameID) + : parentContextID(ParentContextID), nameID(NameID) {} + + SingleDeclTableKey(std::optional ParentCtx, IdentifierID NameID) + : parentContextID(ParentCtx ? ParentCtx->id.Value + : static_cast(-1)), + nameID(NameID) {} + + llvm::hash_code hashValue() const { + return llvm::hash_value(std::make_pair(parentContextID, nameID)); + } +}; + +inline bool operator==(const SingleDeclTableKey &lhs, + const SingleDeclTableKey &rhs) { + return lhs.parentContextID == rhs.parentContextID && lhs.nameID == rhs.nameID; +} + } // namespace api_notes } // namespace clang @@ -341,6 +390,29 @@ template <> struct DenseMapInfo { return lhs == rhs; } }; + +template <> struct DenseMapInfo { + static inline clang::api_notes::SingleDeclTableKey getEmptyKey() { + return clang::api_notes::SingleDeclTableKey(); + } + + static inline clang::api_notes::SingleDeclTableKey getTombstoneKey() { + return clang::api_notes::SingleDeclTableKey{ + DenseMapInfo::getTombstoneKey(), + DenseMapInfo::getTombstoneKey()}; + } + + static unsigned + getHashValue(const clang::api_notes::SingleDeclTableKey &value) { + return value.hashValue(); + } + + static bool isEqual(const clang::api_notes::SingleDeclTableKey &lhs, + const clang::api_notes::SingleDeclTableKey &rhs) { + return lhs == rhs; + } +}; + } // namespace llvm #endif diff --git a/clang/lib/APINotes/APINotesReader.cpp b/clang/lib/APINotes/APINotesReader.cpp index 8454e092b55ac..871f782511d5f 100644 --- a/clang/lib/APINotes/APINotesReader.cpp +++ b/clang/lib/APINotes/APINotesReader.cpp @@ -429,15 +429,13 @@ class ObjCSelectorTableInfo { /// Used to deserialize the on-disk global variable table. class GlobalVariableTableInfo - : public VersionedTableInfo { public: static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { auto CtxID = endian::readNext(Data); - auto ContextKind = - endian::readNext(Data); auto NameID = endian::readNext(Data); - return {CtxID, ContextKind, NameID}; + return {CtxID, NameID}; } hash_value_type ComputeHash(internal_key_type Key) { @@ -454,15 +452,13 @@ class GlobalVariableTableInfo /// Used to deserialize the on-disk global function table. class GlobalFunctionTableInfo - : public VersionedTableInfo { public: static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { auto CtxID = endian::readNext(Data); - auto ContextKind = - endian::readNext(Data); auto NameID = endian::readNext(Data); - return {CtxID, ContextKind, NameID}; + return {CtxID, NameID}; } hash_value_type ComputeHash(internal_key_type Key) { @@ -477,6 +473,29 @@ class GlobalFunctionTableInfo } }; +/// Used to deserialize the on-disk C++ method table. +class CXXMethodTableInfo + : public VersionedTableInfo { +public: + static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { + auto CtxID = endian::readNext(Data); + auto NameID = endian::readNext(Data); + return {CtxID, NameID}; + } + + hash_value_type ComputeHash(internal_key_type Key) { + return static_cast(Key.hashValue()); + } + + static CXXMethodInfo readUnversioned(internal_key_type Key, + const uint8_t *&Data) { + CXXMethodInfo Info; + ReadFunctionInfo(Data, Info); + return Info; + } +}; + /// Used to deserialize the on-disk enumerator table. class EnumConstantTableInfo : public VersionedTableInfo { + : public VersionedTableInfo { public: static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { auto CtxID = endian::readNext(Data); - auto ContextKind = - endian::readNext(Data); auto NameID = endian::readNext(Data); - return {CtxID, ContextKind, NameID}; + return {CtxID, NameID}; } hash_value_type ComputeHash(internal_key_type Key) { @@ -563,16 +580,14 @@ class TagTableInfo /// Used to deserialize the on-disk typedef table. class TypedefTableInfo - : public VersionedTableInfo { public: static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { auto CtxID = endian::readNext(Data); - auto ContextKind = - endian::readNext(Data); auto nameID = endian::readNext(Data); - return {CtxID, ContextKind, nameID}; + return {CtxID, nameID}; } hash_value_type ComputeHash(internal_key_type Key) { @@ -638,6 +653,12 @@ class APINotesReader::Implementation { /// The Objective-C method table. std::unique_ptr ObjCMethodTable; + using SerializedCXXMethodTable = + llvm::OnDiskIterableChainedHashTable; + + /// The C++ method table. + std::unique_ptr CXXMethodTable; + using SerializedObjCSelectorTable = llvm::OnDiskIterableChainedHashTable; @@ -691,6 +712,8 @@ class APINotesReader::Implementation { llvm::SmallVectorImpl &Scratch); bool readObjCMethodBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl &Scratch); + bool readCXXMethodBlock(llvm::BitstreamCursor &Cursor, + llvm::SmallVectorImpl &Scratch); bool readObjCSelectorBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl &Scratch); bool readGlobalVariableBlock(llvm::BitstreamCursor &Cursor, @@ -1148,6 +1171,81 @@ bool APINotesReader::Implementation::readObjCMethodBlock( return false; } +bool APINotesReader::Implementation::readCXXMethodBlock( + llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl &Scratch) { + if (Cursor.EnterSubBlock(CXX_METHOD_BLOCK_ID)) + return true; + + llvm::Expected MaybeNext = Cursor.advance(); + if (!MaybeNext) { + // FIXME this drops the error on the floor. + consumeError(MaybeNext.takeError()); + return false; + } + llvm::BitstreamEntry Next = MaybeNext.get(); + while (Next.Kind != llvm::BitstreamEntry::EndBlock) { + if (Next.Kind == llvm::BitstreamEntry::Error) + return true; + + if (Next.Kind == llvm::BitstreamEntry::SubBlock) { + // Unknown sub-block, possibly for use by a future version of the + // API notes format. + if (Cursor.SkipBlock()) + return true; + + MaybeNext = Cursor.advance(); + if (!MaybeNext) { + // FIXME this drops the error on the floor. + consumeError(MaybeNext.takeError()); + return false; + } + Next = MaybeNext.get(); + continue; + } + + Scratch.clear(); + llvm::StringRef BlobData; + llvm::Expected MaybeKind = + Cursor.readRecord(Next.ID, Scratch, &BlobData); + if (!MaybeKind) { + // FIXME this drops the error on the floor. + consumeError(MaybeKind.takeError()); + return false; + } + unsigned Kind = MaybeKind.get(); + switch (Kind) { + case cxx_method_block::CXX_METHOD_DATA: { + // Already saw C++ method table. + if (CXXMethodTable) + return true; + + uint32_t tableOffset; + cxx_method_block::CXXMethodDataLayout::readRecord(Scratch, tableOffset); + auto base = reinterpret_cast(BlobData.data()); + + CXXMethodTable.reset(SerializedCXXMethodTable::Create( + base + tableOffset, base + sizeof(uint32_t), base)); + break; + } + + default: + // Unknown record, possibly for use by a future version of the + // module format. + break; + } + + MaybeNext = Cursor.advance(); + if (!MaybeNext) { + // FIXME this drops the error on the floor. + consumeError(MaybeNext.takeError()); + return false; + } + Next = MaybeNext.get(); + } + + return false; +} + bool APINotesReader::Implementation::readObjCSelectorBlock( llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl &Scratch) { if (Cursor.EnterSubBlock(OBJC_SELECTOR_BLOCK_ID)) @@ -1700,6 +1798,14 @@ APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer, } break; + case CXX_METHOD_BLOCK_ID: + if (!HasValidControlBlock || + Implementation->readCXXMethodBlock(Cursor, Scratch)) { + Failed = true; + return; + } + break; + case OBJC_SELECTOR_BLOCK_ID: if (!HasValidControlBlock || Implementation->readObjCSelectorBlock(Cursor, Scratch)) { @@ -1919,6 +2025,23 @@ auto APINotesReader::lookupObjCMethod(ContextID CtxID, ObjCSelectorRef Selector, return {Implementation->SwiftVersion, *Known}; } +auto APINotesReader::lookupCXXMethod(ContextID CtxID, llvm::StringRef Name) + -> VersionedInfo { + if (!Implementation->CXXMethodTable) + return std::nullopt; + + std::optional NameID = Implementation->getIdentifier(Name); + if (!NameID) + return std::nullopt; + + auto Known = Implementation->CXXMethodTable->find( + SingleDeclTableKey(CtxID.Value, *NameID)); + if (Known == Implementation->CXXMethodTable->end()) + return std::nullopt; + + return {Implementation->SwiftVersion, *Known}; +} + auto APINotesReader::lookupGlobalVariable(llvm::StringRef Name, std::optional Ctx) -> VersionedInfo { @@ -1929,7 +2052,7 @@ auto APINotesReader::lookupGlobalVariable(llvm::StringRef Name, if (!NameID) return std::nullopt; - ContextTableKey Key(Ctx, *NameID); + SingleDeclTableKey Key(Ctx, *NameID); auto Known = Implementation->GlobalVariableTable->find(Key); if (Known == Implementation->GlobalVariableTable->end()) @@ -1948,7 +2071,7 @@ auto APINotesReader::lookupGlobalFunction(llvm::StringRef Name, if (!NameID) return std::nullopt; - ContextTableKey Key(Ctx, *NameID); + SingleDeclTableKey Key(Ctx, *NameID); auto Known = Implementation->GlobalFunctionTable->find(Key); if (Known == Implementation->GlobalFunctionTable->end()) @@ -1973,6 +2096,24 @@ auto APINotesReader::lookupEnumConstant(llvm::StringRef Name) return {Implementation->SwiftVersion, *Known}; } +auto APINotesReader::lookupTagID(llvm::StringRef Name, + std::optional ParentCtx) + -> std::optional { + if (!Implementation->ContextIDTable) + return std::nullopt; + + std::optional TagID = Implementation->getIdentifier(Name); + if (!TagID) + return std::nullopt; + + auto KnownID = Implementation->ContextIDTable->find( + ContextTableKey(ParentCtx, ContextKind::Tag, *TagID)); + if (KnownID == Implementation->ContextIDTable->end()) + return std::nullopt; + + return ContextID(*KnownID); +} + auto APINotesReader::lookupTag(llvm::StringRef Name, std::optional Ctx) -> VersionedInfo { if (!Implementation->TagTable) @@ -1982,7 +2123,7 @@ auto APINotesReader::lookupTag(llvm::StringRef Name, std::optional Ctx) if (!NameID) return std::nullopt; - ContextTableKey Key(Ctx, *NameID); + SingleDeclTableKey Key(Ctx, *NameID); auto Known = Implementation->TagTable->find(Key); if (Known == Implementation->TagTable->end()) @@ -2001,7 +2142,7 @@ auto APINotesReader::lookupTypedef(llvm::StringRef Name, if (!NameID) return std::nullopt; - ContextTableKey Key(Ctx, *NameID); + SingleDeclTableKey Key(Ctx, *NameID); auto Known = Implementation->TypedefTable->find(Key); if (Known == Implementation->TypedefTable->end()) diff --git a/clang/lib/APINotes/APINotesWriter.cpp b/clang/lib/APINotes/APINotesWriter.cpp index 4053d515ef426..2a71922746ac5 100644 --- a/clang/lib/APINotes/APINotesWriter.cpp +++ b/clang/lib/APINotes/APINotesWriter.cpp @@ -70,22 +70,29 @@ class APINotesWriter::Implementation { llvm::SmallVector, 1>> ObjCMethods; + /// Information about C++ methods. + /// + /// Indexed by the context ID and name ID. + llvm::DenseMap, 1>> + CXXMethods; + /// Mapping from selectors to selector ID. llvm::DenseMap SelectorIDs; /// Information about global variables. /// - /// Indexed by the context ID, contextKind, identifier ID. + /// Indexed by the context ID, identifier ID. llvm::DenseMap< - ContextTableKey, + SingleDeclTableKey, llvm::SmallVector, 1>> GlobalVariables; /// Information about global functions. /// - /// Indexed by the context ID, contextKind, identifier ID. + /// Indexed by the context ID, identifier ID. llvm::DenseMap< - ContextTableKey, + SingleDeclTableKey, llvm::SmallVector, 1>> GlobalFunctions; @@ -98,15 +105,15 @@ class APINotesWriter::Implementation { /// Information about tags. /// - /// Indexed by the context ID, contextKind, identifier ID. - llvm::DenseMap, 1>> Tags; /// Information about typedefs. /// - /// Indexed by the context ID, contextKind, identifier ID. - llvm::DenseMap, 1>> Typedefs; @@ -150,6 +157,7 @@ class APINotesWriter::Implementation { void writeContextBlock(llvm::BitstreamWriter &Stream); void writeObjCPropertyBlock(llvm::BitstreamWriter &Stream); void writeObjCMethodBlock(llvm::BitstreamWriter &Stream); + void writeCXXMethodBlock(llvm::BitstreamWriter &Stream); void writeObjCSelectorBlock(llvm::BitstreamWriter &Stream); void writeGlobalVariableBlock(llvm::BitstreamWriter &Stream); void writeGlobalFunctionBlock(llvm::BitstreamWriter &Stream); @@ -181,6 +189,7 @@ void APINotesWriter::Implementation::writeToStream(llvm::raw_ostream &OS) { writeContextBlock(Stream); writeObjCPropertyBlock(Stream); writeObjCMethodBlock(Stream); + writeCXXMethodBlock(Stream); writeObjCSelectorBlock(Stream); writeGlobalVariableBlock(Stream); writeGlobalFunctionBlock(Stream); @@ -765,6 +774,34 @@ class ObjCMethodTableInfo emitFunctionInfo(OS, OMI); } }; + +/// Used to serialize the on-disk C++ method table. +class CXXMethodTableInfo + : public VersionedTableInfo { +public: + unsigned getKeyLength(key_type_ref) { + return sizeof(uint32_t) + sizeof(uint32_t); + } + + void EmitKey(raw_ostream &OS, key_type_ref Key, unsigned) { + llvm::support::endian::Writer writer(OS, llvm::endianness::little); + writer.write(Key.parentContextID); + writer.write(Key.nameID); + } + + hash_value_type ComputeHash(key_type_ref key) { + return static_cast(key.hashValue()); + } + + unsigned getUnversionedInfoSize(const CXXMethodInfo &OMI) { + return getFunctionInfoSize(OMI); + } + + void emitUnversionedInfo(raw_ostream &OS, const CXXMethodInfo &OMI) { + emitFunctionInfo(OS, OMI); + } +}; } // namespace void APINotesWriter::Implementation::writeObjCMethodBlock( @@ -794,6 +831,33 @@ void APINotesWriter::Implementation::writeObjCMethodBlock( } } +void APINotesWriter::Implementation::writeCXXMethodBlock( + llvm::BitstreamWriter &Stream) { + llvm::BCBlockRAII Scope(Stream, CXX_METHOD_BLOCK_ID, 3); + + if (CXXMethods.empty()) + return; + + { + llvm::SmallString<4096> HashTableBlob; + uint32_t Offset; + { + llvm::OnDiskChainedHashTableGenerator Generator; + for (auto &MD : CXXMethods) + Generator.insert(MD.first, MD.second); + + llvm::raw_svector_ostream BlobStream(HashTableBlob); + // Make sure that no bucket is at offset 0 + llvm::support::endian::write(BlobStream, 0, + llvm::endianness::little); + Offset = Generator.Emit(BlobStream); + } + + cxx_method_block::CXXMethodDataLayout CXXMethodData(Stream); + CXXMethodData.emit(Scratch, Offset, HashTableBlob); + } +} + namespace { /// Used to serialize the on-disk Objective-C selector table. class ObjCSelectorTableInfo { @@ -865,18 +929,17 @@ void APINotesWriter::Implementation::writeObjCSelectorBlock( namespace { /// Used to serialize the on-disk global variable table. class GlobalVariableTableInfo - : public VersionedTableInfo { public: unsigned getKeyLength(key_type_ref) { - return sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t); + return sizeof(uint32_t) + sizeof(uint32_t); } void EmitKey(raw_ostream &OS, key_type_ref Key, unsigned) { llvm::support::endian::Writer writer(OS, llvm::endianness::little); writer.write(Key.parentContextID); - writer.write(Key.contextKind); - writer.write(Key.contextID); + writer.write(Key.nameID); } hash_value_type ComputeHash(key_type_ref Key) { @@ -979,18 +1042,17 @@ void emitFunctionInfo(raw_ostream &OS, const FunctionInfo &FI) { /// Used to serialize the on-disk global function table. class GlobalFunctionTableInfo - : public VersionedTableInfo { public: unsigned getKeyLength(key_type_ref) { - return sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t); + return sizeof(uint32_t) + sizeof(uint32_t); } void EmitKey(raw_ostream &OS, key_type_ref Key, unsigned) { llvm::support::endian::Writer writer(OS, llvm::endianness::little); writer.write(Key.parentContextID); - writer.write(Key.contextKind); - writer.write(Key.contextID); + writer.write(Key.nameID); } hash_value_type ComputeHash(key_type_ref Key) { @@ -1091,20 +1153,20 @@ void APINotesWriter::Implementation::writeEnumConstantBlock( namespace { template class CommonTypeTableInfo - : public VersionedTableInfo { + : public VersionedTableInfo { public: using key_type_ref = typename CommonTypeTableInfo::key_type_ref; using hash_value_type = typename CommonTypeTableInfo::hash_value_type; unsigned getKeyLength(key_type_ref) { - return sizeof(uint32_t) + sizeof(uint8_t) + sizeof(IdentifierID); + return sizeof(uint32_t) + sizeof(IdentifierID); } void EmitKey(raw_ostream &OS, key_type_ref Key, unsigned) { llvm::support::endian::Writer writer(OS, llvm::endianness::little); writer.write(Key.parentContextID); - writer.write(Key.contextKind); - writer.write(Key.contextID); + writer.write(Key.nameID); } hash_value_type ComputeHash(key_type_ref Key) { @@ -1346,12 +1408,20 @@ void APINotesWriter::addObjCMethod(ContextID CtxID, ObjCSelectorRef Selector, } } +void APINotesWriter::addCXXMethod(ContextID CtxID, llvm::StringRef Name, + const CXXMethodInfo &Info, + VersionTuple SwiftVersion) { + IdentifierID NameID = Implementation->getIdentifier(Name); + SingleDeclTableKey Key(CtxID.Value, NameID); + Implementation->CXXMethods[Key].push_back({SwiftVersion, Info}); +} + void APINotesWriter::addGlobalVariable(std::optional Ctx, llvm::StringRef Name, const GlobalVariableInfo &Info, VersionTuple SwiftVersion) { IdentifierID VariableID = Implementation->getIdentifier(Name); - ContextTableKey Key(Ctx, VariableID); + SingleDeclTableKey Key(Ctx, VariableID); Implementation->GlobalVariables[Key].push_back({SwiftVersion, Info}); } @@ -1360,7 +1430,7 @@ void APINotesWriter::addGlobalFunction(std::optional Ctx, const GlobalFunctionInfo &Info, VersionTuple SwiftVersion) { IdentifierID NameID = Implementation->getIdentifier(Name); - ContextTableKey Key(Ctx, NameID); + SingleDeclTableKey Key(Ctx, NameID); Implementation->GlobalFunctions[Key].push_back({SwiftVersion, Info}); } @@ -1374,7 +1444,7 @@ void APINotesWriter::addEnumConstant(llvm::StringRef Name, void APINotesWriter::addTag(std::optional Ctx, llvm::StringRef Name, const TagInfo &Info, VersionTuple SwiftVersion) { IdentifierID TagID = Implementation->getIdentifier(Name); - ContextTableKey Key(Ctx, TagID); + SingleDeclTableKey Key(Ctx, TagID); Implementation->Tags[Key].push_back({SwiftVersion, Info}); } @@ -1382,7 +1452,7 @@ void APINotesWriter::addTypedef(std::optional Ctx, llvm::StringRef Name, const TypedefInfo &Info, VersionTuple SwiftVersion) { IdentifierID TypedefID = Implementation->getIdentifier(Name); - ContextTableKey Key(Ctx, TypedefID); + SingleDeclTableKey Key(Ctx, TypedefID); Implementation->Typedefs[Key].push_back({SwiftVersion, Info}); } } // namespace api_notes diff --git a/clang/lib/APINotes/APINotesYAMLCompiler.cpp b/clang/lib/APINotes/APINotesYAMLCompiler.cpp index 870b64e3b7a9b..11cccc94a15f0 100644 --- a/clang/lib/APINotes/APINotesYAMLCompiler.cpp +++ b/clang/lib/APINotes/APINotesYAMLCompiler.cpp @@ -406,6 +406,9 @@ template <> struct ScalarEnumerationTraits { } // namespace llvm namespace { +struct Tag; +typedef std::vector TagsSeq; + struct Tag { StringRef Name; AvailabilityItem Availability; @@ -420,9 +423,12 @@ struct Tag { std::optional FlagEnum; std::optional EnumConvenienceKind; std::optional SwiftCopyable; -}; + FunctionsSeq Methods; -typedef std::vector TagsSeq; + /// Tags that are declared within the current tag. Only the tags that have + /// corresponding API Notes will be listed. + TagsSeq Tags; +}; } // namespace LLVM_YAML_IS_SEQUENCE_VECTOR(Tag) @@ -454,6 +460,8 @@ template <> struct MappingTraits { IO.mapOptional("FlagEnum", T.FlagEnum); IO.mapOptional("EnumKind", T.EnumConvenienceKind); IO.mapOptional("SwiftCopyable", T.SwiftCopyable); + IO.mapOptional("Methods", T.Methods); + IO.mapOptional("Tags", T.Tags); } }; } // namespace yaml @@ -874,6 +882,101 @@ class YAMLConverter { TheNamespace.Items, SwiftVersion); } + void convertFunction(const Function &Function, FunctionInfo &FI) { + convertAvailability(Function.Availability, FI, Function.Name); + FI.setSwiftPrivate(Function.SwiftPrivate); + FI.SwiftName = std::string(Function.SwiftName); + convertParams(Function.Params, FI); + convertNullability(Function.Nullability, Function.NullabilityOfRet, FI, + Function.Name); + FI.ResultType = std::string(Function.ResultType); + FI.setRetainCountConvention(Function.RetainCountConvention); + } + + void convertTagContext(std::optional ParentContext, const Tag &T, + VersionTuple SwiftVersion) { + TagInfo TI; + std::optional ParentContextID = + ParentContext ? std::optional(ParentContext->id) + : std::nullopt; + convertCommonType(T, TI, T.Name); + + if ((T.SwiftRetainOp || T.SwiftReleaseOp) && !T.SwiftImportAs) { + emitError(llvm::Twine("should declare SwiftImportAs to use " + "SwiftRetainOp and SwiftReleaseOp (for ") + + T.Name + ")"); + return; + } + if (T.SwiftReleaseOp.has_value() != T.SwiftRetainOp.has_value()) { + emitError(llvm::Twine("should declare both SwiftReleaseOp and " + "SwiftRetainOp (for ") + + T.Name + ")"); + return; + } + + if (T.SwiftImportAs) + TI.SwiftImportAs = T.SwiftImportAs; + if (T.SwiftRetainOp) + TI.SwiftRetainOp = T.SwiftRetainOp; + if (T.SwiftReleaseOp) + TI.SwiftReleaseOp = T.SwiftReleaseOp; + + if (T.SwiftCopyable) + TI.setSwiftCopyable(T.SwiftCopyable); + + if (T.EnumConvenienceKind) { + if (T.EnumExtensibility) { + emitError( + llvm::Twine("cannot mix EnumKind and EnumExtensibility (for ") + + T.Name + ")"); + return; + } + if (T.FlagEnum) { + emitError(llvm::Twine("cannot mix EnumKind and FlagEnum (for ") + + T.Name + ")"); + return; + } + switch (*T.EnumConvenienceKind) { + case EnumConvenienceAliasKind::None: + TI.EnumExtensibility = EnumExtensibilityKind::None; + TI.setFlagEnum(false); + break; + case EnumConvenienceAliasKind::CFEnum: + TI.EnumExtensibility = EnumExtensibilityKind::Open; + TI.setFlagEnum(false); + break; + case EnumConvenienceAliasKind::CFOptions: + TI.EnumExtensibility = EnumExtensibilityKind::Open; + TI.setFlagEnum(true); + break; + case EnumConvenienceAliasKind::CFClosedEnum: + TI.EnumExtensibility = EnumExtensibilityKind::Closed; + TI.setFlagEnum(false); + break; + } + } else { + TI.EnumExtensibility = T.EnumExtensibility; + TI.setFlagEnum(T.FlagEnum); + } + + Writer.addTag(ParentContext, T.Name, TI, SwiftVersion); + + ContextInfo CI; + auto TagCtxID = Writer.addContext(ParentContextID, T.Name, ContextKind::Tag, + CI, SwiftVersion); + Context TagCtx(TagCtxID, ContextKind::Tag); + + for (const auto &CXXMethod : T.Methods) { + CXXMethodInfo MI; + convertFunction(CXXMethod, MI); + Writer.addCXXMethod(TagCtxID, CXXMethod.Name, MI, SwiftVersion); + } + + // Convert nested tags. + for (const auto &Tag : T.Tags) + convertTagContext(TagCtx, Tag, SwiftVersion); + } + void convertTopLevelItems(std::optional Ctx, const TopLevelItems &TLItems, VersionTuple SwiftVersion) { @@ -950,14 +1053,7 @@ class YAMLConverter { } GlobalFunctionInfo GFI; - convertAvailability(Function.Availability, GFI, Function.Name); - GFI.setSwiftPrivate(Function.SwiftPrivate); - GFI.SwiftName = std::string(Function.SwiftName); - convertParams(Function.Params, GFI); - convertNullability(Function.Nullability, Function.NullabilityOfRet, GFI, - Function.Name); - GFI.ResultType = std::string(Function.ResultType); - GFI.setRetainCountConvention(Function.RetainCountConvention); + convertFunction(Function, GFI); Writer.addGlobalFunction(Ctx, Function.Name, GFI, SwiftVersion); } @@ -988,68 +1084,7 @@ class YAMLConverter { continue; } - TagInfo TI; - convertCommonType(Tag, TI, Tag.Name); - - if ((Tag.SwiftRetainOp || Tag.SwiftReleaseOp) && !Tag.SwiftImportAs) { - emitError(llvm::Twine("should declare SwiftImportAs to use " - "SwiftRetainOp and SwiftReleaseOp (for ") + - Tag.Name + ")"); - continue; - } - if (Tag.SwiftReleaseOp.has_value() != Tag.SwiftRetainOp.has_value()) { - emitError(llvm::Twine("should declare both SwiftReleaseOp and " - "SwiftRetainOp (for ") + - Tag.Name + ")"); - continue; - } - - if (Tag.SwiftImportAs) - TI.SwiftImportAs = Tag.SwiftImportAs; - if (Tag.SwiftRetainOp) - TI.SwiftRetainOp = Tag.SwiftRetainOp; - if (Tag.SwiftReleaseOp) - TI.SwiftReleaseOp = Tag.SwiftReleaseOp; - - if (Tag.SwiftCopyable) - TI.setSwiftCopyable(Tag.SwiftCopyable); - - if (Tag.EnumConvenienceKind) { - if (Tag.EnumExtensibility) { - emitError( - llvm::Twine("cannot mix EnumKind and EnumExtensibility (for ") + - Tag.Name + ")"); - continue; - } - if (Tag.FlagEnum) { - emitError(llvm::Twine("cannot mix EnumKind and FlagEnum (for ") + - Tag.Name + ")"); - continue; - } - switch (*Tag.EnumConvenienceKind) { - case EnumConvenienceAliasKind::None: - TI.EnumExtensibility = EnumExtensibilityKind::None; - TI.setFlagEnum(false); - break; - case EnumConvenienceAliasKind::CFEnum: - TI.EnumExtensibility = EnumExtensibilityKind::Open; - TI.setFlagEnum(false); - break; - case EnumConvenienceAliasKind::CFOptions: - TI.EnumExtensibility = EnumExtensibilityKind::Open; - TI.setFlagEnum(true); - break; - case EnumConvenienceAliasKind::CFClosedEnum: - TI.EnumExtensibility = EnumExtensibilityKind::Closed; - TI.setFlagEnum(false); - break; - } - } else { - TI.EnumExtensibility = Tag.EnumExtensibility; - TI.setFlagEnum(Tag.FlagEnum); - } - - Writer.addTag(Ctx, Tag.Name, TI, SwiftVersion); + convertTagContext(Ctx, Tag, SwiftVersion); } // Write all typedefs. diff --git a/clang/lib/AST/ASTConcept.cpp b/clang/lib/AST/ASTConcept.cpp index 95e7ac1a3d775..d8efbe44dbecb 100644 --- a/clang/lib/AST/ASTConcept.cpp +++ b/clang/lib/AST/ASTConcept.cpp @@ -28,11 +28,9 @@ CreateUnsatisfiedConstraintRecord(const ASTContext &C, else { auto &SubstitutionDiagnostic = *Detail.get *>(); - unsigned MessageSize = SubstitutionDiagnostic.second.size(); - char *Mem = new (C) char[MessageSize]; - memcpy(Mem, SubstitutionDiagnostic.second.data(), MessageSize); + StringRef Message = C.backupStr(SubstitutionDiagnostic.second); auto *NewSubstDiag = new (C) std::pair( - SubstitutionDiagnostic.first, StringRef(Mem, MessageSize)); + SubstitutionDiagnostic.first, Message); new (TrailingObject) UnsatisfiedConstraintRecord(NewSubstDiag); } } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 268faefe6f6cc..a779d136b9d31 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1389,7 +1389,8 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target, #include "clang/Basic/OpenCLExtensionTypes.def" } - if (Target.hasAArch64SVETypes()) { + if (Target.hasAArch64SVETypes() || + (AuxTarget && AuxTarget->hasAArch64SVETypes())) { #define SVE_TYPE(Name, Id, SingletonId) \ InitBuiltinType(SingletonId, BuiltinType::Id); #include "clang/Basic/AArch64SVEACLETypes.def" @@ -3234,14 +3235,16 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx, OS << ""; return; - case Type::Enum: + case Type::Enum: { // C11 6.7.2.2p4: // Each enumerated type shall be compatible with char, a signed integer // type, or an unsigned integer type. // // So we have to treat enum types as integers. + QualType UnderlyingType = cast(T)->getDecl()->getIntegerType(); return encodeTypeForFunctionPointerAuth( - Ctx, OS, cast(T)->getDecl()->getIntegerType()); + Ctx, OS, UnderlyingType.isNull() ? Ctx.IntTy : UnderlyingType); + } case Type::FunctionNoProto: case Type::FunctionProto: { @@ -3292,7 +3295,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx, return; case Type::Builtin: { - const auto *BTy = T->getAs(); + const auto *BTy = T->castAs(); switch (BTy->getKind()) { #define SIGNED_TYPE(Id, SingletonId) \ case BuiltinType::Id: \ @@ -3372,9 +3375,10 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx, #include "clang/Basic/RISCVVTypes.def" llvm_unreachable("not yet implemented"); } + llvm_unreachable("should never get here"); } case Type::Record: { - const RecordDecl *RD = T->getAs()->getDecl(); + const RecordDecl *RD = T->castAs()->getDecl(); const IdentifierInfo *II = RD->getIdentifier(); // In C++, an immediate typedef of an anonymous struct or union @@ -3416,7 +3420,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx, } } -uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) const { +uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) { assert(!T->isDependentType() && "cannot compute type discriminator of a dependent type"); @@ -3426,11 +3430,13 @@ uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) const { if (T->isFunctionPointerType() || T->isFunctionReferenceType()) T = T->getPointeeType(); - if (T->isFunctionType()) + if (T->isFunctionType()) { encodeTypeForFunctionPointerAuth(*this, Out, T); - else - llvm_unreachable( - "type discrimination of non-function type not implemented yet"); + } else { + T = T.getUnqualifiedType(); + std::unique_ptr MC(createMangleContext()); + MC->mangleCanonicalTypeName(T, Out); + } return llvm::getPointerAuthStableSipHash(Str); } diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 1d7d52db39d10..adff21df590cb 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -359,6 +359,54 @@ namespace clang { Params, Importer.getToContext().getTranslationUnitDecl()); } + template + void tryUpdateTemplateParmDeclInheritedFrom(NamedDecl *RecentParm, + NamedDecl *NewParm) { + if (auto *ParmT = dyn_cast(RecentParm)) { + if (ParmT->hasDefaultArgument()) { + auto *P = cast(NewParm); + P->removeDefaultArgument(); + P->setInheritedDefaultArgument(Importer.ToContext, ParmT); + } + } + } + + // Update the parameter list `NewParams` of a template declaration + // by "inheriting" default argument values from `RecentParams`, + // which is the parameter list of an earlier declaration of the + // same template. (Note that "inheriting" default argument values + // is not related to object-oriented inheritance.) + // + // In the clang AST template parameters (NonTypeTemplateParmDec, + // TemplateTypeParmDecl, TemplateTemplateParmDecl) have a reference to the + // default value, if one is specified at the first declaration. The default + // value can be specified only once. The template parameters of the + // following declarations have a reference to the original default value + // through the "inherited" value. This value should be set for all imported + // template parameters that have a previous declaration (also a previous + // template declaration). + // + // In the `Visit*ParmDecl` functions the default value of these template + // arguments is always imported. At that location the previous declaration + // is not easily accessible, it is not possible to call + // `setInheritedDefaultArgument` at that place. + // `updateTemplateParametersInheritedFrom` is called later when the already + // imported default value is erased and changed to "inherited". + // It is important to change the mode to "inherited" otherwise false + // structural in-equivalences could be detected. + void updateTemplateParametersInheritedFrom( + const TemplateParameterList &RecentParams, + TemplateParameterList &NewParams) { + for (auto [Idx, Param] : enumerate(RecentParams)) { + tryUpdateTemplateParmDeclInheritedFrom( + Param, NewParams.getParam(Idx)); + tryUpdateTemplateParmDeclInheritedFrom( + Param, NewParams.getParam(Idx)); + tryUpdateTemplateParmDeclInheritedFrom( + Param, NewParams.getParam(Idx)); + } + } + public: explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) {} @@ -2955,7 +3003,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) { if (auto *FoundEnum = dyn_cast(FoundDecl)) { if (!hasSameVisibilityContextAndLinkage(FoundEnum, D)) continue; - if (IsStructuralMatch(D, FoundEnum)) { + if (IsStructuralMatch(D, FoundEnum, !SearchName.isEmpty())) { EnumDecl *FoundDef = FoundEnum->getDefinition(); if (D->isThisDeclarationADefinition() && FoundDef) return Importer.MapImported(D, FoundDef); @@ -2966,7 +3014,12 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) { } } - if (!ConflictingDecls.empty()) { + // In case of unnamed enums, we try to find an existing similar one, if none + // was found, perform the import always. + // Structural in-equivalence is not detected in this way here, but it may + // be found when the parent decl is imported (if the enum is part of a + // class). To make this totally exact a more difficult solution is needed. + if (SearchName && !ConflictingDecls.empty()) { ExpectedName NameOrErr = Importer.HandleNameConflict( SearchName, DC, IDNS, ConflictingDecls.data(), ConflictingDecls.size()); @@ -4180,12 +4233,6 @@ ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl *D) { D->getInClassInitStyle())) return ToField; - // We need [[no_unqiue_address]] attributes to be added to FieldDecl, before - // we add fields in CXXRecordDecl::addedMember, otherwise record will be - // marked as having non-zero size. - Err = Importer.ImportAttrs(ToField, D); - if (Err) - return std::move(Err); ToField->setAccess(D->getAccess()); ToField->setLexicalDeclContext(LexicalDC); ToField->setImplicit(D->isImplicit()); @@ -6139,6 +6186,9 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) { } D2->setPreviousDecl(Recent); + + updateTemplateParametersInheritedFrom(*(Recent->getTemplateParameters()), + **TemplateParamsOrErr); } return D2; @@ -6453,6 +6503,9 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) { ToTemplated->setPreviousDecl(PrevTemplated); } ToVarTD->setPreviousDecl(Recent); + + updateTemplateParametersInheritedFrom(*(Recent->getTemplateParameters()), + **TemplateParamsOrErr); } return ToVarTD; @@ -6725,6 +6778,9 @@ ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { TemplatedFD->setPreviousDecl(PrevTemplated); } ToFunc->setPreviousDecl(Recent); + + updateTemplateParametersInheritedFrom(*(Recent->getTemplateParameters()), + *Params); } return ToFunc; @@ -9400,19 +9456,6 @@ TranslationUnitDecl *ASTImporter::GetFromTU(Decl *ToD) { return FromDPos->second->getTranslationUnitDecl(); } -Error ASTImporter::ImportAttrs(Decl *ToD, Decl *FromD) { - if (!FromD->hasAttrs() || ToD->hasAttrs()) - return Error::success(); - for (const Attr *FromAttr : FromD->getAttrs()) { - auto ToAttrOrErr = Import(FromAttr); - if (ToAttrOrErr) - ToD->addAttr(*ToAttrOrErr); - else - return ToAttrOrErr.takeError(); - } - return Error::success(); -} - Expected ASTImporter::Import(Decl *FromD) { if (!FromD) return nullptr; @@ -9546,8 +9589,15 @@ Expected ASTImporter::Import(Decl *FromD) { } // Make sure that ImportImpl registered the imported decl. assert(ImportedDecls.count(FromD) != 0 && "Missing call to MapImported?"); - if (auto Error = ImportAttrs(ToD, FromD)) - return std::move(Error); + + if (FromD->hasAttrs()) + for (const Attr *FromAttr : FromD->getAttrs()) { + auto ToAttrOrErr = Import(FromAttr); + if (ToAttrOrErr) + ToD->addAttr(*ToAttrOrErr); + else + return ToAttrOrErr.takeError(); + } // Notify subclasses. Imported(FromD, ToD); diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index bc5a9206c0db2..a1f70546bde42 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -879,8 +879,6 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { return IDNS_Ordinary; case Label: return IDNS_Label; - case IndirectField: - return IDNS_Ordinary | IDNS_Member; case Binding: case NonTypeTemplateParm: @@ -918,6 +916,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { return IDNS_ObjCProtocol; case Field: + case IndirectField: case ObjCAtDefsField: case ObjCIvar: return IDNS_Member; diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 72d68f39a97a5..9a3ede426e914 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -561,6 +561,42 @@ void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) { data().StructuralIfLiteral = false; } +const CXXRecordDecl *CXXRecordDecl::getStandardLayoutBaseWithFields() const { + assert( + isStandardLayout() && + "getStandardLayoutBaseWithFields called on a non-standard-layout type"); +#ifdef EXPENSIVE_CHECKS + { + unsigned NumberOfBasesWithFields = 0; + if (!field_empty()) + ++NumberOfBasesWithFields; + llvm::SmallPtrSet UniqueBases; + forallBases([&](const CXXRecordDecl *Base) -> bool { + if (!Base->field_empty()) + ++NumberOfBasesWithFields; + assert( + UniqueBases.insert(Base->getCanonicalDecl()).second && + "Standard layout struct has multiple base classes of the same type"); + return true; + }); + assert(NumberOfBasesWithFields <= 1 && + "Standard layout struct has fields declared in more than one class"); + } +#endif + if (!field_empty()) + return this; + const CXXRecordDecl *Result = this; + forallBases([&](const CXXRecordDecl *Base) -> bool { + if (!Base->field_empty()) { + // This is the base where the fields are declared; return early + Result = Base; + return false; + } + return true; + }); + return Result; +} + bool CXXRecordDecl::hasConstexprDestructor() const { auto *Dtor = getDestructor(); return Dtor ? Dtor->isConstexpr() : defaultedDestructorIsConstexpr(); @@ -675,6 +711,9 @@ bool CXXRecordDecl::hasSubobjectAtOffsetZeroOfEmptyBaseType( if (!IsFirstField && !FD->isZeroSize(Ctx)) continue; + if (FD->isInvalidDecl()) + continue; + // -- If X is n array type, [visit the element type] QualType T = Ctx.getBaseElementType(FD->getType()); if (auto *RD = T->getAsCXXRecordDecl()) diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 722c7fcf0b0df..976b3a3e1eced 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -44,6 +44,12 @@ using namespace clang; // TemplateParameterList Implementation //===----------------------------------------------------------------------===// +template +static bool +DefaultTemplateArgumentContainsUnexpandedPack(const TemplateParam &P) { + return P.hasDefaultArgument() && + P.getDefaultArgument().getArgument().containsUnexpandedParameterPack(); +} TemplateParameterList::TemplateParameterList(const ASTContext& C, SourceLocation TemplateLoc, @@ -61,27 +67,30 @@ TemplateParameterList::TemplateParameterList(const ASTContext& C, bool IsPack = P->isTemplateParameterPack(); if (const auto *NTTP = dyn_cast(P)) { - if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack()) + if (!IsPack && (NTTP->getType()->containsUnexpandedParameterPack() || + DefaultTemplateArgumentContainsUnexpandedPack(*NTTP))) ContainsUnexpandedParameterPack = true; if (NTTP->hasPlaceholderTypeConstraint()) HasConstrainedParameters = true; } else if (const auto *TTP = dyn_cast(P)) { if (!IsPack && - TTP->getTemplateParameters()->containsUnexpandedParameterPack()) + (TTP->getTemplateParameters()->containsUnexpandedParameterPack() || + DefaultTemplateArgumentContainsUnexpandedPack(*TTP))) { ContainsUnexpandedParameterPack = true; + } } else if (const auto *TTP = dyn_cast(P)) { - if (const TypeConstraint *TC = TTP->getTypeConstraint()) { - if (TC->getImmediatelyDeclaredConstraint() - ->containsUnexpandedParameterPack()) - ContainsUnexpandedParameterPack = true; + if (!IsPack && DefaultTemplateArgumentContainsUnexpandedPack(*TTP)) { + ContainsUnexpandedParameterPack = true; + } else if (const TypeConstraint *TC = TTP->getTypeConstraint(); + TC && TC->getImmediatelyDeclaredConstraint() + ->containsUnexpandedParameterPack()) { + ContainsUnexpandedParameterPack = true; } if (TTP->hasTypeConstraint()) HasConstrainedParameters = true; } else { llvm_unreachable("unexpected template parameter type"); } - // FIXME: If a default argument contains an unexpanded parameter pack, the - // template parameter list does too. } if (HasRequiresClause) { diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index f6956f132bd93..ec2ffeb9ef44c 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -2428,7 +2428,7 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx, EmbedExpr::EmbedExpr(const ASTContext &Ctx, SourceLocation Loc, EmbedDataStorage *Data, unsigned Begin, unsigned NumOfElements) - : Expr(EmbedExprClass, Ctx.UnsignedCharTy, VK_PRValue, OK_Ordinary), + : Expr(EmbedExprClass, Ctx.IntTy, VK_PRValue, OK_Ordinary), EmbedKeywordLoc(Loc), Ctx(&Ctx), Data(Data), Begin(Begin), NumOfElements(NumOfElements) { setDependence(ExprDependence::None); diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 8d2a1b5611ccc..6212989e21737 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -152,7 +152,7 @@ bool CXXTypeidExpr::isMostDerived(ASTContext &Context) const { const Expr *E = getExprOperand()->IgnoreParenNoopCasts(Context); if (const auto *DRE = dyn_cast(E)) { QualType Ty = DRE->getDecl()->getType(); - if (!Ty->isPointerType() && !Ty->isReferenceType()) + if (!Ty->isPointerOrReferenceType()) return true; } @@ -1944,3 +1944,22 @@ CXXParenListInitExpr *CXXParenListInitExpr::CreateEmpty(ASTContext &C, alignof(CXXParenListInitExpr)); return new (Mem) CXXParenListInitExpr(Empty, NumExprs); } + +CXXFoldExpr::CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee, + SourceLocation LParenLoc, Expr *LHS, + BinaryOperatorKind Opcode, + SourceLocation EllipsisLoc, Expr *RHS, + SourceLocation RParenLoc, + std::optional NumExpansions) + : Expr(CXXFoldExprClass, T, VK_PRValue, OK_Ordinary), LParenLoc(LParenLoc), + EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc), + NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) { + // We rely on asserted invariant to distinguish left and right folds. + assert(((LHS && LHS->containsUnexpandedParameterPack()) != + (RHS && RHS->containsUnexpandedParameterPack())) && + "Exactly one of LHS or RHS should contain an unexpanded pack"); + SubExprs[SubExpr::Callee] = Callee; + SubExprs[SubExpr::LHS] = LHS; + SubExprs[SubExpr::RHS] = RHS; + setDependence(computeDependence(this)); +} diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 04061616dc5e9..7e6279f7dd25c 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -119,12 +119,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { // First come the expressions that are always lvalues, unconditionally. case Expr::ObjCIsaExprClass: - // C++ [expr.prim.general]p1: A string literal is an lvalue. - case Expr::StringLiteralClass: - // @encode is equivalent to its string - case Expr::ObjCEncodeExprClass: - // __func__ and friends are too. - case Expr::PredefinedExprClass: // Property references are lvalues case Expr::ObjCSubscriptRefExprClass: case Expr::ObjCPropertyRefExprClass: @@ -150,6 +144,26 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::OMPIteratorExprClass: return Cl::CL_LValue; + // C++ [expr.prim.general]p1: A string literal is an lvalue. + case Expr::StringLiteralClass: + // @encode is equivalent to its string + case Expr::ObjCEncodeExprClass: + // Except we special case them as prvalues when they are used to + // initialize a char array. + return E->isLValue() ? Cl::CL_LValue : Cl::CL_PRValue; + + // __func__ and friends are too. + // The char array initialization special case also applies + // when they are transparent. + case Expr::PredefinedExprClass: { + auto *PE = cast(E); + const StringLiteral *SL = PE->getFunctionName(); + if (PE->isTransparent()) + return SL ? ClassifyInternal(Ctx, SL) : Cl::CL_LValue; + assert(!SL || SL->isLValue()); + return Cl::CL_LValue; + } + // C99 6.5.2.5p5 says that compound literals are lvalues. // In C++, they're prvalue temporaries, except for file-scope arrays. case Expr::CompoundLiteralExprClass: diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 3f7c2e6775e65..18fe6e4f19d4e 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2401,6 +2401,10 @@ static bool CheckMemberPointerConstantExpression(EvalInfo &Info, /// produce an appropriate diagnostic. static bool CheckLiteralType(EvalInfo &Info, const Expr *E, const LValue *This = nullptr) { + // The restriction to literal types does not exist in C++23 anymore. + if (Info.getLangOpts().CPlusPlus23) + return true; + if (!E->isPRValue() || E->getType()->isLiteralType(Info.Ctx)) return true; @@ -2839,6 +2843,8 @@ static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, // During constant-folding, a negative shift is an opposite shift. Such // a shift is not a constant expression. Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS; + if (!Info.noteUndefinedBehavior()) + return false; RHS = -RHS; goto shift_right; } @@ -2849,19 +2855,23 @@ static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, if (SA != RHS) { Info.CCEDiag(E, diag::note_constexpr_large_shift) << RHS << E->getType() << LHS.getBitWidth(); + if (!Info.noteUndefinedBehavior()) + return false; } else if (LHS.isSigned() && !Info.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. - if (LHS.isNegative()) + if (LHS.isNegative()) { Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS; - else if (LHS.countl_zero() < SA) + if (!Info.noteUndefinedBehavior()) + return false; + } else if (LHS.countl_zero() < SA) { Info.CCEDiag(E, diag::note_constexpr_lshift_discards); + if (!Info.noteUndefinedBehavior()) + return false; + } } - if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() && - Info.getLangOpts().CPlusPlus11) - return false; Result = LHS << SA; return true; } @@ -2875,6 +2885,8 @@ static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, // During constant-folding, a negative shift is an opposite shift. Such a // shift is not a constant expression. Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS; + if (!Info.noteUndefinedBehavior()) + return false; RHS = -RHS; goto shift_left; } @@ -2882,13 +2894,13 @@ static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, // C++11 [expr.shift]p1: Shift width must be less than the bit width of the // shifted type. unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1); - if (SA != RHS) + if (SA != RHS) { Info.CCEDiag(E, diag::note_constexpr_large_shift) << RHS << E->getType() << LHS.getBitWidth(); + if (!Info.noteUndefinedBehavior()) + return false; + } - if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() && - Info.getLangOpts().CPlusPlus11) - return false; Result = LHS >> SA; return true; } @@ -12979,19 +12991,35 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth(); if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) { if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free || - Size == CharUnits::One() || - E->getArg(1)->isNullPointerConstant(Info.Ctx, - Expr::NPC_NeverValueDependent)) - // OK, we will inline appropriately-aligned operations of this size, - // and _Atomic(T) is appropriately-aligned. + Size == CharUnits::One()) return Success(1, E); - QualType PointeeType = E->getArg(1)->IgnoreImpCasts()->getType()-> - castAs()->getPointeeType(); - if (!PointeeType->isIncompleteType() && - Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) { - // OK, we will inline operations on this object. + // If the pointer argument can be evaluated to a compile-time constant + // integer (or nullptr), check if that value is appropriately aligned. + const Expr *PtrArg = E->getArg(1); + Expr::EvalResult ExprResult; + APSInt IntResult; + if (PtrArg->EvaluateAsRValue(ExprResult, Info.Ctx) && + ExprResult.Val.toIntegralConstant(IntResult, PtrArg->getType(), + Info.Ctx) && + IntResult.isAligned(Size.getAsAlign())) return Success(1, E); + + // Otherwise, check if the type's alignment against Size. + if (auto *ICE = dyn_cast(PtrArg)) { + // Drop the potential implicit-cast to 'const volatile void*', getting + // the underlying type. + if (ICE->getCastKind() == CK_BitCast) + PtrArg = ICE->getSubExpr(); + } + + if (auto PtrTy = PtrArg->getType()->getAs()) { + QualType PointeeType = PtrTy->getPointeeType(); + if (!PointeeType->isIncompleteType() && + Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) { + // OK, we will inline operations on this object. + return Success(1, E); + } } } } @@ -14068,6 +14096,12 @@ bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr( E); } + case UETT_PtrAuthTypeDiscriminator: { + if (E->getArgumentType()->isDependentType()) + return false; + return Success( + Info.Ctx.getPointerAuthTypeDiscriminator(E->getArgumentType()), E); + } case UETT_VecStep: { QualType Ty = E->getTypeOfArgument(); diff --git a/clang/lib/AST/Interp/Boolean.h b/clang/lib/AST/Interp/Boolean.h index 1bfb26b1b669f..23f7286036764 100644 --- a/clang/lib/AST/Interp/Boolean.h +++ b/clang/lib/AST/Interp/Boolean.h @@ -56,7 +56,7 @@ class Boolean final { APSInt toAPSInt(unsigned NumBits) const { return APSInt(toAPSInt().zextOrTrunc(NumBits), true); } - APValue toAPValue() const { return APValue(toAPSInt()); } + APValue toAPValue(const ASTContext &) const { return APValue(toAPSInt()); } Boolean toUnsigned() const { return *this; } diff --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp b/clang/lib/AST/Interp/ByteCodeEmitter.cpp index a3d4c7d7392da..a01fa15dc0b7d 100644 --- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp +++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp @@ -27,7 +27,9 @@ using namespace clang::interp; /// Similar information is available via ASTContext::BuiltinInfo, /// but that is not correct for our use cases. static bool isUnevaluatedBuiltin(unsigned BuiltinID) { - return BuiltinID == Builtin::BI__builtin_classify_type; + return BuiltinID == Builtin::BI__builtin_classify_type || + BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size || + BuiltinID == Builtin::BI__builtin_constant_p; } Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) { diff --git a/clang/lib/AST/Interp/Compiler.cpp b/clang/lib/AST/Interp/Compiler.cpp index 28c4ffd071862..258e4ed645254 100644 --- a/clang/lib/AST/Interp/Compiler.cpp +++ b/clang/lib/AST/Interp/Compiler.cpp @@ -89,6 +89,10 @@ bool InitLink::emit(Compiler *Ctx, const Expr *E) const { return Ctx->emitGetPtrLocal(Offset, E); case K_Decl: return Ctx->visitDeclRef(D, E); + case K_Elem: + if (!Ctx->emitConstUint32(Offset, E)) + return false; + return Ctx->emitArrayElemPtrPopUint32(E); default: llvm_unreachable("Unhandled InitLink kind"); } @@ -466,6 +470,16 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { if (!this->visit(SubExpr)) return false; + // Possibly diagnose casts to enum types if the target type does not + // have a fixed size. + if (Ctx.getLangOpts().CPlusPlus && CE->getType()->isEnumeralType()) { + if (const auto *ET = CE->getType().getCanonicalType()->getAs(); + ET && !ET->getDecl()->isFixed()) { + if (!this->emitCheckEnumValue(*FromT, ET->getDecl(), CE)) + return false; + } + } + if (ToT == PT_IntAP) return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->getType()), CE); if (ToT == PT_IntAPS) @@ -1324,6 +1338,7 @@ bool Compiler::visitInitList(ArrayRef Inits, auto initPrimitiveField = [=](const Record::Field *FieldToInit, const Expr *Init, PrimType T) -> bool { + InitStackScope ISS(this, isa(Init)); if (!this->visit(Init)) return false; @@ -1334,6 +1349,7 @@ bool Compiler::visitInitList(ArrayRef Inits, auto initCompositeField = [=](const Record::Field *FieldToInit, const Expr *Init) -> bool { + InitStackScope ISS(this, isa(Init)); InitLinkScope ILS(this, InitLink::Field(FieldToInit->Offset)); // Non-primitive case. Get a pointer to the field-to-initialize // on the stack and recurse into visitInitializer(). @@ -1544,6 +1560,7 @@ bool Compiler::visitArrayElemInit(unsigned ElemIndex, return this->emitInitElem(*T, ElemIndex, Init); } + InitLinkScope ILS(this, InitLink::Elem(ElemIndex)); // Advance the pointer currently on the stack to the given // dimension. if (!this->emitConstUint32(ElemIndex, Init)) @@ -1686,10 +1703,8 @@ bool Compiler::VisitUnaryExprOrTypeTraitExpr( if (Kind == UETT_VectorElements) { if (const auto *VT = E->getTypeOfArgument()->getAs()) return this->emitConst(VT->getNumElements(), E); - - // FIXME: Apparently we need to catch the fact that a sizeless vector type - // has been passed and diagnose that (at run time). assert(E->getTypeOfArgument()->isSizelessVectorType()); + return this->emitSizelessVectorElementSize(E); } if (Kind == UETT_VecStep) { @@ -3184,13 +3199,9 @@ bool Compiler::VisitStmtExpr(const StmtExpr *E) { } assert(S == Result); - if (const Expr *ResultExpr = dyn_cast(S)) { - if (DiscardResult) - return this->discard(ResultExpr); + if (const Expr *ResultExpr = dyn_cast(S)) return this->delegate(ResultExpr); - } - - return this->visitStmt(S); + return this->emitUnsupported(E); } return BS.destroyLocals(); @@ -3245,6 +3256,9 @@ bool Compiler::visitInitializer(const Expr *E) { if (E->containsErrors()) return this->emitError(E); + if (!this->checkLiteralType(E)) + return false; + OptionScope Scope(this, /*NewDiscardResult=*/false, /*NewInitializing=*/true); return this->Visit(E); @@ -3677,6 +3691,9 @@ VarCreationState Compiler::visitVarDecl(const VarDecl *VD, bool Topleve const Expr *Init = VD->getInit(); std::optional VarT = classify(VD->getType()); + if (Init && Init->isValueDependent()) + return false; + if (Context::shouldBeGloballyIndexed(VD)) { auto checkDecl = [&]() -> bool { bool NeedsOp = !Toplevel && VD->isLocalVarDecl() && VD->isStaticLocal(); @@ -4078,12 +4095,7 @@ template bool Compiler::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) { SourceLocScope SLS(this, E); - bool Old = InitStackActive; - InitStackActive = - !(E->getUsedContext()->getDeclKind() == Decl::CXXConstructor); - bool Result = this->delegate(E->getExpr()); - InitStackActive = Old; - return Result; + return this->delegate(E->getExpr()); } template @@ -4141,10 +4153,14 @@ bool Compiler::VisitCXXThisExpr(const CXXThisExpr *E) { // instance pointer of the current function frame, but e.g. to the declaration // currently being initialized. Here we emit the necessary instruction(s) for // this scenario. + if (!InitStackActive || !E->isImplicit()) + return this->emitThis(E); + if (InitStackActive && !InitStack.empty()) { unsigned StartIndex = 0; for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) { - if (InitStack[StartIndex].Kind != InitLink::K_Field) + if (InitStack[StartIndex].Kind != InitLink::K_Field && + InitStack[StartIndex].Kind != InitLink::K_Elem) break; } @@ -4357,6 +4373,7 @@ bool Compiler::visitWhileStmt(const WhileStmt *S) { if (!this->jump(CondLabel)) return false; + this->fallthrough(EndLabel); this->emitLabel(EndLabel); return true; @@ -4685,6 +4702,17 @@ bool Compiler::emitLambdaStaticInvokerBody(const CXXMethodDecl *MD) { return this->emitRetVoid(MD); } +template +bool Compiler::checkLiteralType(const Expr *E) { + if (Ctx.getLangOpts().CPlusPlus23) + return true; + + if (!E->isPRValue() || E->getType()->isLiteralType(Ctx.getASTContext())) + return true; + + return this->emitCheckLiteralType(E->getType().getTypePtr(), E); +} + template bool Compiler::visitFunc(const FunctionDecl *F) { // Classify the return type. @@ -5226,6 +5254,10 @@ bool Compiler::visitDeclRef(const ValueDecl *D, const Expr *E) { return false; }; + // DecompositionDecls are just proxies for us. + if (isa(VD)) + return revisit(VD); + // Visit local const variables like normal. if ((VD->hasGlobalStorage() || VD->isLocalVarDecl() || VD->isStaticDataMember()) && @@ -5274,8 +5306,8 @@ template unsigned Compiler::collectBaseOffset(const QualType BaseType, const QualType DerivedType) { const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * { - if (const auto *PT = dyn_cast(Ty)) - return PT->getPointeeType()->getAsCXXRecordDecl(); + if (const auto *R = Ty->getPointeeCXXRecordDecl()) + return R; return Ty->getAsCXXRecordDecl(); }; const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType); diff --git a/clang/lib/AST/Interp/Compiler.h b/clang/lib/AST/Interp/Compiler.h index 6df723df2b444..6bc9985fe7232 100644 --- a/clang/lib/AST/Interp/Compiler.h +++ b/clang/lib/AST/Interp/Compiler.h @@ -33,6 +33,7 @@ template class DestructorScope; template class VariableScope; template class DeclScope; template class InitLinkScope; +template class InitStackScope; template class OptionScope; template class ArrayIndexScope; template class SourceLocScope; @@ -49,6 +50,7 @@ struct InitLink { K_Field = 1, K_Temp = 2, K_Decl = 3, + K_Elem = 5, }; static InitLink This() { return InitLink{K_This}; } @@ -67,6 +69,11 @@ struct InitLink { IL.D = D; return IL; } + static InitLink Elem(unsigned Index) { + InitLink IL{K_Elem}; + IL.Offset = Index; + return IL; + } InitLink(uint8_t Kind) : Kind(Kind) {} template @@ -298,6 +305,7 @@ class Compiler : public ConstStmtVisitor, bool>, friend class DestructorScope; friend class DeclScope; friend class InitLinkScope; + friend class InitStackScope; friend class OptionScope; friend class ArrayIndexScope; friend class SourceLocScope; @@ -351,6 +359,8 @@ class Compiler : public ConstStmtVisitor, bool>, const QualType DerivedType); bool emitLambdaStaticInvokerBody(const CXXMethodDecl *MD); + bool checkLiteralType(const Expr *E); + protected: /// Variable to storage mapping. llvm::DenseMap Locals; @@ -612,6 +622,20 @@ template class InitLinkScope final { Compiler *Ctx; }; +template class InitStackScope final { +public: + InitStackScope(Compiler *Ctx, bool Active) + : Ctx(Ctx), OldValue(Ctx->InitStackActive) { + Ctx->InitStackActive = Active; + } + + ~InitStackScope() { this->Ctx->InitStackActive = OldValue; } + +private: + Compiler *Ctx; + bool OldValue; +}; + } // namespace interp } // namespace clang diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp index b5e992c5a9ac1..b1e06cd4d8a4c 100644 --- a/clang/lib/AST/Interp/Context.cpp +++ b/clang/lib/AST/Interp/Context.cpp @@ -176,8 +176,7 @@ std::optional Context::classify(QualType T) const { T->isFunctionType()) return PT_FnPtr; - if (T->isReferenceType() || T->isPointerType() || - T->isObjCObjectPointerType()) + if (T->isPointerOrReferenceType() || T->isObjCObjectPointerType()) return PT_Ptr; if (const auto *AT = T->getAs()) diff --git a/clang/lib/AST/Interp/Descriptor.cpp b/clang/lib/AST/Interp/Descriptor.cpp index f7d1201f625bb..671f2c03d7e5c 100644 --- a/clang/lib/AST/Interp/Descriptor.cpp +++ b/clang/lib/AST/Interp/Descriptor.cpp @@ -33,7 +33,8 @@ static void dtorTy(Block *, std::byte *Ptr, const Descriptor *) { template static void moveTy(Block *, const std::byte *Src, std::byte *Dst, const Descriptor *) { - const auto *SrcPtr = reinterpret_cast(Src); + // FIXME: Get rid of the const_cast. + auto *SrcPtr = reinterpret_cast(const_cast(Src)); auto *DstPtr = reinterpret_cast(Dst); new (DstPtr) T(std::move(*SrcPtr)); } @@ -162,7 +163,8 @@ static void initField(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, } static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, - bool IsActive, const Descriptor *D, unsigned FieldOffset) { + bool IsActive, const Descriptor *D, unsigned FieldOffset, + bool IsVirtualBase) { assert(D); assert(D->ElemRecord); @@ -172,13 +174,14 @@ static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, Desc->Desc = D; Desc->IsInitialized = D->IsArray; Desc->IsBase = true; + Desc->IsVirtualBase = IsVirtualBase; Desc->IsActive = IsActive && !IsUnion; Desc->IsConst = IsConst || D->IsConst; Desc->IsFieldMutable = IsMutable || D->IsMutable; for (const auto &V : D->ElemRecord->bases()) initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, V.Desc, - V.Offset); + V.Offset, false); for (const auto &F : D->ElemRecord->fields()) initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, IsUnion, F.Desc, F.Offset); @@ -187,11 +190,11 @@ static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, static void ctorRecord(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, bool IsActive, const Descriptor *D) { for (const auto &V : D->ElemRecord->bases()) - initBase(B, Ptr, IsConst, IsMutable, IsActive, V.Desc, V.Offset); + initBase(B, Ptr, IsConst, IsMutable, IsActive, V.Desc, V.Offset, false); for (const auto &F : D->ElemRecord->fields()) initField(B, Ptr, IsConst, IsMutable, IsActive, D->ElemRecord->isUnion(), F.Desc, F.Offset); for (const auto &V : D->ElemRecord->virtual_bases()) - initBase(B, Ptr, IsConst, IsMutable, IsActive, V.Desc, V.Offset); + initBase(B, Ptr, IsConst, IsMutable, IsActive, V.Desc, V.Offset, true); } static void destroyField(Block *B, std::byte *Ptr, const Descriptor *D, diff --git a/clang/lib/AST/Interp/Descriptor.h b/clang/lib/AST/Interp/Descriptor.h index 0dd97812e5a5c..0cc5d77c407e3 100644 --- a/clang/lib/AST/Interp/Descriptor.h +++ b/clang/lib/AST/Interp/Descriptor.h @@ -83,6 +83,8 @@ struct InlineDescriptor { /// Flag indicating if the field is an embedded base class. LLVM_PREFERRED_TYPE(bool) unsigned IsBase : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned IsVirtualBase : 1; /// Flag indicating if the field is the active member of a union. LLVM_PREFERRED_TYPE(bool) unsigned IsActive : 1; diff --git a/clang/lib/AST/Interp/Disasm.cpp b/clang/lib/AST/Interp/Disasm.cpp index c6c6275593007..5e3a5b9515b52 100644 --- a/clang/lib/AST/Interp/Disasm.cpp +++ b/clang/lib/AST/Interp/Disasm.cpp @@ -278,10 +278,15 @@ LLVM_DUMP_METHOD void InterpFrame::dump(llvm::raw_ostream &OS, OS << "\n"; OS.indent(Spaces) << "This: " << getThis() << "\n"; OS.indent(Spaces) << "RVO: " << getRVOPtr() << "\n"; - - while (const InterpFrame *F = this->Caller) { + OS.indent(Spaces) << "Depth: " << Depth << "\n"; + OS.indent(Spaces) << "ArgSize: " << ArgSize << "\n"; + OS.indent(Spaces) << "Args: " << (void *)Args << "\n"; + OS.indent(Spaces) << "FrameOffset: " << FrameOffset << "\n"; + OS.indent(Spaces) << "FrameSize: " << (Func ? Func->getFrameSize() : 0) + << "\n"; + + for (const InterpFrame *F = this->Caller; F; F = F->Caller) { F->dump(OS, Indent + 1); - F = F->Caller; } } @@ -366,9 +371,9 @@ LLVM_DUMP_METHOD void EvaluationResult::dump() const { OS << "LValue: "; if (const auto *P = std::get_if(&Value)) - P->toAPValue().printPretty(OS, ASTCtx, SourceType); + P->toAPValue(ASTCtx).printPretty(OS, ASTCtx, SourceType); else if (const auto *FP = std::get_if(&Value)) // Nope - FP->toAPValue().printPretty(OS, ASTCtx, SourceType); + FP->toAPValue(ASTCtx).printPretty(OS, ASTCtx, SourceType); OS << "\n"; break; } diff --git a/clang/lib/AST/Interp/EvalEmitter.cpp b/clang/lib/AST/Interp/EvalEmitter.cpp index 59e78686b78ad..08536536ac3c2 100644 --- a/clang/lib/AST/Interp/EvalEmitter.cpp +++ b/clang/lib/AST/Interp/EvalEmitter.cpp @@ -145,7 +145,7 @@ template bool EvalEmitter::emitRet(const SourceInfo &Info) { return false; using T = typename PrimConv::T; - EvalResult.setValue(S.Stk.pop().toAPValue()); + EvalResult.setValue(S.Stk.pop().toAPValue(Ctx.getASTContext())); return true; } @@ -169,7 +169,9 @@ template <> bool EvalEmitter::emitRet(const SourceInfo &Info) { return false; // Never allow reading from a non-const pointer, unless the memory // has been created in this evaluation. - if (!Ptr.isConst() && Ptr.block()->getEvalID() != Ctx.getEvalID()) + if (!Ptr.isZero() && Ptr.isBlockPointer() && + Ptr.block()->getEvalID() != Ctx.getEvalID() && + (!CheckLoad(S, OpPC, Ptr, AK_Read) || !Ptr.isConst())) return false; if (std::optional V = @@ -179,7 +181,7 @@ template <> bool EvalEmitter::emitRet(const SourceInfo &Info) { return false; } } else { - EvalResult.setValue(Ptr.toAPValue()); + EvalResult.setValue(Ptr.toAPValue(Ctx.getASTContext())); } return true; @@ -283,7 +285,8 @@ void EvalEmitter::updateGlobalTemporaries() { APValue *Cached = Temp->getOrCreateValue(true); if (std::optional T = Ctx.classify(E->getType())) { - TYPE_SWITCH(*T, { *Cached = Ptr.deref().toAPValue(); }); + TYPE_SWITCH( + *T, { *Cached = Ptr.deref().toAPValue(Ctx.getASTContext()); }); } else { if (std::optional APV = Ptr.toRValue(Ctx, Temp->getTemporaryExpr()->getType())) diff --git a/clang/lib/AST/Interp/EvaluationResult.cpp b/clang/lib/AST/Interp/EvaluationResult.cpp index 0bebfd4ad984e..bdebd19af9f94 100644 --- a/clang/lib/AST/Interp/EvaluationResult.cpp +++ b/clang/lib/AST/Interp/EvaluationResult.cpp @@ -10,7 +10,9 @@ #include "InterpState.h" #include "Record.h" #include "clang/AST/ExprCXX.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" +#include namespace clang { namespace interp { @@ -21,9 +23,9 @@ APValue EvaluationResult::toAPValue() const { case LValue: // Either a pointer or a function pointer. if (const auto *P = std::get_if(&Value)) - return P->toAPValue(); + return P->toAPValue(Ctx->getASTContext()); else if (const auto *FP = std::get_if(&Value)) - return FP->toAPValue(); + return FP->toAPValue(Ctx->getASTContext()); else llvm_unreachable("Unhandled LValue type"); break; @@ -46,7 +48,7 @@ std::optional EvaluationResult::toRValue() const { if (const auto *P = std::get_if(&Value)) return P->toRValue(*Ctx, getSourceType()); else if (const auto *FP = std::get_if(&Value)) // Nope - return FP->toAPValue(); + return FP->toAPValue(Ctx->getASTContext()); llvm_unreachable("Unhandled lvalue kind"); } @@ -122,19 +124,18 @@ static bool CheckFieldsInitialized(InterpState &S, SourceLocation Loc, } // Check Fields in all bases - for (const Record::Base &B : R->bases()) { + for (auto [I, B] : llvm::enumerate(R->bases())) { Pointer P = BasePtr.atField(B.Offset); if (!P.isInitialized()) { const Descriptor *Desc = BasePtr.getDeclDesc(); - if (Desc->asDecl()) - S.FFDiag(BasePtr.getDeclDesc()->asDecl()->getLocation(), - diag::note_constexpr_uninitialized_base) + if (const auto *CD = dyn_cast_if_present(R->getDecl())) { + const auto &BS = *std::next(CD->bases_begin(), I); + S.FFDiag(BS.getBaseTypeLoc(), diag::note_constexpr_uninitialized_base) + << B.Desc->getType() << BS.getSourceRange(); + } else { + S.FFDiag(Desc->getLocation(), diag::note_constexpr_uninitialized_base) << B.Desc->getType(); - else - S.FFDiag(BasePtr.getDeclDesc()->asExpr()->getExprLoc(), - diag::note_constexpr_uninitialized_base) - << B.Desc->getType(); - + } return false; } Result &= CheckFieldsInitialized(S, Loc, P, B.R); diff --git a/clang/lib/AST/Interp/Floating.h b/clang/lib/AST/Interp/Floating.h index e4ac76d8509fb..114487821880f 100644 --- a/clang/lib/AST/Interp/Floating.h +++ b/clang/lib/AST/Interp/Floating.h @@ -69,7 +69,7 @@ class Floating final { APSInt toAPSInt(unsigned NumBits = 0) const { return APSInt(F.bitcastToAPInt()); } - APValue toAPValue() const { return APValue(F); } + APValue toAPValue(const ASTContext &) const { return APValue(F); } void print(llvm::raw_ostream &OS) const { // Can't use APFloat::print() since it appends a newline. SmallVector Buffer; diff --git a/clang/lib/AST/Interp/FunctionPointer.h b/clang/lib/AST/Interp/FunctionPointer.h index fc3d7a4214a72..d92cd32933fcd 100644 --- a/clang/lib/AST/Interp/FunctionPointer.h +++ b/clang/lib/AST/Interp/FunctionPointer.h @@ -23,11 +23,10 @@ class FunctionPointer final { bool Valid; public: - FunctionPointer(const Function *Func) : Func(Func), Valid(true) { - assert(Func); - } + FunctionPointer() = default; + FunctionPointer(const Function *Func) : Func(Func), Valid(true) {} - FunctionPointer(uintptr_t IntVal = 0, const Descriptor *Desc = nullptr) + FunctionPointer(uintptr_t IntVal, const Descriptor *Desc = nullptr) : Func(reinterpret_cast(IntVal)), Valid(false) {} const Function *getFunction() const { return Func; } @@ -40,7 +39,7 @@ class FunctionPointer final { return Func->getDecl()->isWeak(); } - APValue toAPValue() const { + APValue toAPValue(const ASTContext &) const { if (!Func) return APValue(static_cast(nullptr), CharUnits::Zero(), {}, /*OnePastTheEnd=*/false, /*IsNull=*/true); @@ -69,7 +68,7 @@ class FunctionPointer final { if (!Func) return "nullptr"; - return toAPValue().getAsString(Ctx, Func->getDecl()->getType()); + return toAPValue(Ctx).getAsString(Ctx, Func->getDecl()->getType()); } uint64_t getIntegerRepresentation() const { diff --git a/clang/lib/AST/Interp/Integral.h b/clang/lib/AST/Interp/Integral.h index db4cc9ae45b49..aafdd02676c96 100644 --- a/clang/lib/AST/Interp/Integral.h +++ b/clang/lib/AST/Interp/Integral.h @@ -112,7 +112,7 @@ template class Integral final { else return APSInt(toAPSInt().zextOrTrunc(NumBits), !Signed); } - APValue toAPValue() const { return APValue(toAPSInt()); } + APValue toAPValue(const ASTContext &) const { return APValue(toAPSInt()); } Integral toUnsigned() const { return Integral(*this); diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index 7464f15cdb03b..b8aa21038256c 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -133,7 +133,7 @@ template class IntegralAP final { else return APSInt(V.zext(Bits), !Signed); } - APValue toAPValue() const { return APValue(toAPSInt()); } + APValue toAPValue(const ASTContext &) const { return APValue(toAPSInt()); } bool isZero() const { return V.isZero(); } bool isPositive() const { return V.isNonNegative(); } diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index fb63228f8aea8..3694253ae9782 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -22,6 +22,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "llvm/ADT/APSInt.h" +#include "llvm/ADT/StringExtras.h" #include #include @@ -232,7 +233,8 @@ void cleanupAfterFunctionCall(InterpState &S, CodePtr OpPC) { assert(false && "Can't get arguments from that expression type"); assert(NumArgs >= CurFunc->getNumWrittenParams()); - NumVarArgs = NumArgs - CurFunc->getNumWrittenParams(); + NumVarArgs = NumArgs - (CurFunc->getNumWrittenParams() + + isa(CallSite)); for (unsigned I = 0; I != NumVarArgs; ++I) { const Expr *A = Args[NumArgs - 1 - I]; popArg(S, A); @@ -332,7 +334,7 @@ bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc) { } static bool CheckConstant(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { - if (Ptr.isIntegralPointer()) + if (!Ptr.isBlockPointer()) return true; return CheckConstant(S, OpPC, Ptr.getDeclDesc()); } @@ -579,57 +581,62 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { return false; } - if (!F->isConstexpr() || !F->hasBody()) { - const SourceLocation &Loc = S.Current->getLocation(OpPC); - if (S.getLangOpts().CPlusPlus11) { - const FunctionDecl *DiagDecl = F->getDecl(); + if (F->isConstexpr() && F->hasBody() && + (F->getDecl()->isConstexpr() || F->getDecl()->hasAttr())) + return true; - // Invalid decls have been diagnosed before. - if (DiagDecl->isInvalidDecl()) - return false; + // Implicitly constexpr. + if (F->isLambdaStaticInvoker()) + return true; - // If this function is not constexpr because it is an inherited - // non-constexpr constructor, diagnose that directly. - const auto *CD = dyn_cast(DiagDecl); - if (CD && CD->isInheritingConstructor()) { - const auto *Inherited = CD->getInheritedConstructor().getConstructor(); - if (!Inherited->isConstexpr()) - DiagDecl = CD = Inherited; - } + const SourceLocation &Loc = S.Current->getLocation(OpPC); + if (S.getLangOpts().CPlusPlus11) { + const FunctionDecl *DiagDecl = F->getDecl(); - // FIXME: If DiagDecl is an implicitly-declared special member function - // or an inheriting constructor, we should be much more explicit about why - // it's not constexpr. - if (CD && CD->isInheritingConstructor()) { - S.FFDiag(Loc, diag::note_constexpr_invalid_inhctor, 1) + // Invalid decls have been diagnosed before. + if (DiagDecl->isInvalidDecl()) + return false; + + // If this function is not constexpr because it is an inherited + // non-constexpr constructor, diagnose that directly. + const auto *CD = dyn_cast(DiagDecl); + if (CD && CD->isInheritingConstructor()) { + const auto *Inherited = CD->getInheritedConstructor().getConstructor(); + if (!Inherited->isConstexpr()) + DiagDecl = CD = Inherited; + } + + // FIXME: If DiagDecl is an implicitly-declared special member function + // or an inheriting constructor, we should be much more explicit about why + // it's not constexpr. + if (CD && CD->isInheritingConstructor()) { + S.FFDiag(Loc, diag::note_constexpr_invalid_inhctor, 1) << CD->getInheritedConstructor().getConstructor()->getParent(); - S.Note(DiagDecl->getLocation(), diag::note_declared_at); - } else { - // Don't emit anything if the function isn't defined and we're checking - // for a constant expression. It might be defined at the point we're - // actually calling it. - bool IsExtern = DiagDecl->getStorageClass() == SC_Extern; - if (!DiagDecl->isDefined() && !IsExtern && - S.checkingPotentialConstantExpression()) - return false; + S.Note(DiagDecl->getLocation(), diag::note_declared_at); + } else { + // Don't emit anything if the function isn't defined and we're checking + // for a constant expression. It might be defined at the point we're + // actually calling it. + bool IsExtern = DiagDecl->getStorageClass() == SC_Extern; + if (!DiagDecl->isDefined() && !IsExtern && DiagDecl->isConstexpr() && + S.checkingPotentialConstantExpression()) + return false; - // If the declaration is defined, declared 'constexpr' _and_ has a body, - // the below diagnostic doesn't add anything useful. - if (DiagDecl->isDefined() && DiagDecl->isConstexpr() && - DiagDecl->hasBody()) - return false; + // If the declaration is defined, declared 'constexpr' _and_ has a body, + // the below diagnostic doesn't add anything useful. + if (DiagDecl->isDefined() && DiagDecl->isConstexpr() && + DiagDecl->hasBody()) + return false; - S.FFDiag(Loc, diag::note_constexpr_invalid_function, 1) + S.FFDiag(Loc, diag::note_constexpr_invalid_function, 1) << DiagDecl->isConstexpr() << (bool)CD << DiagDecl; - S.Note(DiagDecl->getLocation(), diag::note_declared_at); - } - } else { - S.FFDiag(Loc, diag::note_invalid_subexpr_in_const_expr); + S.Note(DiagDecl->getLocation(), diag::note_declared_at); } - return false; + } else { + S.FFDiag(Loc, diag::note_invalid_subexpr_in_const_expr); } - return true; + return false; } bool CheckCallDepth(InterpState &S, CodePtr OpPC) { @@ -722,8 +729,8 @@ bool CheckDynamicMemoryAllocation(InterpState &S, CodePtr OpPC) { return true; const SourceInfo &E = S.Current->getSource(OpPC); - S.FFDiag(E, diag::note_constexpr_new); - return false; + S.CCEDiag(E, diag::note_constexpr_new); + return true; } bool CheckNewDeleteForms(InterpState &S, CodePtr OpPC, bool NewWasArray, @@ -819,6 +826,106 @@ bool CheckNonNullArgs(InterpState &S, CodePtr OpPC, const Function *F, return true; } +// FIXME: This is similar to code we already have in Compiler.cpp. +// I think it makes sense to instead add the field and base destruction stuff +// to the destructor Function itself. Then destroying a record would really +// _just_ be calling its destructor. That would also help with the diagnostic +// difference when the destructor or a field/base fails. +static bool runRecordDestructor(InterpState &S, CodePtr OpPC, + const Pointer &BasePtr, + const Descriptor *Desc) { + assert(Desc->isRecord()); + const Record *R = Desc->ElemRecord; + assert(R); + + // Fields. + for (const Record::Field &Field : llvm::reverse(R->fields())) { + const Descriptor *D = Field.Desc; + if (D->isRecord()) { + if (!runRecordDestructor(S, OpPC, BasePtr.atField(Field.Offset), D)) + return false; + } else if (D->isCompositeArray()) { + const Descriptor *ElemDesc = Desc->ElemDesc; + assert(ElemDesc->isRecord()); + for (unsigned I = 0; I != Desc->getNumElems(); ++I) { + if (!runRecordDestructor(S, OpPC, BasePtr.atIndex(I).narrow(), + ElemDesc)) + return false; + } + } + } + + // Destructor of this record. + if (const CXXDestructorDecl *Dtor = R->getDestructor(); + Dtor && !Dtor->isTrivial()) { + const Function *DtorFunc = S.getContext().getOrCreateFunction(Dtor); + if (!DtorFunc) + return false; + + S.Stk.push(BasePtr); + if (!Call(S, OpPC, DtorFunc, 0)) + return false; + } + + // Bases. + for (const Record::Base &Base : llvm::reverse(R->bases())) { + if (!runRecordDestructor(S, OpPC, BasePtr.atField(Base.Offset), Base.Desc)) + return false; + } + + return true; +} + +bool RunDestructors(InterpState &S, CodePtr OpPC, const Block *B) { + assert(B); + const Descriptor *Desc = B->getDescriptor(); + + if (Desc->isPrimitive() || Desc->isPrimitiveArray()) + return true; + + assert(Desc->isRecord() || Desc->isCompositeArray()); + + if (Desc->isCompositeArray()) { + const Descriptor *ElemDesc = Desc->ElemDesc; + assert(ElemDesc->isRecord()); + + Pointer RP(const_cast(B)); + for (unsigned I = 0; I != Desc->getNumElems(); ++I) { + if (!runRecordDestructor(S, OpPC, RP.atIndex(I).narrow(), ElemDesc)) + return false; + } + return true; + } + + assert(Desc->isRecord()); + return runRecordDestructor(S, OpPC, Pointer(const_cast(B)), Desc); +} + +void diagnoseEnumValue(InterpState &S, CodePtr OpPC, const EnumDecl *ED, + const APSInt &Value) { + llvm::APInt Min; + llvm::APInt Max; + + if (S.EvaluatingDecl && !S.EvaluatingDecl->isConstexpr()) + return; + + ED->getValueRange(Max, Min); + --Max; + + if (ED->getNumNegativeBits() && + (Max.slt(Value.getSExtValue()) || Min.sgt(Value.getSExtValue()))) { + const SourceLocation &Loc = S.Current->getLocation(OpPC); + S.report(Loc, diag::warn_constexpr_unscoped_enum_out_of_range) + << llvm::toString(Value, 10) << Min.getSExtValue() << Max.getSExtValue() + << ED; + } else if (!ED->getNumNegativeBits() && Max.ult(Value.getZExtValue())) { + const SourceLocation &Loc = S.Current->getLocation(OpPC); + S.report(Loc, diag::warn_constexpr_unscoped_enum_out_of_range) + << llvm::toString(Value, 10) << Min.getZExtValue() << Max.getZExtValue() + << ED; + } +} + bool Interpret(InterpState &S, APValue &Result) { // The current stack frame when we started Interpret(). // This is being used by the ops to determine wheter diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index b4f8c03280c85..63e9966b831db 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -39,8 +39,9 @@ namespace interp { using APSInt = llvm::APSInt; /// Convert a value to an APValue. -template bool ReturnValue(const T &V, APValue &R) { - R = V.toAPValue(); +template +bool ReturnValue(const InterpState &S, const T &V, APValue &R) { + R = V.toAPValue(S.getCtx()); return true; } @@ -152,7 +153,8 @@ bool CheckShift(InterpState &S, CodePtr OpPC, const LT &LHS, const RT &RHS, if (RHS.isNegative()) { const SourceInfo &Loc = S.Current->getSource(OpPC); S.CCEDiag(Loc, diag::note_constexpr_negative_shift) << RHS.toAPSInt(); - return false; + if (!S.noteUndefinedBehavior()) + return false; } // C++11 [expr.shift]p1: Shift width must be less than the bit width of @@ -162,17 +164,24 @@ bool CheckShift(InterpState &S, CodePtr OpPC, const LT &LHS, const RT &RHS, const APSInt Val = RHS.toAPSInt(); QualType Ty = E->getType(); S.CCEDiag(E, diag::note_constexpr_large_shift) << Val << Ty << Bits; - return !(S.getEvalStatus().Diag && !S.getEvalStatus().Diag->empty() && S.getLangOpts().CPlusPlus11); + if (!S.noteUndefinedBehavior()) + return false; } if (LHS.isSigned() && !S.getLangOpts().CPlusPlus20) { const Expr *E = S.Current->getExpr(OpPC); // C++11 [expr.shift]p2: A signed left shift must have a non-negative // operand, and must not overflow the corresponding unsigned type. - if (LHS.isNegative()) + if (LHS.isNegative()) { S.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS.toAPSInt(); - else if (LHS.toUnsigned().countLeadingZeros() < static_cast(RHS)) + if (!S.noteUndefinedBehavior()) + return false; + } else if (LHS.toUnsigned().countLeadingZeros() < + static_cast(RHS)) { S.CCEDiag(E, diag::note_constexpr_lshift_discards); + if (!S.noteUndefinedBehavior()) + return false; + } } // C++2a [expr.shift]p2: [P0907R4]: @@ -186,10 +195,15 @@ template bool CheckDivRem(InterpState &S, CodePtr OpPC, const T &LHS, const T &RHS) { if (RHS.isZero()) { const auto *Op = cast(S.Current->getExpr(OpPC)); + if constexpr (std::is_same_v) { + S.CCEDiag(Op, diag::note_expr_divide_by_zero) + << Op->getRHS()->getSourceRange(); + return true; + } + S.FFDiag(Op, diag::note_expr_divide_by_zero) << Op->getRHS()->getSourceRange(); - if constexpr (!std::is_same_v) - return false; + return false; } if (LHS.isSigned() && LHS.isMin() && RHS.isNegative() && RHS.isMinusOne()) { @@ -286,7 +300,7 @@ bool Ret(InterpState &S, CodePtr &PC, APValue &Result) { } else { delete S.Current; S.Current = nullptr; - if (!ReturnValue(Ret, Result)) + if (!ReturnValue(S, Ret, Result)) return false; } return true; @@ -1318,7 +1332,7 @@ bool InitGlobalTemp(InterpState &S, CodePtr OpPC, uint32_t I, const Pointer &Ptr = S.P.getGlobal(I); const T Value = S.Stk.peek(); - APValue APV = Value.toAPValue(); + APValue APV = Value.toAPValue(S.getCtx()); APValue *Cached = Temp->getOrCreateValue(true); *Cached = APV; @@ -1557,7 +1571,10 @@ inline bool GetPtrBase(InterpState &S, CodePtr OpPC, uint32_t Off) { return false; if (!CheckSubobject(S, OpPC, Ptr, CSK_Base)) return false; - S.Stk.push(Ptr.atField(Off)); + const Pointer &Result = Ptr.atField(Off); + if (Result.isPastEnd()) + return false; + S.Stk.push(Result); return true; } @@ -1567,7 +1584,10 @@ inline bool GetPtrBasePop(InterpState &S, CodePtr OpPC, uint32_t Off) { return false; if (!CheckSubobject(S, OpPC, Ptr, CSK_Base)) return false; - S.Stk.push(Ptr.atField(Off)); + const Pointer &Result = Ptr.atField(Off); + if (Result.isPastEnd()) + return false; + S.Stk.push(Result); return true; } @@ -2263,8 +2283,7 @@ inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS) { // shift is not a constant expression. const SourceInfo &Loc = S.Current->getSource(OpPC); S.CCEDiag(Loc, diag::note_constexpr_negative_shift) << RHS.toAPSInt(); - if (S.getLangOpts().CPlusPlus11 && S.getEvalStatus().Diag && - !S.getEvalStatus().Diag->empty()) + if (!S.noteUndefinedBehavior()) return false; RHS = -RHS; return DoShift < LT, RT, @@ -2280,8 +2299,7 @@ inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS) { // 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.getLangOpts().CPlusPlus11 && S.getEvalStatus().Diag && - !S.getEvalStatus().Diag->empty()) + if (!S.noteUndefinedBehavior()) return false; } } @@ -2531,14 +2549,14 @@ inline bool Call(InterpState &S, CodePtr OpPC, const Function *Func, if (!CheckInvoke(S, OpPC, ThisPtr)) return false; } - - if (S.checkingPotentialConstantExpression()) - return false; } if (!CheckCallable(S, OpPC, Func)) return false; + if (Func->hasThisPointer() && S.checkingPotentialConstantExpression()) + return false; + if (!CheckCallDepth(S, OpPC)) return false; @@ -2570,12 +2588,20 @@ inline bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func, size_t ThisOffset = ArgSize - (Func->hasRVO() ? primSize(PT_Ptr) : 0); Pointer &ThisPtr = S.Stk.peek(ThisOffset); - QualType DynamicType = ThisPtr.getDeclDesc()->getType(); - const CXXRecordDecl *DynamicDecl; - if (DynamicType->isPointerType() || DynamicType->isReferenceType()) - DynamicDecl = DynamicType->getPointeeCXXRecordDecl(); - else - DynamicDecl = ThisPtr.getDeclDesc()->getType()->getAsCXXRecordDecl(); + const CXXRecordDecl *DynamicDecl = nullptr; + { + Pointer TypePtr = ThisPtr; + while (TypePtr.isBaseClass()) + TypePtr = TypePtr.getBase(); + + QualType DynamicType = TypePtr.getType(); + if (DynamicType->isPointerType() || DynamicType->isReferenceType()) + DynamicDecl = DynamicType->getPointeeCXXRecordDecl(); + else + DynamicDecl = DynamicType->getAsCXXRecordDecl(); + } + assert(DynamicDecl); + const auto *StaticDecl = cast(Func->getParentDecl()); const auto *InitialFunction = cast(Func->getDecl()); const CXXMethodDecl *Overrider = S.getContext().getOverridingFunction( @@ -2602,7 +2628,29 @@ inline bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func, } } - return Call(S, OpPC, Func, VarArgSize); + if (!Call(S, OpPC, Func, VarArgSize)) + return false; + + // Covariant return types. The return type of Overrider is a pointer + // or reference to a class type. + if (Overrider != InitialFunction && + Overrider->getReturnType()->isPointerOrReferenceType() && + InitialFunction->getReturnType()->isPointerOrReferenceType()) { + QualType OverriderPointeeType = + Overrider->getReturnType()->getPointeeType(); + QualType InitialPointeeType = + InitialFunction->getReturnType()->getPointeeType(); + // We've called Overrider above, but calling code expects us to return what + // InitialFunction returned. According to the rules for covariant return + // types, what InitialFunction returns needs to be a base class of what + // Overrider returns. So, we need to do an upcast here. + unsigned Offset = S.getContext().collectBaseOffset( + InitialPointeeType->getAsRecordDecl(), + OverriderPointeeType->getAsRecordDecl()); + return GetPtrBasePop(S, OpPC, Offset); + } + + return true; } inline bool CallBI(InterpState &S, CodePtr &PC, const Function *Func, @@ -2735,6 +2783,15 @@ inline bool InvalidDeclRef(InterpState &S, CodePtr OpPC, return CheckDeclRef(S, OpPC, DR); } +inline bool SizelessVectorElementSize(InterpState &S, CodePtr OpPC) { + if (S.inConstantContext()) { + const SourceRange &ArgRange = S.Current->getRange(OpPC); + const Expr *E = S.Current->getExpr(OpPC); + S.CCEDiag(E, diag::note_constexpr_non_const_vectorelements) << ArgRange; + } + return false; +} + inline bool Assume(InterpState &S, CodePtr OpPC) { const auto Val = S.Stk.pop(); @@ -2774,6 +2831,20 @@ inline bool CheckNonNullArg(InterpState &S, CodePtr OpPC) { return false; } +void diagnoseEnumValue(InterpState &S, CodePtr OpPC, const EnumDecl *ED, + const APSInt &Value); + +template ::T> +inline bool CheckEnumValue(InterpState &S, CodePtr OpPC, const EnumDecl *ED) { + assert(ED); + assert(!ED->isFixed()); + const APSInt Val = S.Stk.peek().toAPSInt(); + + if (S.inConstantContext()) + diagnoseEnumValue(S, OpPC, ED, Val); + return true; +} + /// OldPtr -> Integer -> NewPtr. template inline bool DecayPtr(InterpState &S, CodePtr OpPC) { @@ -2782,6 +2853,13 @@ inline bool DecayPtr(InterpState &S, CodePtr OpPC) { using ToT = typename PrimConv::T; const FromT &OldPtr = S.Stk.pop(); + + if constexpr (std::is_same_v && + std::is_same_v) { + S.Stk.push(OldPtr.getFunction()); + return true; + } + S.Stk.push(ToT(OldPtr.getIntegerRepresentation(), nullptr)); return true; } @@ -2872,8 +2950,8 @@ inline bool AllocCN(InterpState &S, CodePtr OpPC, const Descriptor *ElementDesc, return true; } +bool RunDestructors(InterpState &S, CodePtr OpPC, const Block *B); static inline bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm) { - if (!CheckDynamicMemoryAllocation(S, OpPC)) return false; @@ -2904,6 +2982,10 @@ static inline bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm) { assert(Source); assert(BlockToDelete); + // Invoke destructors before deallocating the memory. + if (!RunDestructors(S, OpPC, BlockToDelete)) + return false; + DynamicAllocator &Allocator = S.getAllocator(); bool WasArrayAlloc = Allocator.isArrayAllocation(Source); const Descriptor *BlockDesc = BlockToDelete->getDescriptor(); @@ -2918,6 +3000,39 @@ static inline bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm) { BlockDesc, Source); } +inline bool CheckLiteralType(InterpState &S, CodePtr OpPC, const Type *T) { + assert(T); + assert(!S.getLangOpts().CPlusPlus23); + + // C++1y: A constant initializer for an object o [...] may also invoke + // constexpr constructors for o and its subobjects even if those objects + // are of non-literal class types. + // + // C++11 missed this detail for aggregates, so classes like this: + // struct foo_t { union { int i; volatile int j; } u; }; + // are not (obviously) initializable like so: + // __attribute__((__require_constant_initialization__)) + // static const foo_t x = {{0}}; + // because "i" is a subobject with non-literal initialization (due to the + // volatile member of the union). See: + // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1677 + // Therefore, we use the C++1y behavior. + + if (S.EvaluatingDecl) + return true; + + if (S.Current->getFunction() && S.Current->getFunction()->isConstructor() && + S.Current->getThis().getDeclDesc()->asDecl() == S.EvaluatingDecl) + return true; + + const Expr *E = S.Current->getExpr(OpPC); + if (S.getLangOpts().CPlusPlus11) + S.FFDiag(E, diag::note_constexpr_nonliteral) << E->getType(); + else + S.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); + return false; +} + //===----------------------------------------------------------------------===// // Read opcode arguments //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index 98928b3c22d7c..d7538c76e91d9 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -7,6 +7,8 @@ //===----------------------------------------------------------------------===// #include "../ExprConstShared.h" #include "Boolean.h" +#include "Compiler.h" +#include "EvalEmitter.h" #include "Interp.h" #include "PrimType.h" #include "clang/AST/OSLog.h" @@ -942,15 +944,29 @@ static bool interp__builtin_atomic_lock_free(InterpState &S, CodePtr OpPC, if (Ptr.isZero()) return returnBool(true); - QualType PointeeType = Call->getArg(1) - ->IgnoreImpCasts() - ->getType() - ->castAs() - ->getPointeeType(); - // OK, we will inline operations on this object. - if (!PointeeType->isIncompleteType() && - S.getCtx().getTypeAlignInChars(PointeeType) >= Size) - return returnBool(true); + if (Ptr.isIntegralPointer()) { + uint64_t IntVal = Ptr.getIntegerRepresentation(); + if (APSInt(APInt(64, IntVal, false), true).isAligned(Size.getAsAlign())) + return returnBool(true); + } + + const Expr *PtrArg = Call->getArg(1); + // Otherwise, check if the type's alignment against Size. + if (const auto *ICE = dyn_cast(PtrArg)) { + // Drop the potential implicit-cast to 'const volatile void*', getting + // the underlying type. + if (ICE->getCastKind() == CK_BitCast) + PtrArg = ICE->getSubExpr(); + } + + if (auto PtrTy = PtrArg->getType()->getAs()) { + QualType PointeeType = PtrTy->getPointeeType(); + if (!PointeeType->isIncompleteType() && + S.getCtx().getTypeAlignInChars(PointeeType) >= Size) { + // OK, we will inline operations on this object. + return returnBool(true); + } + } } } @@ -1113,6 +1129,76 @@ static bool interp__builtin_ptrauth_string_discriminator( return true; } +// FIXME: This implementation is not complete. +// The Compiler instance we create cannot access the current stack frame, local +// variables, function parameters, etc. We also need protection from +// side-effects, fatal errors, etc. +static bool interp__builtin_constant_p(InterpState &S, CodePtr OpPC, + const InterpFrame *Frame, + const Function *Func, + const CallExpr *Call) { + const Expr *Arg = Call->getArg(0); + QualType ArgType = Arg->getType(); + + auto returnInt = [&S, Call](bool Value) -> bool { + pushInteger(S, Value, Call->getType()); + return true; + }; + + // __builtin_constant_p always has one operand. The rules which gcc follows + // are not precisely documented, but are as follows: + // + // - If the operand is of integral, floating, complex or enumeration type, + // and can be folded to a known value of that type, it returns 1. + // - If the operand can be folded to a pointer to the first character + // of a string literal (or such a pointer cast to an integral type) + // or to a null pointer or an integer cast to a pointer, it returns 1. + // + // Otherwise, it returns 0. + // + // FIXME: GCC also intends to return 1 for literals of aggregate types, but + // its support for this did not work prior to GCC 9 and is not yet well + // understood. + if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() || + ArgType->isAnyComplexType() || ArgType->isPointerType() || + ArgType->isNullPtrType()) { + InterpStack Stk; + Compiler C(S.Ctx, S.P, S, Stk); + auto Res = C.interpretExpr(Arg, /*ConvertResultToRValue=*/Arg->isGLValue()); + if (Res.isInvalid()) { + C.cleanup(); + Stk.clear(); + } + + if (!Res.isInvalid() && !Res.empty()) { + const APValue &LV = Res.toAPValue(); + if (LV.isLValue()) { + APValue::LValueBase Base = LV.getLValueBase(); + if (Base.isNull()) { + // A null base is acceptable. + return returnInt(true); + } else if (const auto *E = Base.dyn_cast()) { + if (!isa(E)) + return returnInt(false); + return returnInt(LV.getLValueOffset().isZero()); + } else if (Base.is()) { + // Surprisingly, GCC considers __builtin_constant_p(&typeid(int)) to + // evaluate to true. + return returnInt(true); + } else { + // Any other base is not constant enough for GCC. + return returnInt(false); + } + } + } + + // Otherwise, any constant value is good enough. + return returnInt(true); + } + + return returnInt(false); +} + bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, const CallExpr *Call) { const InterpFrame *Frame = S.Current; @@ -1442,6 +1528,11 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, return false; break; + case Builtin::BI__builtin_constant_p: + if (!interp__builtin_constant_p(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/Interp/MemberPointer.cpp b/clang/lib/AST/Interp/MemberPointer.cpp index 96f63643e83c9..0c1b6edc5f7e1 100644 --- a/clang/lib/AST/Interp/MemberPointer.cpp +++ b/clang/lib/AST/Interp/MemberPointer.cpp @@ -60,13 +60,13 @@ FunctionPointer MemberPointer::toFunctionPointer(const Context &Ctx) const { return FunctionPointer(Ctx.getProgram().getFunction(cast(Dcl))); } -APValue MemberPointer::toAPValue() const { +APValue MemberPointer::toAPValue(const ASTContext &ASTCtx) const { if (isZero()) return APValue(static_cast(nullptr), /*IsDerivedMember=*/false, /*Path=*/{}); if (hasBase()) - return Base.toAPValue(); + return Base.toAPValue(ASTCtx); return APValue(cast(getDecl()), /*IsDerivedMember=*/false, /*Path=*/{}); diff --git a/clang/lib/AST/Interp/MemberPointer.h b/clang/lib/AST/Interp/MemberPointer.h index f56dc530431e4..2b3be124db426 100644 --- a/clang/lib/AST/Interp/MemberPointer.h +++ b/clang/lib/AST/Interp/MemberPointer.h @@ -80,7 +80,7 @@ class MemberPointer final { return MemberPointer(Instance, this->Dcl, this->PtrOffset); } - APValue toAPValue() const; + APValue toAPValue(const ASTContext &) const; bool isZero() const { return Base.isZero() && !Dcl; } bool hasBase() const { return !Base.isZero(); } diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index 3e69098570bd7..eeb9cb2e933a6 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -66,6 +66,8 @@ def ArgDecl : ArgType { let Name = "const Decl*"; } def ArgVarDecl : ArgType { let Name = "const VarDecl*"; } def ArgDesc : ArgType { let Name = "const Descriptor *"; } def ArgPrimType : ArgType { let Name = "PrimType"; } +def ArgEnumDecl : ArgType { let Name = "const EnumDecl *"; } +def ArgTypePtr : ArgType { let Name = "const Type *"; } //===----------------------------------------------------------------------===// // Classes of types instructions operate on. @@ -389,6 +391,16 @@ def CheckDecl : Opcode { let Args = [ArgVarDecl]; } +def CheckEnumValue : Opcode { + let Args = [ArgEnumDecl]; + let Types = [FixedSizeIntegralTypeClass]; + let HasGroup = 1; +} + +def CheckLiteralType : Opcode { + let Args = [ArgTypePtr]; +} + // [] -> [Value] def GetGlobal : AccessOpcode; def GetGlobalUnchecked : AccessOpcode; @@ -726,6 +738,8 @@ def InvalidDeclRef : Opcode { let Args = [ArgDeclRef]; } +def SizelessVectorElementSize : Opcode; + def Assume : Opcode; def ArrayDecay : Opcode; diff --git a/clang/lib/AST/Interp/Pointer.cpp b/clang/lib/AST/Interp/Pointer.cpp index ff4da0fa805dc..3ac8bc2b09709 100644 --- a/clang/lib/AST/Interp/Pointer.cpp +++ b/clang/lib/AST/Interp/Pointer.cpp @@ -16,6 +16,7 @@ #include "MemberPointer.h" #include "PrimType.h" #include "Record.h" +#include "clang/AST/RecordLayout.h" using namespace clang; using namespace clang::interp; @@ -54,7 +55,7 @@ Pointer::Pointer(Pointer &&P) } Pointer::~Pointer() { - if (isIntegralPointer()) + if (!isBlockPointer()) return; if (Block *Pointee = PointeeStorage.BS.Pointee) { @@ -86,6 +87,8 @@ void Pointer::operator=(const Pointer &P) { PointeeStorage.BS.Pointee->addPointer(this); } else if (P.isIntegralPointer()) { PointeeStorage.Int = P.PointeeStorage.Int; + } else if (P.isFunctionPointer()) { + PointeeStorage.Fn = P.PointeeStorage.Fn; } else { assert(false && "Unhandled storage kind"); } @@ -114,12 +117,14 @@ void Pointer::operator=(Pointer &&P) { PointeeStorage.BS.Pointee->addPointer(this); } else if (P.isIntegralPointer()) { PointeeStorage.Int = P.PointeeStorage.Int; + } else if (P.isFunctionPointer()) { + PointeeStorage.Fn = P.PointeeStorage.Fn; } else { assert(false && "Unhandled storage kind"); } } -APValue Pointer::toAPValue() const { +APValue Pointer::toAPValue(const ASTContext &ASTCtx) const { llvm::SmallVector Path; if (isZero()) @@ -130,6 +135,8 @@ APValue Pointer::toAPValue() const { CharUnits::fromQuantity(asIntPointer().Value + this->Offset), Path, /*IsOnePastEnd=*/false, /*IsNullPtr=*/false); + if (isFunctionPointer()) + return asFunctionPointer().toAPValue(ASTCtx); // Build the lvalue base from the block. const Descriptor *Desc = getDeclDesc(); @@ -141,41 +148,79 @@ APValue Pointer::toAPValue() const { else llvm_unreachable("Invalid allocation type"); - if (isDummy() || isUnknownSizeArray() || Desc->asExpr()) + if (isUnknownSizeArray() || Desc->asExpr()) return APValue(Base, CharUnits::Zero(), Path, /*IsOnePastEnd=*/isOnePastEnd(), /*IsNullPtr=*/false); - // TODO: compute the offset into the object. CharUnits Offset = CharUnits::Zero(); + auto getFieldOffset = [&](const FieldDecl *FD) -> CharUnits { + // This shouldn't happen, but if it does, don't crash inside + // getASTRecordLayout. + if (FD->getParent()->isInvalidDecl()) + return CharUnits::Zero(); + const ASTRecordLayout &Layout = ASTCtx.getASTRecordLayout(FD->getParent()); + unsigned FieldIndex = FD->getFieldIndex(); + return ASTCtx.toCharUnitsFromBits(Layout.getFieldOffset(FieldIndex)); + }; + // Build the path into the object. Pointer Ptr = *this; while (Ptr.isField() || Ptr.isArrayElement()) { if (Ptr.isArrayRoot()) { Path.push_back(APValue::LValuePathEntry( {Ptr.getFieldDesc()->asDecl(), /*IsVirtual=*/false})); + + if (const auto *FD = dyn_cast(Ptr.getFieldDesc()->asDecl())) + Offset += getFieldOffset(FD); + Ptr = Ptr.getBase(); } else if (Ptr.isArrayElement()) { + unsigned Index; if (Ptr.isOnePastEnd()) - Path.push_back(APValue::LValuePathEntry::ArrayIndex(Ptr.getArray().getNumElems())); + Index = Ptr.getArray().getNumElems(); else - Path.push_back(APValue::LValuePathEntry::ArrayIndex(Ptr.getIndex())); + Index = Ptr.getIndex(); + + Offset += (Index * ASTCtx.getTypeSizeInChars(Ptr.getType())); + Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index)); Ptr = Ptr.getArray(); } else { - // TODO: figure out if base is virtual bool IsVirtual = false; // Create a path entry for the field. const Descriptor *Desc = Ptr.getFieldDesc(); if (const auto *BaseOrMember = Desc->asDecl()) { + if (const auto *FD = dyn_cast(BaseOrMember)) { + Ptr = Ptr.getBase(); + Offset += getFieldOffset(FD); + } else if (const auto *RD = dyn_cast(BaseOrMember)) { + IsVirtual = Ptr.isVirtualBaseClass(); + Ptr = Ptr.getBase(); + const Record *BaseRecord = Ptr.getRecord(); + + const ASTRecordLayout &Layout = ASTCtx.getASTRecordLayout( + cast(BaseRecord->getDecl())); + if (IsVirtual) + Offset += Layout.getVBaseClassOffset(RD); + else + Offset += Layout.getBaseClassOffset(RD); + + } else { + Ptr = Ptr.getBase(); + } Path.push_back(APValue::LValuePathEntry({BaseOrMember, IsVirtual})); - Ptr = Ptr.getBase(); continue; } llvm_unreachable("Invalid field type"); } } + // FIXME(perf): We compute the lvalue path above, but we can't supply it + // for dummy pointers (that causes crashes later in CheckConstantExpression). + if (isDummy()) + Path.clear(); + // We assemble the LValuePath starting from the innermost pointer to the // outermost one. SO in a.b.c, the first element in Path will refer to // the field 'c', while later code expects it to refer to 'a'. @@ -220,13 +265,19 @@ std::string Pointer::toDiagnosticString(const ASTContext &Ctx) const { if (isIntegralPointer()) return (Twine("&(") + Twine(asIntPointer().Value + Offset) + ")").str(); - return toAPValue().getAsString(Ctx, getType()); + return toAPValue(Ctx).getAsString(Ctx, getType()); } bool Pointer::isInitialized() const { - if (isIntegralPointer()) + if (!isBlockPointer()) return true; + if (isRoot() && PointeeStorage.BS.Base == sizeof(GlobalInlineDescriptor)) { + const GlobalInlineDescriptor &GD = + *reinterpret_cast(block()->rawData()); + return GD.InitState == GlobalInitState::Initialized; + } + assert(PointeeStorage.BS.Pointee && "Cannot check if null pointer was initialized"); const Descriptor *Desc = getFieldDesc(); @@ -249,23 +300,24 @@ bool Pointer::isInitialized() const { if (asBlockPointer().Base == 0) return true; - if (isRoot() && PointeeStorage.BS.Base == sizeof(GlobalInlineDescriptor)) { - const GlobalInlineDescriptor &GD = - *reinterpret_cast(block()->rawData()); - return GD.InitState == GlobalInitState::Initialized; - } - // Field has its bit in an inline descriptor. return getInlineDesc()->IsInitialized; } void Pointer::initialize() const { - if (isIntegralPointer()) + if (!isBlockPointer()) return; assert(PointeeStorage.BS.Pointee && "Cannot initialize null pointer"); const Descriptor *Desc = getFieldDesc(); + if (isRoot() && PointeeStorage.BS.Base == sizeof(GlobalInlineDescriptor)) { + GlobalInlineDescriptor &GD = *reinterpret_cast( + asBlockPointer().Pointee->rawData()); + GD.InitState = GlobalInitState::Initialized; + return; + } + assert(Desc); if (Desc->isPrimitiveArray()) { // Primitive global arrays don't have an initmap. @@ -294,13 +346,6 @@ void Pointer::initialize() const { return; } - if (isRoot() && PointeeStorage.BS.Base == sizeof(GlobalInlineDescriptor)) { - GlobalInlineDescriptor &GD = *reinterpret_cast( - asBlockPointer().Pointee->rawData()); - GD.InitState = GlobalInitState::Initialized; - return; - } - // Field has its bit in an inline descriptor. assert(PointeeStorage.BS.Base != 0 && "Only composite fields can be initialised"); @@ -329,10 +374,15 @@ bool Pointer::hasSameBase(const Pointer &A, const Pointer &B) { if (A.isIntegralPointer() && B.isIntegralPointer()) return true; + if (A.isFunctionPointer() && B.isFunctionPointer()) + return true; if (A.isIntegralPointer() || B.isIntegralPointer()) return A.getSource() == B.getSource(); + if (A.StorageKind != B.StorageKind) + return false; + return A.asBlockPointer().Pointee == B.asBlockPointer().Pointee; } @@ -344,10 +394,12 @@ bool Pointer::hasSameArray(const Pointer &A, const Pointer &B) { std::optional Pointer::toRValue(const Context &Ctx, QualType ResultType) const { + const ASTContext &ASTCtx = Ctx.getASTContext(); assert(!ResultType.isNull()); // Method to recursively traverse composites. std::function Composite; - Composite = [&Composite, &Ctx](QualType Ty, const Pointer &Ptr, APValue &R) { + Composite = [&Composite, &Ctx, &ASTCtx](QualType Ty, const Pointer &Ptr, + APValue &R) { if (const auto *AT = Ty->getAs()) Ty = AT->getValueType(); @@ -358,7 +410,7 @@ std::optional Pointer::toRValue(const Context &Ctx, // Primitive values. if (std::optional T = Ctx.classify(Ty)) { - TYPE_SWITCH(*T, R = Ptr.deref().toAPValue()); + TYPE_SWITCH(*T, R = Ptr.deref().toAPValue(ASTCtx)); return true; } @@ -375,7 +427,7 @@ std::optional Pointer::toRValue(const Context &Ctx, QualType FieldTy = F.Decl->getType(); if (FP.isActive()) { if (std::optional T = Ctx.classify(FieldTy)) { - TYPE_SWITCH(*T, Value = FP.deref().toAPValue()); + TYPE_SWITCH(*T, Value = FP.deref().toAPValue(ASTCtx)); } else { Ok &= Composite(FieldTy, FP, Value); } @@ -398,7 +450,7 @@ std::optional Pointer::toRValue(const Context &Ctx, APValue &Value = R.getStructField(I); if (std::optional T = Ctx.classify(FieldTy)) { - TYPE_SWITCH(*T, Value = FP.deref().toAPValue()); + TYPE_SWITCH(*T, Value = FP.deref().toAPValue(ASTCtx)); } else { Ok &= Composite(FieldTy, FP, Value); } @@ -436,7 +488,7 @@ std::optional Pointer::toRValue(const Context &Ctx, APValue &Slot = R.getArrayInitializedElt(I); const Pointer &EP = Ptr.atIndex(I); if (std::optional T = Ctx.classify(ElemTy)) { - TYPE_SWITCH(*T, Slot = EP.deref().toAPValue()); + TYPE_SWITCH(*T, Slot = EP.deref().toAPValue(ASTCtx)); } else { Ok &= Composite(ElemTy, EP.narrow(), Slot); } @@ -475,7 +527,7 @@ std::optional Pointer::toRValue(const Context &Ctx, Values.reserve(VT->getNumElements()); for (unsigned I = 0; I != VT->getNumElements(); ++I) { TYPE_SWITCH(ElemT, { - Values.push_back(Ptr.atIndex(I).deref().toAPValue()); + Values.push_back(Ptr.atIndex(I).deref().toAPValue(ASTCtx)); }); } @@ -493,11 +545,11 @@ std::optional Pointer::toRValue(const Context &Ctx, // We can return these as rvalues, but we can't deref() them. if (isZero() || isIntegralPointer()) - return toAPValue(); + return toAPValue(ASTCtx); // Just load primitive types. if (std::optional T = Ctx.classify(ResultType)) { - TYPE_SWITCH(*T, return this->deref().toAPValue()); + TYPE_SWITCH(*T, return this->deref().toAPValue(ASTCtx)); } // Return the composite type. diff --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h index 972f55a553f6e..6b0c31358159c 100644 --- a/clang/lib/AST/Interp/Pointer.h +++ b/clang/lib/AST/Interp/Pointer.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_AST_INTERP_POINTER_H #include "Descriptor.h" +#include "FunctionPointer.h" #include "InterpBlock.h" #include "clang/AST/ComparisonCategories.h" #include "clang/AST/Decl.h" @@ -45,7 +46,7 @@ struct IntPointer { uint64_t Value; }; -enum class Storage { Block, Int }; +enum class Storage { Block, Int, Fn }; /// A pointer to a memory block, live or dead. /// @@ -96,6 +97,10 @@ class Pointer { PointeeStorage.Int.Value = Address; PointeeStorage.Int.Desc = Desc; } + Pointer(const Function *F, uint64_t Offset = 0) + : Offset(Offset), StorageKind(Storage::Fn) { + PointeeStorage.Fn = FunctionPointer(F); + } ~Pointer(); void operator=(const Pointer &P); @@ -118,7 +123,7 @@ class Pointer { bool operator!=(const Pointer &P) const { return !(P == *this); } /// Converts the pointer to an APValue. - APValue toAPValue() const; + APValue toAPValue(const ASTContext &ASTCtx) const; /// Converts the pointer to a string usable in diagnostics. std::string toDiagnosticString(const ASTContext &Ctx) const; @@ -126,6 +131,8 @@ class Pointer { uint64_t getIntegerRepresentation() const { if (isIntegralPointer()) return asIntPointer().Value + (Offset * elemSize()); + if (isFunctionPointer()) + return asFunctionPointer().getIntegerRepresentation(); return reinterpret_cast(asBlockPointer().Pointee) + Offset; } @@ -137,6 +144,8 @@ class Pointer { [[nodiscard]] Pointer atIndex(uint64_t Idx) const { if (isIntegralPointer()) return Pointer(asIntPointer().Value, asIntPointer().Desc, Idx); + if (isFunctionPointer()) + return Pointer(asFunctionPointer().getFunction(), Idx); if (asBlockPointer().Base == RootPtrMark) return Pointer(asBlockPointer().Pointee, RootPtrMark, @@ -247,18 +256,20 @@ class Pointer { bool isZero() const { if (isBlockPointer()) return asBlockPointer().Pointee == nullptr; + if (isFunctionPointer()) + return asFunctionPointer().isZero(); assert(isIntegralPointer()); return asIntPointer().Value == 0 && Offset == 0; } /// Checks if the pointer is live. bool isLive() const { - if (isIntegralPointer()) + if (!isBlockPointer()) return true; return asBlockPointer().Pointee && !asBlockPointer().Pointee->IsDead; } /// Checks if the item is a field in an object. bool isField() const { - if (isIntegralPointer()) + if (!isBlockPointer()) return false; return !isRoot() && getFieldDesc()->asDecl(); @@ -268,6 +279,8 @@ class Pointer { const Descriptor *getDeclDesc() const { if (isIntegralPointer()) return asIntPointer().Desc; + if (isFunctionPointer()) + return nullptr; assert(isBlockPointer()); assert(asBlockPointer().Pointee); @@ -279,7 +292,10 @@ class Pointer { DeclTy getSource() const { if (isBlockPointer()) return getDeclDesc()->getSource(); - + if (isFunctionPointer()) { + const Function *F = asFunctionPointer().getFunction(); + return F ? F->getDecl() : DeclTy(); + } assert(isIntegralPointer()); return asIntPointer().Desc ? asIntPointer().Desc->getSource() : DeclTy(); } @@ -354,6 +370,7 @@ class Pointer { /// Returns the offset into an array. unsigned getOffset() const { assert(Offset != PastEndMark && "invalid offset"); + assert(isBlockPointer()); if (asBlockPointer().Base == RootPtrMark) return Offset; @@ -421,8 +438,14 @@ class Pointer { assert(isIntegralPointer()); return PointeeStorage.Int; } + [[nodiscard]] const FunctionPointer &asFunctionPointer() const { + assert(isFunctionPointer()); + return PointeeStorage.Fn; + } + bool isBlockPointer() const { return StorageKind == Storage::Block; } bool isIntegralPointer() const { return StorageKind == Storage::Int; } + bool isFunctionPointer() const { return StorageKind == Storage::Fn; } /// Returns the record descriptor of a class. const Record *getRecord() const { return getFieldDesc()->ElemRecord; } @@ -445,7 +468,7 @@ class Pointer { } /// Checks if the storage is static. bool isStatic() const { - if (isIntegralPointer()) + if (!isBlockPointer()) return true; assert(asBlockPointer().Pointee); return asBlockPointer().Pointee->isStatic(); @@ -469,7 +492,7 @@ class Pointer { } bool isWeak() const { - if (isIntegralPointer()) + if (!isBlockPointer()) return false; assert(isBlockPointer()); @@ -487,6 +510,9 @@ class Pointer { } /// Checks if a structure is a base class. bool isBaseClass() const { return isField() && getInlineDesc()->IsBase; } + bool isVirtualBaseClass() const { + return isField() && getInlineDesc()->IsVirtualBase; + } /// Checks if the pointer points to a dummy value. bool isDummy() const { if (!isBlockPointer()) @@ -525,8 +551,8 @@ class Pointer { /// Returns the number of elements. unsigned getNumElems() const { - if (isIntegralPointer()) - return ~unsigned(0); + if (!isBlockPointer()) + return ~0u; return getSize() / elemSize(); } @@ -552,7 +578,7 @@ class Pointer { /// Checks if the index is one past end. bool isOnePastEnd() const { - if (isIntegralPointer()) + if (isIntegralPointer() || isFunctionPointer()) return false; if (!asBlockPointer().Pointee) @@ -689,6 +715,7 @@ class Pointer { union { BlockPointer BS; IntPointer Int; + FunctionPointer Fn; } PointeeStorage; Storage StorageKind = Storage::Int; }; diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index a9204fa9a887f..eee446df846f5 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -5191,6 +5191,14 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity, Diags.Report(DiagID); return; } + case UETT_PtrAuthTypeDiscriminator: { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID( + DiagnosticsEngine::Error, + "cannot yet mangle __builtin_ptrauth_type_discriminator expression"); + Diags.Report(E->getExprLoc(), DiagID); + return; + } case UETT_VecStep: { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, @@ -6497,7 +6505,7 @@ void CXXNameMangler::mangleValueInTemplateArg(QualType T, const APValue &V, case APValue::LValue: { // Proposed in https://github.com/itanium-cxx-abi/cxx-abi/issues/47. - assert((T->isPointerType() || T->isReferenceType()) && + assert((T->isPointerOrReferenceType()) && "unexpected type for LValue template arg"); if (V.isNullPointer()) { diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 661b21ace5f36..c67b0fd617a38 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -337,6 +337,10 @@ class MicrosoftCXXNameMangler { const bool PointersAre64Bit; + DiagnosticBuilder Error(SourceLocation, StringRef, StringRef); + DiagnosticBuilder Error(SourceLocation, StringRef); + DiagnosticBuilder Error(StringRef); + public: enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result }; enum class TplArgKind { ClassNTTP, StructuralValue }; @@ -564,6 +568,31 @@ MicrosoftMangleContextImpl::shouldMangleStringLiteral(const StringLiteral *SL) { return true; } +DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc, + StringRef thing1, + StringRef thing2) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this %0 %1 yet"); + return Diags.Report(loc, DiagID) << thing1 << thing2; +} + +DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc, + StringRef thingy) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this %0 yet"); + return Diags.Report(loc, DiagID) << thingy; +} + +DiagnosticBuilder MicrosoftCXXNameMangler::Error(StringRef thingy) { + DiagnosticsEngine &Diags = Context.getDiags(); + // extra placeholders are ignored quietly when not used + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this %0 yet"); + return Diags.Report(DiagID) << thingy; +} + void MicrosoftCXXNameMangler::mangle(GlobalDecl GD, StringRef Prefix) { const NamedDecl *D = cast(GD.getDecl()); // MSVC doesn't mangle C++ names the same way it mangles extern "C" names. @@ -986,6 +1015,7 @@ void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) { case APFloat::S_Float8E5M2FNUZ: case APFloat::S_Float8E4M3FNUZ: case APFloat::S_Float8E4M3B11FNUZ: + case APFloat::S_Float8E3M4: case APFloat::S_FloatTF32: case APFloat::S_Float6E3M2FN: case APFloat::S_Float6E2M3FN: @@ -1578,10 +1608,7 @@ void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, case OO_Spaceship: Out << "?__M"; break; case OO_Conditional: { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this conditional operator yet"); - Diags.Report(Loc, DiagID); + Error(Loc, "conditional operator"); break; } @@ -1673,11 +1700,8 @@ void MicrosoftCXXNameMangler::mangleExpression( } // As bad as this diagnostic is, it's better than crashing. - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID( - DiagnosticsEngine::Error, "cannot yet mangle expression type %0"); - Diags.Report(E->getExprLoc(), DiagID) << E->getStmtClassName() - << E->getSourceRange(); + Error(E->getExprLoc(), "expression type: ", E->getStmtClassName()) + << E->getSourceRange(); } void MicrosoftCXXNameMangler::mangleTemplateArgs( @@ -1923,11 +1947,19 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T, if (WithScalarType) mangleType(T, SourceRange(), QMM_Escape); - // We don't know how to mangle past-the-end pointers yet. - if (V.isLValueOnePastTheEnd()) - break; - APValue::LValueBase Base = V.getLValueBase(); + + // this might not cover every case but did cover issue 97756 + // see test CodeGen/ms_mangler_templatearg_opte + if (V.isLValueOnePastTheEnd()) { + Out << "5E"; + auto *VD = Base.dyn_cast(); + if (VD) + mangle(VD); + Out << "@"; + return; + } + if (!V.hasLValuePath() || V.getLValuePath().empty()) { // Taking the address of a complete object has a special-case mangling. if (Base.isNull()) { @@ -1939,12 +1971,14 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T, mangleNumber(V.getLValueOffset().getQuantity()); } else if (!V.hasLValuePath()) { // FIXME: This can only happen as an extension. Invent a mangling. - break; + Error("template argument (extension not comaptible with ms mangler)"); + return; } else if (auto *VD = Base.dyn_cast()) { Out << "E"; mangle(VD); } else { - break; + Error("template argument (undeclared base)"); + return; } } else { if (TAK == TplArgKind::ClassNTTP && T->isPointerType()) @@ -1989,8 +2023,10 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T, Out << *I; auto *VD = Base.dyn_cast(); - if (!VD) - break; + if (!VD) { + Error("template argument (null value decl)"); + return; + } Out << (TAK == TplArgKind::ClassNTTP ? 'E' : '1'); mangle(VD); @@ -2105,15 +2141,16 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T, return; } - case APValue::AddrLabelDiff: - case APValue::FixedPoint: - break; + case APValue::AddrLabelDiff: { + Error("template argument (value type: address label diff)"); + return; } - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID( - DiagnosticsEngine::Error, "cannot mangle this template argument yet"); - Diags.Report(DiagID); + case APValue::FixedPoint: { + Error("template argument (value type: fixed point)"); + return; + } + } } void MicrosoftCXXNameMangler::mangleObjCProtocol(const ObjCProtocolDecl *PD) { @@ -2762,11 +2799,9 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers, case BuiltinType::SatULongFract: case BuiltinType::Ibm128: case BuiltinType::Float128: { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID( - DiagnosticsEngine::Error, "cannot mangle this built-in %0 type yet"); - Diags.Report(Range.getBegin(), DiagID) - << T->getName(Context.getASTContext().getPrintingPolicy()) << Range; + Error(Range.getBegin(), "built-in type: ", + T->getName(Context.getASTContext().getPrintingPolicy())) + << Range; break; } } @@ -3095,10 +3130,7 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC, return; } - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID( - DiagnosticsEngine::Error, "cannot mangle this calling convention yet"); - Diags.Report(Range.getBegin(), DiagID) << Range; + Error(Range.getBegin(), "calling convention") << Range; } void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T, SourceRange Range) { @@ -3119,11 +3151,7 @@ void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T, Qualifiers, SourceRange Range) { // Probably should be mangled as a template instantiation; need to see what // VC does first. - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this unresolved dependent type yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + Error(Range.getBegin(), "unresolved dependent type") << Range; } // ::= | | | @@ -3230,11 +3258,8 @@ void MicrosoftCXXNameMangler::mangleArrayType(const ArrayType *T) { // The dependent expression has to be folded into a constant (TODO). const DependentSizedArrayType *DSAT = getASTContext().getAsDependentSizedArrayType(ElementTy); - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this dependent-length array yet"); - Diags.Report(DSAT->getSizeExpr()->getExprLoc(), DiagID) - << DSAT->getBracketsRange(); + Error(DSAT->getSizeExpr()->getExprLoc(), "dependent-length") + << DSAT->getBracketsRange(); return; } else { break; @@ -3274,20 +3299,12 @@ void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T, void MicrosoftCXXNameMangler::mangleType(const TemplateTypeParmType *T, Qualifiers, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this template type parameter type yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + Error(Range.getBegin(), "template type parameter type") << Range; } void MicrosoftCXXNameMangler::mangleType(const SubstTemplateTypeParmPackType *T, Qualifiers, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this substituted parameter pack yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + Error(Range.getBegin(), "substituted parameter pack") << Range; } // ::= @@ -3438,46 +3455,27 @@ void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T, void MicrosoftCXXNameMangler::mangleType(const DependentVectorType *T, Qualifiers, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID( - DiagnosticsEngine::Error, - "cannot mangle this dependent-sized vector type yet"); - Diags.Report(Range.getBegin(), DiagID) << Range; + Error(Range.getBegin(), "dependent-sized vector type") << Range; } void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T, Qualifiers, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this dependent-sized extended vector type yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + Error(Range.getBegin(), "dependent-sized extended vector type") << Range; } void MicrosoftCXXNameMangler::mangleType(const ConstantMatrixType *T, Qualifiers quals, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "Cannot mangle this matrix type yet"); - Diags.Report(Range.getBegin(), DiagID) << Range; + Error(Range.getBegin(), "matrix type") << Range; } void MicrosoftCXXNameMangler::mangleType(const DependentSizedMatrixType *T, Qualifiers quals, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID( - DiagnosticsEngine::Error, - "Cannot mangle this dependent-sized matrix type yet"); - Diags.Report(Range.getBegin(), DiagID) << Range; + Error(Range.getBegin(), "dependent-sized matrix type") << Range; } void MicrosoftCXXNameMangler::mangleType(const DependentAddressSpaceType *T, Qualifiers, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID( - DiagnosticsEngine::Error, - "cannot mangle this dependent address space type yet"); - Diags.Report(Range.getBegin(), DiagID) << Range; + Error(Range.getBegin(), "dependent address space type") << Range; } void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, Qualifiers, @@ -3547,39 +3545,23 @@ void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *, void MicrosoftCXXNameMangler::mangleType(const TemplateSpecializationType *T, Qualifiers, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this template specialization type yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + Error(Range.getBegin(), "template specialization type") << Range; } void MicrosoftCXXNameMangler::mangleType(const DependentNameType *T, Qualifiers, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this dependent name type yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + Error(Range.getBegin(), "dependent name type") << Range; } void MicrosoftCXXNameMangler::mangleType( const DependentTemplateSpecializationType *T, Qualifiers, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this dependent template specialization type yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + Error(Range.getBegin(), "dependent template specialization type") << Range; } void MicrosoftCXXNameMangler::mangleType(const PackExpansionType *T, Qualifiers, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this pack expansion yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + Error(Range.getBegin(), "pack expansion") << Range; } void MicrosoftCXXNameMangler::mangleType(const PackIndexingType *T, @@ -3590,60 +3572,37 @@ void MicrosoftCXXNameMangler::mangleType(const PackIndexingType *T, void MicrosoftCXXNameMangler::mangleType(const TypeOfType *T, Qualifiers, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this typeof(type) yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + Error(Range.getBegin(), "typeof(type)") << Range; } void MicrosoftCXXNameMangler::mangleType(const TypeOfExprType *T, Qualifiers, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this typeof(expression) yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + Error(Range.getBegin(), "typeof(expression)") << Range; } void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T, Qualifiers, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this decltype() yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + Error(Range.getBegin(), "decltype()") << Range; } void MicrosoftCXXNameMangler::mangleType(const UnaryTransformType *T, Qualifiers, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this unary transform type yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + Error(Range.getBegin(), "unary transform type") << Range; } void MicrosoftCXXNameMangler::mangleType(const AutoType *T, Qualifiers, SourceRange Range) { assert(T->getDeducedType().isNull() && "expecting a dependent type!"); - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this 'auto' type yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + Error(Range.getBegin(), "'auto' type") << Range; } void MicrosoftCXXNameMangler::mangleType( const DeducedTemplateSpecializationType *T, Qualifiers, SourceRange Range) { assert(T->getDeducedType().isNull() && "expecting a dependent type!"); - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this deduced class template specialization type yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + Error(Range.getBegin(), "deduced class template specialization type") + << Range; } void MicrosoftCXXNameMangler::mangleType(const AtomicType *T, Qualifiers, @@ -3717,10 +3676,7 @@ void MicrosoftCXXNameMangler::mangleType(const BitIntType *T, Qualifiers, void MicrosoftCXXNameMangler::mangleType(const DependentBitIntType *T, Qualifiers, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID( - DiagnosticsEngine::Error, "cannot mangle this DependentBitInt type yet"); - Diags.Report(Range.getBegin(), DiagID) << Range; + Error(Range.getBegin(), "DependentBitInt type") << Range; } // ::= | | diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp index c8792941a6bb6..451a9fe9fe3d2 100644 --- a/clang/lib/AST/StmtOpenMP.cpp +++ b/clang/lib/AST/StmtOpenMP.cpp @@ -297,10 +297,11 @@ OMPParallelDirective *OMPParallelDirective::CreateEmpty(const ASTContext &C, /*NumChildren=*/1); } -OMPSimdDirective *OMPSimdDirective::Create( - const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - unsigned CollapsedNum, ArrayRef Clauses, Stmt *AssociatedStmt, - const HelperExprs &Exprs, OpenMPDirectiveKind ParamPrevMappedDirective) { +OMPSimdDirective * +OMPSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, unsigned CollapsedNum, + ArrayRef Clauses, Stmt *AssociatedStmt, + const HelperExprs &Exprs) { auto *Dir = createDirective( C, Clauses, AssociatedStmt, numLoopChildren(CollapsedNum, OMPD_simd), StartLoc, EndLoc, CollapsedNum); @@ -320,7 +321,6 @@ OMPSimdDirective *OMPSimdDirective::Create( Dir->setDependentInits(Exprs.DependentInits); Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); - Dir->setMappedDirective(ParamPrevMappedDirective); return Dir; } @@ -336,8 +336,7 @@ OMPSimdDirective *OMPSimdDirective::CreateEmpty(const ASTContext &C, OMPForDirective *OMPForDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, Stmt *AssociatedStmt, - const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel, - OpenMPDirectiveKind ParamPrevMappedDirective) { + const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel) { auto *Dir = createDirective( C, Clauses, AssociatedStmt, numLoopChildren(CollapsedNum, OMPD_for) + 1, StartLoc, EndLoc, CollapsedNum); @@ -367,7 +366,6 @@ OMPForDirective *OMPForDirective::Create( Dir->setPreInits(Exprs.PreInits); Dir->setTaskReductionRefExpr(TaskRedRef); Dir->setHasCancel(HasCancel); - Dir->setMappedDirective(ParamPrevMappedDirective); return Dir; } @@ -449,6 +447,44 @@ OMPUnrollDirective *OMPUnrollDirective::CreateEmpty(const ASTContext &C, SourceLocation(), SourceLocation()); } +OMPReverseDirective * +OMPReverseDirective::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, Stmt *AssociatedStmt, + Stmt *TransformedStmt, Stmt *PreInits) { + OMPReverseDirective *Dir = createDirective( + C, std::nullopt, AssociatedStmt, TransformedStmtOffset + 1, StartLoc, + EndLoc); + Dir->setTransformedStmt(TransformedStmt); + Dir->setPreInits(PreInits); + return Dir; +} + +OMPReverseDirective *OMPReverseDirective::CreateEmpty(const ASTContext &C) { + return createEmptyDirective( + C, /*NumClauses=*/0, /*HasAssociatedStmt=*/true, + TransformedStmtOffset + 1, SourceLocation(), SourceLocation()); +} + +OMPInterchangeDirective *OMPInterchangeDirective::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef Clauses, unsigned NumLoops, Stmt *AssociatedStmt, + Stmt *TransformedStmt, Stmt *PreInits) { + OMPInterchangeDirective *Dir = createDirective( + C, Clauses, AssociatedStmt, TransformedStmtOffset + 1, StartLoc, EndLoc, + NumLoops); + Dir->setTransformedStmt(TransformedStmt); + Dir->setPreInits(PreInits); + return Dir; +} + +OMPInterchangeDirective * +OMPInterchangeDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, + unsigned NumLoops) { + return createEmptyDirective( + C, NumClauses, /*HasAssociatedStmt=*/true, TransformedStmtOffset + 1, + SourceLocation(), SourceLocation(), NumLoops); +} + OMPForSimdDirective * OMPForSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, @@ -1531,10 +1567,11 @@ OMPParallelMaskedTaskLoopSimdDirective::CreateEmpty(const ASTContext &C, CollapsedNum); } -OMPDistributeDirective *OMPDistributeDirective::Create( - const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - unsigned CollapsedNum, ArrayRef Clauses, Stmt *AssociatedStmt, - const HelperExprs &Exprs, OpenMPDirectiveKind ParamPrevMappedDirective) { +OMPDistributeDirective * +OMPDistributeDirective::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, unsigned CollapsedNum, + ArrayRef Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs) { auto *Dir = createDirective( C, Clauses, AssociatedStmt, numLoopChildren(CollapsedNum, OMPD_distribute), StartLoc, EndLoc, @@ -1563,7 +1600,6 @@ OMPDistributeDirective *OMPDistributeDirective::Create( Dir->setDependentInits(Exprs.DependentInits); Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); - Dir->setMappedDirective(ParamPrevMappedDirective); return Dir; } diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 1b6758a432ad6..9e472a240c98a 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -763,6 +763,16 @@ void StmtPrinter::VisitOMPUnrollDirective(OMPUnrollDirective *Node) { PrintOMPExecutableDirective(Node); } +void StmtPrinter::VisitOMPReverseDirective(OMPReverseDirective *Node) { + Indent() << "#pragma omp reverse"; + PrintOMPExecutableDirective(Node); +} + +void StmtPrinter::VisitOMPInterchangeDirective(OMPInterchangeDirective *Node) { + Indent() << "#pragma omp interchange"; + PrintOMPExecutableDirective(Node); +} + void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) { Indent() << "#pragma omp for"; PrintOMPExecutableDirective(Node); diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index dcfb3093470c2..cf9988fcbe75c 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -624,7 +624,7 @@ void OMPClauseProfiler::VisitOMPFilterClause(const OMPFilterClause *C) { template void OMPClauseProfiler::VisitOMPClauseList(T *Node) { - for (auto *E : Node->varlists()) { + for (auto *E : Node->varlist()) { if (E) Profiler->VisitStmt(E); } @@ -918,7 +918,7 @@ void OMPClauseProfiler::VisitOMPUsesAllocatorsClause( void OMPClauseProfiler::VisitOMPAffinityClause(const OMPAffinityClause *C) { if (const Expr *Modifier = C->getModifier()) Profiler->VisitStmt(Modifier); - for (const Expr *E : C->varlists()) + for (const Expr *E : C->varlist()) Profiler->VisitStmt(E); } void OMPClauseProfiler::VisitOMPOrderClause(const OMPOrderClause *C) {} @@ -985,6 +985,15 @@ void StmtProfiler::VisitOMPUnrollDirective(const OMPUnrollDirective *S) { VisitOMPLoopTransformationDirective(S); } +void StmtProfiler::VisitOMPReverseDirective(const OMPReverseDirective *S) { + VisitOMPLoopTransformationDirective(S); +} + +void StmtProfiler::VisitOMPInterchangeDirective( + const OMPInterchangeDirective *S) { + VisitOMPLoopTransformationDirective(S); +} + void StmtProfiler::VisitOMPForDirective(const OMPForDirective *S) { VisitOMPLoopDirective(S); } diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 8de38dc97e7cc..374f1ab1a1d98 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -75,7 +75,7 @@ bool Qualifiers::isStrictSupersetOf(Qualifiers Other) const { const IdentifierInfo* QualType::getBaseTypeIdentifier() const { const Type* ty = getTypePtr(); NamedDecl *ND = nullptr; - if (ty->isPointerType() || ty->isReferenceType()) + if (ty->isPointerOrReferenceType()) return ty->getPointeeType().getBaseTypeIdentifier(); else if (ty->isRecordType()) ND = ty->castAs()->getDecl(); diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp index bf87b1aa0992a..06309d327896b 100644 --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -537,14 +537,23 @@ class PatternSet { /// that didn't match. /// Return true if there are still any patterns left. bool consumeNameSuffix(StringRef NodeName, bool CanSkip) { - for (size_t I = 0; I < Patterns.size();) { - if (::clang::ast_matchers::internal::consumeNameSuffix(Patterns[I].P, - NodeName) || - CanSkip) { - ++I; - } else { - Patterns.erase(Patterns.begin() + I); + if (CanSkip) { + // If we can skip the node, then we need to handle the case where a + // skipped node has the same name as its parent. + // namespace a { inline namespace a { class A; } } + // cxxRecordDecl(hasName("::a::A")) + // To do this, any patterns that match should be duplicated in our set, + // one of them with the tail removed. + for (size_t I = 0, E = Patterns.size(); I != E; ++I) { + StringRef Pattern = Patterns[I].P; + if (ast_matchers::internal::consumeNameSuffix(Patterns[I].P, NodeName)) + Patterns.push_back({Pattern, Patterns[I].IsFullyQualified}); } + } else { + llvm::erase_if(Patterns, [&NodeName](auto &Pattern) { + return !::clang::ast_matchers::internal::consumeNameSuffix(Pattern.P, + NodeName); + }); } return !Patterns.empty(); } diff --git a/clang/lib/Analysis/Consumed.cpp b/clang/lib/Analysis/Consumed.cpp index d01c7f688e8b5..63c5943242944 100644 --- a/clang/lib/Analysis/Consumed.cpp +++ b/clang/lib/Analysis/Consumed.cpp @@ -141,7 +141,7 @@ static bool isCallableInState(const CallableWhenAttr *CWAttr, } static bool isConsumableType(const QualType &QT) { - if (QT->isPointerType() || QT->isReferenceType()) + if (QT->isPointerOrReferenceType()) return false; if (const CXXRecordDecl *RD = QT->getAsCXXRecordDecl()) @@ -151,7 +151,7 @@ static bool isConsumableType(const QualType &QT) { } static bool isAutoCastType(const QualType &QT) { - if (QT->isPointerType() || QT->isReferenceType()) + if (QT->isPointerOrReferenceType()) return false; if (const CXXRecordDecl *RD = QT->getAsCXXRecordDecl()) @@ -186,10 +186,6 @@ static bool isTestingFunction(const FunctionDecl *FunDecl) { return FunDecl->hasAttr(); } -static bool isPointerOrRef(QualType ParamType) { - return ParamType->isPointerType() || ParamType->isReferenceType(); -} - static ConsumedState mapConsumableAttrState(const QualType QT) { assert(isConsumableType(QT)); @@ -648,7 +644,7 @@ bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg, setStateForVarOrTmp(StateMap, PInfo, mapReturnTypestateAttrState(RT)); else if (isRValueRef(ParamType) || isConsumableType(ParamType)) setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Consumed); - else if (isPointerOrRef(ParamType) && + else if (ParamType->isPointerOrReferenceType() && (!ParamType->getPointeeType().isConstQualified() || isSetOnReadPtrType(ParamType))) setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Unknown); diff --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp index 3b3782fa1db9a..6d726ae44104e 100644 --- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp +++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp @@ -404,25 +404,24 @@ ExprMutationAnalyzer::Analyzer::findDirectMutation(const Expr *Exp) { memberExpr(hasObjectExpression(canResolveToExpr(Exp)))), nonConstReferenceType()); const auto NotInstantiated = unless(hasDeclaration(isInstantiated())); - const auto TypeDependentCallee = - callee(expr(anyOf(unresolvedLookupExpr(), unresolvedMemberExpr(), - cxxDependentScopeMemberExpr(), - hasType(templateTypeParmType()), isTypeDependent()))); - - const auto AsNonConstRefArg = anyOf( - callExpr(NonConstRefParam, NotInstantiated), - cxxConstructExpr(NonConstRefParam, NotInstantiated), - callExpr(TypeDependentCallee, hasAnyArgument(canResolveToExpr(Exp))), - cxxUnresolvedConstructExpr(hasAnyArgument(canResolveToExpr(Exp))), - // Previous False Positive in the following Code: - // `template void f() { int i = 42; new Type(i); }` - // Where the constructor of `Type` takes its argument as reference. - // The AST does not resolve in a `cxxConstructExpr` because it is - // type-dependent. - parenListExpr(hasDescendant(expr(canResolveToExpr(Exp)))), - // If the initializer is for a reference type, there is no cast for - // the variable. Values are cast to RValue first. - initListExpr(hasAnyInit(expr(canResolveToExpr(Exp))))); + + const auto AsNonConstRefArg = + anyOf(callExpr(NonConstRefParam, NotInstantiated), + cxxConstructExpr(NonConstRefParam, NotInstantiated), + // If the call is type-dependent, we can't properly process any + // argument because required type conversions and implicit casts + // will be inserted only after specialization. + callExpr(isTypeDependent(), hasAnyArgument(canResolveToExpr(Exp))), + cxxUnresolvedConstructExpr(hasAnyArgument(canResolveToExpr(Exp))), + // Previous False Positive in the following Code: + // `template void f() { int i = 42; new Type(i); }` + // Where the constructor of `Type` takes its argument as reference. + // The AST does not resolve in a `cxxConstructExpr` because it is + // type-dependent. + parenListExpr(hasDescendant(expr(canResolveToExpr(Exp)))), + // If the initializer is for a reference type, there is no cast for + // the variable. Values are cast to RValue first. + initListExpr(hasAnyInit(expr(canResolveToExpr(Exp))))); // Captured by a lambda by reference. // If we're initializing a capture with 'Exp' directly then we're initializing diff --git a/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp b/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp index 255543021a998..876b5a3db5249 100644 --- a/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp +++ b/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp @@ -16,6 +16,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/Stmt.h" #include "clang/Analysis/CFG.h" +#include "clang/Analysis/FlowSensitive/ASTOps.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Error.h" @@ -96,8 +97,7 @@ static llvm::BitVector findReachableBlocks(const CFG &Cfg) { static llvm::DenseSet buildContainsExprConsumedInDifferentBlock( - const CFG &Cfg, - const llvm::DenseMap &StmtToBlock) { + const CFG &Cfg, const internal::StmtToBlockMap &StmtToBlock) { llvm::DenseSet Result; auto CheckChildExprs = [&Result, &StmtToBlock](const Stmt *S, @@ -105,7 +105,7 @@ buildContainsExprConsumedInDifferentBlock( for (const Stmt *Child : S->children()) { if (!isa_and_nonnull(Child)) continue; - const CFGBlock *ChildBlock = StmtToBlock.lookup(Child); + const CFGBlock *ChildBlock = StmtToBlock.lookup(*Child); if (ChildBlock != Block) Result.insert(ChildBlock); } @@ -126,6 +126,13 @@ buildContainsExprConsumedInDifferentBlock( return Result; } +namespace internal { + +StmtToBlockMap::StmtToBlockMap(const CFG &Cfg) + : StmtToBlock(buildStmtToBasicBlockMap(Cfg)) {} + +} // namespace internal + llvm::Expected AdornedCFG::build(const FunctionDecl &Func) { if (!Func.doesThisDeclarationHaveABody()) return llvm::createStringError( @@ -166,8 +173,7 @@ llvm::Expected AdornedCFG::build(const Decl &D, Stmt &S, std::make_error_code(std::errc::invalid_argument), "CFG::buildCFG failed"); - llvm::DenseMap StmtToBlock = - buildStmtToBasicBlockMap(*Cfg); + internal::StmtToBlockMap StmtToBlock(*Cfg); llvm::BitVector BlockReachable = findReachableBlocks(*Cfg); diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index f734168e647bd..e1f68e493f355 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -416,7 +416,7 @@ class ResultObjectVisitor : public AnalysisASTVisitor { // below them can initialize the same object (or part of it). if (isa(E) || isa(E) || isa(E) || isa(E) || isa(E) || - isa(E) || + isa(E) || isa(E) || // We treat `BuiltinBitCastExpr` as an "original initializer" too as // it may not even be casting from a record type -- and even if it is, // the two objects are in general of unrelated type. @@ -524,12 +524,21 @@ void Environment::initialize() { assert(VarDecl != nullptr); setStorageLocation(*VarDecl, createObject(*VarDecl, nullptr)); } else if (Capture.capturesThis()) { - const auto *SurroundingMethodDecl = - cast(InitialTargetFunc->getNonClosureAncestor()); - QualType ThisPointeeType = - SurroundingMethodDecl->getFunctionObjectParameterType(); - setThisPointeeStorageLocation( - cast(createObject(ThisPointeeType))); + if (auto *Ancestor = InitialTargetFunc->getNonClosureAncestor()) { + const auto *SurroundingMethodDecl = cast(Ancestor); + QualType ThisPointeeType = + SurroundingMethodDecl->getFunctionObjectParameterType(); + setThisPointeeStorageLocation( + cast(createObject(ThisPointeeType))); + } else if (auto *FieldBeingInitialized = + dyn_cast(Parent->getLambdaContextDecl())) { + // This is in a field initializer, rather than a method. + setThisPointeeStorageLocation( + cast(createObject(QualType( + FieldBeingInitialized->getParent()->getTypeForDecl(), 0)))); + } else { + assert(false && "Unexpected this-capturing lambda context."); + } } } } else if (MethodDecl->isImplicitObjectMemberFunction()) { diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index 3c896d373a211..9c54eb16d2224 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -40,17 +40,16 @@ namespace clang { namespace dataflow { const Environment *StmtToEnvMap::getEnvironment(const Stmt &S) const { - auto BlockIt = ACFG.getStmtToBlock().find(&ignoreCFGOmittedNodes(S)); - if (BlockIt == ACFG.getStmtToBlock().end()) { + const CFGBlock *Block = ACFG.blockForStmt(S); + if (Block == nullptr) { assert(false); - // Return null to avoid dereferencing the end iterator in non-assert builds. return nullptr; } - if (!ACFG.isBlockReachable(*BlockIt->getSecond())) + if (!ACFG.isBlockReachable(*Block)) return nullptr; - if (BlockIt->getSecond()->getBlockID() == CurBlockID) + if (Block->getBlockID() == CurBlockID) return &CurState.Env; - const auto &State = BlockToState[BlockIt->getSecond()->getBlockID()]; + const auto &State = BlockToState[Block->getBlockID()]; if (!(State)) return nullptr; return &State->Env; diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp index 200682faafd6a..8afd18b315d28 100644 --- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -243,10 +243,11 @@ computeBlockInputState(const CFGBlock &Block, AnalysisContext &AC) { // See `NoreturnDestructorTest` for concrete examples. if (Block.succ_begin()->getReachableBlock() != nullptr && Block.succ_begin()->getReachableBlock()->hasNoReturnElement()) { - auto &StmtToBlock = AC.ACFG.getStmtToBlock(); - auto StmtBlock = StmtToBlock.find(Block.getTerminatorStmt()); - assert(StmtBlock != StmtToBlock.end()); - llvm::erase(Preds, StmtBlock->getSecond()); + const CFGBlock *StmtBlock = nullptr; + if (const Stmt *Terminator = Block.getTerminatorStmt()) + StmtBlock = AC.ACFG.blockForStmt(*Terminator); + assert(StmtBlock != nullptr); + llvm::erase(Preds, StmtBlock); } } diff --git a/clang/lib/Analysis/LiveVariables.cpp b/clang/lib/Analysis/LiveVariables.cpp index 6d03dd05ca3d2..481932ee59c8e 100644 --- a/clang/lib/Analysis/LiveVariables.cpp +++ b/clang/lib/Analysis/LiveVariables.cpp @@ -214,6 +214,22 @@ static void AddLiveExpr(llvm::ImmutableSet &Set, Set = F.add(Set, LookThroughExpr(E)); } +/// Add as a live expression all individual conditions in a logical expression. +/// For example, for the expression: +/// "(a < b) || (c && d && ((e || f) != (g && h)))" +/// the following expressions will be added as live: +/// "a < b", "c", "d", "((e || f) != (g && h))" +static void AddAllConditionalTerms(llvm::ImmutableSet &Set, + llvm::ImmutableSet::Factory &F, + const Expr *Cond) { + AddLiveExpr(Set, F, Cond); + if (auto const *BO = dyn_cast(Cond->IgnoreParens()); + BO && BO->isLogicalOp()) { + AddAllConditionalTerms(Set, F, BO->getLHS()); + AddAllConditionalTerms(Set, F, BO->getRHS()); + } +} + void TransferFunctions::Visit(Stmt *S) { if (observer) observer->observeStmt(S, currentBlock, val); @@ -313,7 +329,27 @@ void TransferFunctions::Visit(Stmt *S) { AddLiveExpr(val.liveExprs, LV.ESetFact, cast(S)->getCond()); return; } - + case Stmt::ConditionalOperatorClass: { + // Keep not only direct children alive, but also all the short-circuited + // parts of the condition. Short-circuiting evaluation may cause the + // conditional operator evaluation to skip the evaluation of the entire + // condtion expression, so the value of the entire condition expression is + // never computed. + // + // This makes a difference when we compare exploded nodes coming from true + // and false expressions with no side effects: the only difference in the + // state is the value of (part of) the condition. + // + // BinaryConditionalOperatorClass ('x ?: y') is not affected because it + // explicitly calculates the value of the entire condition expression (to + // possibly use as a value for the "true expr") even if it is + // short-circuited. + auto const *CO = cast(S); + AddAllConditionalTerms(val.liveExprs, LV.ESetFact, CO->getCond()); + AddLiveExpr(val.liveExprs, LV.ESetFact, CO->getTrueExpr()); + AddLiveExpr(val.liveExprs, LV.ESetFact, CO->getFalseExpr()); + return; + } } // HACK + FIXME: What is this? One could only guess that this is an attempt to diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp index 3e8c959ccee4f..cbcfefdc52549 100644 --- a/clang/lib/Analysis/ThreadSafetyCommon.cpp +++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp @@ -97,7 +97,7 @@ static StringRef ClassifyDiagnostic(QualType VDT) { if (const auto *TD = TT->getDecl()) if (const auto *CA = TD->getAttr()) return ClassifyDiagnostic(CA); - } else if (VDT->isPointerType() || VDT->isReferenceType()) + } else if (VDT->isPointerOrReferenceType()) return ClassifyDiagnostic(VDT->getPointeeType()); return "mutex"; diff --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp index 9577277d85f81..9ce6efe6fce60 100644 --- a/clang/lib/Basic/Attributes.cpp +++ b/clang/lib/Basic/Attributes.cpp @@ -157,6 +157,40 @@ std::string AttributeCommonInfo::getNormalizedFullName() const { normalizeName(getAttrName(), getScopeName(), getSyntax())); } +static StringRef getSyntaxName(AttributeCommonInfo::Syntax SyntaxUsed) { + switch (SyntaxUsed) { + case AttributeCommonInfo::AS_GNU: + return "GNU"; + case AttributeCommonInfo::AS_CXX11: + return "CXX11"; + case AttributeCommonInfo::AS_C23: + return "C23"; + case AttributeCommonInfo::AS_Declspec: + return "Declspec"; + case AttributeCommonInfo::AS_Microsoft: + return "Microsoft"; + case AttributeCommonInfo::AS_Keyword: + return "Keyword"; + case AttributeCommonInfo::AS_Pragma: + return "Pragma"; + case AttributeCommonInfo::AS_ContextSensitiveKeyword: + return "ContextSensitiveKeyword"; + case AttributeCommonInfo::AS_HLSLAnnotation: + return "HLSLAnnotation"; + case AttributeCommonInfo::AS_Implicit: + return "Implicit"; + } + llvm_unreachable("Invalid attribute syntax"); +} + +std::string AttributeCommonInfo::normalizeFullNameWithSyntax( + const IdentifierInfo *Name, const IdentifierInfo *ScopeName, + Syntax SyntaxUsed) { + return (Twine(getSyntaxName(SyntaxUsed)) + + "::" + normalizeName(Name, ScopeName, SyntaxUsed)) + .str(); +} + unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const { // Both variables will be used in tablegen generated // attribute spell list index matching code. diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp index 7116e27cd9546..25a601573698e 100644 --- a/clang/lib/Basic/Builtins.cpp +++ b/clang/lib/Basic/Builtins.cpp @@ -90,6 +90,9 @@ static bool builtinIsSupported(const Builtin::Info &BuiltinInfo, /* MSMode Unsupported */ if (!LangOpts.MicrosoftExt && (BuiltinInfo.Langs & MS_LANG)) return false; + /* HLSLMode Unsupported */ + if (!LangOpts.HLSL && (BuiltinInfo.Langs & HLSL_LANG)) + return false; /* ObjC Unsupported */ if (!LangOpts.ObjC && BuiltinInfo.Langs == OBJC_LANG) return false; diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp index e5adc034f60c1..9331a63d91b17 100644 --- a/clang/lib/Basic/LangOptions.cpp +++ b/clang/lib/Basic/LangOptions.cpp @@ -34,8 +34,8 @@ void LangOptions::resetNonModularOptions() { // invocations that cannot be round-tripped to arguments. // FIXME: we should derive this automatically from ImpliedBy in tablegen. AllowFPReassoc = UnsafeFPMath; - NoHonorNaNs = FiniteMathOnly; - NoHonorInfs = FiniteMathOnly; + NoHonorInfs = FastMath; + NoHonorNaNs = FastMath; // These options do not affect AST generation. NoSanitizeFiles.clear(); diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 766d6a8418a6a..b141e48e77e3c 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -684,7 +684,8 @@ bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) { } bool clang::isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind) { - return DKind == OMPD_tile || DKind == OMPD_unroll; + return DKind == OMPD_tile || DKind == OMPD_unroll || DKind == OMPD_reverse || + DKind == OMPD_interchange; } bool clang::isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind) { diff --git a/clang/lib/Basic/Sarif.cpp b/clang/lib/Basic/Sarif.cpp index 8c144df341673..980b0ae40ae22 100644 --- a/clang/lib/Basic/Sarif.cpp +++ b/clang/lib/Basic/Sarif.cpp @@ -141,7 +141,7 @@ static unsigned int adjustColumnPos(FullSourceLoc Loc, /// @{ /// \internal -json::Object createMessage(StringRef Text) { +static json::Object createMessage(StringRef Text) { return json::Object{{"text", Text.str()}}; } diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 2692ddec26ff4..6ba31cc05a0d7 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -204,7 +204,8 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, StringRef AArch64TargetInfo::getABI() const { return ABI; } bool AArch64TargetInfo::setABI(const std::string &Name) { - if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs") + if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs" && + Name != "pauthtest") return false; ABI = Name; @@ -218,6 +219,12 @@ bool AArch64TargetInfo::validateTarget(DiagnosticsEngine &Diags) const { Diags.Report(diag::err_target_unsupported_abi_with_fpu) << ABI; return false; } + if (getTriple().getEnvironment() == llvm::Triple::PAuthTest && + getTriple().getOS() != llvm::Triple::Linux) { + Diags.Report(diag::err_target_unsupported_abi_for_triple) + << getTriple().getEnvironmentName() << getTriple().getTriple(); + return false; + } return true; } @@ -449,6 +456,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasSVE2) Builder.defineMacro("__ARM_FEATURE_SVE2", "1"); + if (HasSVE2p1) + Builder.defineMacro("__ARM_FEATURE_SVE2p1", "1"); + if (HasSVE2 && HasSVE2AES) Builder.defineMacro("__ARM_FEATURE_SVE2_AES", "1"); @@ -467,8 +477,15 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, } if (HasSME2) { - Builder.defineMacro("__ARM_FEATURE_SME"); - Builder.defineMacro("__ARM_FEATURE_SME2"); + Builder.defineMacro("__ARM_FEATURE_SME", "1"); + Builder.defineMacro("__ARM_FEATURE_SME2", "1"); + Builder.defineMacro("__ARM_FEATURE_LOCALLY_STREAMING", "1"); + } + + if (HasSME2p1) { + Builder.defineMacro("__ARM_FEATURE_SME", "1"); + Builder.defineMacro("__ARM_FEATURE_SME2", "1"); + Builder.defineMacro("__ARM_FEATURE_SME2p1", "1"); Builder.defineMacro("__ARM_FEATURE_LOCALLY_STREAMING", "1"); } @@ -739,8 +756,10 @@ bool AArch64TargetInfo::hasFeature(StringRef Feature) const { .Case("sve2-bitperm", FPU & SveMode && HasSVE2BitPerm) .Case("sve2-sha3", FPU & SveMode && HasSVE2SHA3) .Case("sve2-sm4", FPU & SveMode && HasSVE2SM4) + .Case("sve2p1", FPU & SveMode && HasSVE2p1) .Case("sme", HasSME) .Case("sme2", HasSME2) + .Case("sme2p1", HasSME2p1) .Case("sme-f64f64", HasSMEF64F64) .Case("sme-i16i64", HasSMEI16I64) .Case("sme-fa64", HasSMEFA64) @@ -816,6 +835,13 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector &Features, HasFullFP16 = true; HasSVE2 = true; } + if (Feature == "+sve2p1") { + FPU |= NeonMode; + FPU |= SveMode; + HasFullFP16 = true; + HasSVE2 = true; + HasSVE2p1 = true; + } if (Feature == "+sve2-aes") { FPU |= NeonMode; FPU |= SveMode; @@ -867,6 +893,13 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector &Features, HasBFloat16 = true; HasFullFP16 = true; } + if (Feature == "+sme2p1") { + HasSME = true; + HasSME2 = true; + HasSME2p1 = true; + HasBFloat16 = true; + HasFullFP16 = true; + } if (Feature == "+sme-f64f64") { HasSME = true; HasSMEF64F64 = true; diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index 71510fe289510..7bdf5a2b4106e 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -49,6 +49,7 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { bool HasMatMul = false; bool HasBFloat16 = false; bool HasSVE2 = false; + bool HasSVE2p1 = false; bool HasSVE2AES = false; bool HasSVE2SHA3 = false; bool HasSVE2SM4 = false; @@ -70,6 +71,7 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { bool HasSME2 = false; bool HasSMEF64F64 = false; bool HasSMEI16I64 = false; + bool HasSME2p1 = false; bool HasSB = false; bool HasPredRes = false; bool HasSSBS = false; diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp index 75f71a337b7a4..cb3fd12c48ddb 100644 --- a/clang/lib/Basic/Targets/LoongArch.cpp +++ b/clang/lib/Basic/Targets/LoongArch.cpp @@ -200,7 +200,24 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts, // Define __loongarch_arch. StringRef ArchName = getCPU(); - Builder.defineMacro("__loongarch_arch", Twine('"') + ArchName + Twine('"')); + if (ArchName == "loongarch64") { + if (HasFeatureLSX) { + // TODO: As more features of the V1.1 ISA are supported, a unified "v1.1" + // arch feature set will be used to include all sub-features belonging to + // the V1.1 ISA version. + if (HasFeatureFrecipe) + Builder.defineMacro("__loongarch_arch", + Twine('"') + "la64v1.1" + Twine('"')); + else + Builder.defineMacro("__loongarch_arch", + Twine('"') + "la64v1.0" + Twine('"')); + } else { + Builder.defineMacro("__loongarch_arch", + Twine('"') + ArchName + Twine('"')); + } + } else { + Builder.defineMacro("__loongarch_arch", Twine('"') + ArchName + Twine('"')); + } // Define __loongarch_tune. StringRef TuneCPU = getTargetOpts().TuneCPU; @@ -216,6 +233,8 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__loongarch_simd_width", "128"); Builder.defineMacro("__loongarch_sx", Twine(1)); } + if (HasFeatureFrecipe) + Builder.defineMacro("__loongarch_frecipe", Twine(1)); StringRef ABI = getABI(); if (ABI == "lp64d" || ABI == "lp64f" || ABI == "lp64s") @@ -291,6 +310,8 @@ bool LoongArchTargetInfo::handleTargetFeatures( HasFeatureLASX = true; else if (Feature == "-ual") HasUnalignedAccess = false; + else if (Feature == "+frecipe") + HasFeatureFrecipe = true; } return true; } diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h index 5fc223483951e..c668ca7eca047 100644 --- a/clang/lib/Basic/Targets/LoongArch.h +++ b/clang/lib/Basic/Targets/LoongArch.h @@ -29,6 +29,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { bool HasFeatureF; bool HasFeatureLSX; bool HasFeatureLASX; + bool HasFeatureFrecipe; public: LoongArchTargetInfo(const llvm::Triple &Triple, const TargetOptions &) @@ -37,6 +38,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { HasFeatureF = false; HasFeatureLSX = false; HasFeatureLASX = false; + HasFeatureFrecipe = false; LongDoubleWidth = 128; LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::IEEEquad(); diff --git a/clang/lib/Basic/Targets/OSTargets.cpp b/clang/lib/Basic/Targets/OSTargets.cpp index 899aefa6173ac..b56e2c7ca9c49 100644 --- a/clang/lib/Basic/Targets/OSTargets.cpp +++ b/clang/lib/Basic/Targets/OSTargets.cpp @@ -173,10 +173,10 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) { // "Under /fp:precise and /fp:strict, the compiler doesn't do any mathematical // transformation unless the transformation is guaranteed to produce a bitwise // identical result." - const bool any_imprecise_flags = - Opts.FastMath || Opts.FiniteMathOnly || Opts.UnsafeFPMath || - Opts.AllowFPReassoc || Opts.NoHonorNaNs || Opts.NoHonorInfs || - Opts.NoSignedZero || Opts.AllowRecip || Opts.ApproxFunc; + const bool any_imprecise_flags = Opts.FastMath || Opts.UnsafeFPMath || + Opts.AllowFPReassoc || Opts.NoHonorNaNs || + Opts.NoHonorInfs || Opts.NoSignedZero || + Opts.AllowRecip || Opts.ApproxFunc; // "Under both /fp:precise and /fp:fast, the compiler generates code intended // to run in the default floating-point environment." diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index 4ba4a49311d36..d8203f76a5468 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -14,6 +14,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/MacroBuilder.h" #include "clang/Basic/TargetBuiltins.h" +#include "llvm/TargetParser/PPCTargetParser.h" using namespace clang; using namespace clang::targets; @@ -385,6 +386,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("_ARCH_PWR9"); if (ArchDefs & ArchDefinePwr10) Builder.defineMacro("_ARCH_PWR10"); + if (ArchDefs & ArchDefinePwr11) + Builder.defineMacro("_ARCH_PWR11"); if (ArchDefs & ArchDefineA2) Builder.defineMacro("_ARCH_A2"); if (ArchDefs & ArchDefineE500) @@ -622,10 +625,17 @@ bool PPCTargetInfo::initFeatureMap( addP10SpecificFeatures(Features); } - // Future CPU should include all of the features of Power 10 as well as any + // Power11 includes all the same features as Power10 plus any features + // specific to the Power11 core. + if (CPU == "pwr11" || CPU == "power11") { + initFeatureMap(Features, Diags, "pwr10", FeaturesVec); + addP11SpecificFeatures(Features); + } + + // Future CPU should include all of the features of Power 11 as well as any // additional features (yet to be determined) specific to it. if (CPU == "future") { - initFeatureMap(Features, Diags, "pwr10", FeaturesVec); + initFeatureMap(Features, Diags, "pwr11", FeaturesVec); addFutureSpecificFeatures(Features); } @@ -696,6 +706,10 @@ void PPCTargetInfo::addP10SpecificFeatures( Features["isa-v31-instructions"] = true; } +// Add any Power11 specific features. +void PPCTargetInfo::addP11SpecificFeatures( + llvm::StringMap &Features) const {} + // Add features specific to the "Future" CPU. void PPCTargetInfo::addFutureSpecificFeatures( llvm::StringMap &Features) const {} @@ -869,25 +883,12 @@ ArrayRef PPCTargetInfo::getGCCAddlRegNames() const { return llvm::ArrayRef(GCCAddlRegNames); } -static constexpr llvm::StringLiteral ValidCPUNames[] = { - {"generic"}, {"440"}, {"450"}, {"601"}, {"602"}, - {"603"}, {"603e"}, {"603ev"}, {"604"}, {"604e"}, - {"620"}, {"630"}, {"g3"}, {"7400"}, {"g4"}, - {"7450"}, {"g4+"}, {"750"}, {"8548"}, {"970"}, - {"g5"}, {"a2"}, {"e500"}, {"e500mc"}, {"e5500"}, - {"power3"}, {"pwr3"}, {"power4"}, {"pwr4"}, {"power5"}, - {"pwr5"}, {"power5x"}, {"pwr5x"}, {"power6"}, {"pwr6"}, - {"power6x"}, {"pwr6x"}, {"power7"}, {"pwr7"}, {"power8"}, - {"pwr8"}, {"power9"}, {"pwr9"}, {"power10"}, {"pwr10"}, - {"powerpc"}, {"ppc"}, {"ppc32"}, {"powerpc64"}, {"ppc64"}, - {"powerpc64le"}, {"ppc64le"}, {"future"}}; - bool PPCTargetInfo::isValidCPUName(StringRef Name) const { - return llvm::is_contained(ValidCPUNames, Name); + return llvm::PPC::isValidCPU(Name); } void PPCTargetInfo::fillValidCPUList(SmallVectorImpl &Values) const { - Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); + llvm::PPC::fillValidCPUList(Values); } void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index b15ab6fbcf492..6d5d8dd54d013 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -44,8 +44,9 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { ArchDefinePwr8 = 1 << 12, ArchDefinePwr9 = 1 << 13, ArchDefinePwr10 = 1 << 14, - ArchDefineFuture = 1 << 15, - ArchDefineA2 = 1 << 16, + ArchDefinePwr11 = 1 << 15, + ArchDefineFuture = 1 << 16, + ArchDefineA2 = 1 << 17, ArchDefineE500 = 1 << 18 } ArchDefineTypes; @@ -166,11 +167,16 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { ArchDefinePwr7 | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) + .Cases("power11", "pwr11", + ArchDefinePwr11 | ArchDefinePwr10 | ArchDefinePwr9 | + ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6 | + ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | + ArchDefinePpcgr | ArchDefinePpcsq) .Case("future", - ArchDefineFuture | ArchDefinePwr10 | ArchDefinePwr9 | - ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6 | - ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | - ArchDefinePpcgr | ArchDefinePpcsq) + ArchDefineFuture | ArchDefinePwr11 | ArchDefinePwr10 | + ArchDefinePwr9 | ArchDefinePwr8 | ArchDefinePwr7 | + ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | + ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) .Cases("8548", "e500", ArchDefineE500) .Default(ArchDefineNone); } @@ -192,6 +198,7 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { const std::vector &FeaturesVec) const override; void addP10SpecificFeatures(llvm::StringMap &Features) const; + void addP11SpecificFeatures(llvm::StringMap &Features) const; void addFutureSpecificFeatures(llvm::StringMap &Features) const; bool handleTargetFeatures(std::vector &Features, diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index 9159162f01d1b..41d836330b38c 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -479,3 +479,9 @@ RISCVTargetInfo::checkCallingConvention(CallingConv CC) const { return CCCR_OK; } } + +bool RISCVTargetInfo::validateCpuSupports(StringRef Feature) const { + // Only allow extensions we have a known bit position for in the + // __riscv_feature_bits structure. + return -1 != llvm::RISCVISAInfo::getRISCVFeaturesBitPosition(Feature); +} diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h index d5df6344bedc0..626274b8fc437 100644 --- a/clang/lib/Basic/Targets/RISCV.h +++ b/clang/lib/Basic/Targets/RISCV.h @@ -126,6 +126,10 @@ class RISCVTargetInfo : public TargetInfo { std::pair hardwareInterferenceSizes() const override { return std::make_pair(32, 32); } + + bool supportsCpuSupports() const override { return getTriple().isOSLinux(); } + bool supportsCpuInit() const override { return getTriple().isOSLinux(); } + bool validateCpuSupports(StringRef Feature) const override; }; class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo { public: diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index 121a2c2d795fe..18e6dbf03e00d 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -963,8 +963,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__CF__"); if (HasZU) Builder.defineMacro("__ZU__"); - // Condition here is aligned with the feature set of mapxf in Options.td - if (HasEGPR && HasPush2Pop2 && HasPPX && HasNDD && HasCCMP && HasNF && HasCF) + if (HasEGPR && HasPush2Pop2 && HasPPX && HasNDD && HasCCMP && HasNF && + HasCF && HasZU) Builder.defineMacro("__APX_F__"); if (HasEGPR && HasInlineAsmUseGPR32) Builder.defineMacro("__APX_INLINE_ASM_USE_GPR32__"); diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index cdec41afd1a4b..ba34ab2c7f336 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -513,15 +513,6 @@ class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo public: NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : NetBSDTargetInfo(Triple, Opts) {} - - LangOptions::FPEvalMethodKind getFPEvalMethod() const override { - VersionTuple OsVersion = getTriple().getOSVersion(); - // New NetBSD uses the default rounding mode. - if (OsVersion >= VersionTuple(6, 99, 26) || OsVersion.getMajor() == 0) - return X86_32TargetInfo::getFPEvalMethod(); - // NetBSD before 6.99.26 defaults to "double" rounding. - return LangOptions::FPEvalMethodKind::FEM_Double; - } }; class LLVM_LIBRARY_VISIBILITY OpenBSDI386TargetInfo diff --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h index 35ec370a139c9..a18c7169af1eb 100644 --- a/clang/lib/CodeGen/Address.h +++ b/clang/lib/CodeGen/Address.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_ADDRESS_H #define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H +#include "CGPointerAuthInfo.h" #include "clang/AST/CharUnits.h" #include "clang/AST/Type.h" #include "llvm/ADT/PointerIntPair.h" @@ -108,6 +109,22 @@ class RawAddress { /// Like RawAddress, an abstract representation of an aligned address, but the /// pointer contained in this class is possibly signed. +/// +/// This is designed to be an IR-level abstraction, carrying just the +/// information necessary to perform IR operations on an address like loads and +/// stores. In particular, it doesn't carry C type information or allow the +/// representation of things like bit-fields; clients working at that level +/// should generally be using `LValue`. +/// +/// An address may be either *raw*, meaning that it's an ordinary machine +/// pointer, or *signed*, meaning that the pointer carries an embedded +/// pointer-authentication signature. Representing signed pointers directly in +/// this abstraction allows the authentication to be delayed as long as possible +/// without forcing IRGen to use totally different code paths for signed and +/// unsigned values or to separately propagate signature information through +/// every API that manipulates addresses. Pointer arithmetic on signed addresses +/// (e.g. drilling down to a struct field) is accumulated into a separate offset +/// which is applied when the address is finally accessed. class Address { friend class CGBuilderTy; @@ -121,7 +138,11 @@ class Address { CharUnits Alignment; - /// Offset from the base pointer. + /// The ptrauth information needed to authenticate the base pointer. + CGPointerAuthInfo PtrAuthInfo; + + /// Offset from the base pointer. This is non-null only when the base + /// pointer is signed. llvm::Value *Offset = nullptr; llvm::Value *emitRawPointerSlow(CodeGenFunction &CGF) const; @@ -140,12 +161,14 @@ class Address { } Address(llvm::Value *BasePtr, llvm::Type *ElementType, CharUnits Alignment, - llvm::Value *Offset, KnownNonNull_t IsKnownNonNull = NotKnownNonNull) + CGPointerAuthInfo PtrAuthInfo, llvm::Value *Offset, + KnownNonNull_t IsKnownNonNull = NotKnownNonNull) : Pointer(BasePtr, IsKnownNonNull), ElementType(ElementType), - Alignment(Alignment), Offset(Offset) {} + Alignment(Alignment), PtrAuthInfo(PtrAuthInfo), Offset(Offset) {} Address(RawAddress RawAddr) - : Pointer(RawAddr.isValid() ? RawAddr.getPointer() : nullptr), + : Pointer(RawAddr.isValid() ? RawAddr.getPointer() : nullptr, + RawAddr.isValid() ? RawAddr.isKnownNonNull() : NotKnownNonNull), ElementType(RawAddr.isValid() ? RawAddr.getElementType() : nullptr), Alignment(RawAddr.isValid() ? RawAddr.getAlignment() : CharUnits::Zero()) {} @@ -192,6 +215,9 @@ class Address { /// Return the IR name of the pointer value. llvm::StringRef getName() const { return Pointer.getPointer()->getName(); } + const CGPointerAuthInfo &getPointerAuthInfo() const { return PtrAuthInfo; } + void setPointerAuthInfo(const CGPointerAuthInfo &Info) { PtrAuthInfo = Info; } + // This function is called only in CGBuilderBaseTy::CreateElementBitCast. void setElementType(llvm::Type *Ty) { assert(hasOffset() && @@ -199,6 +225,8 @@ class Address { ElementType = Ty; } + bool isSigned() const { return PtrAuthInfo.isSigned(); } + /// Whether the pointer is known not to be null. KnownNonNull_t isKnownNonNull() const { assert(isValid()); @@ -215,10 +243,15 @@ class Address { llvm::Value *getOffset() const { return Offset; } + Address getResignedAddress(const CGPointerAuthInfo &NewInfo, + CodeGenFunction &CGF) const; + /// Return the pointer contained in this class after authenticating it and /// adding offset to it if necessary. llvm::Value *emitRawPointer(CodeGenFunction &CGF) const { - return getBasePointer(); + if (!isSigned()) + return getBasePointer(); + return emitRawPointerSlow(CGF); } /// Return address with different pointer, but same element type and @@ -240,7 +273,8 @@ class Address { /// alignment. Address withElementType(llvm::Type *ElemTy) const { if (!hasOffset()) - return Address(getBasePointer(), ElemTy, getAlignment(), nullptr, + return Address(getBasePointer(), ElemTy, getAlignment(), + getPointerAuthInfo(), /*Offset=*/nullptr, isKnownNonNull()); Address A(*this); A.ElementType = ElemTy; diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index 0337c95dfa3cf..4e639a976389f 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -728,7 +728,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, llvm::Value *LoadVal1 = CGF.Builder.CreateLoad(Val1); llvm::AtomicRMWInst *RMWI = - CGF.Builder.CreateAtomicRMW(Op, Ptr, LoadVal1, Order, Scope); + CGF.emitAtomicRMWInst(Op, Ptr, LoadVal1, Order, Scope); RMWI->setVolatile(E->isVolatile()); // For __atomic_*_fetch operations, perform the operation again to @@ -2035,6 +2035,17 @@ std::pair CodeGenFunction::EmitAtomicCompareExchange( IsWeak); } +llvm::AtomicRMWInst * +CodeGenFunction::emitAtomicRMWInst(llvm::AtomicRMWInst::BinOp Op, Address Addr, + llvm::Value *Val, llvm::AtomicOrdering Order, + llvm::SyncScope::ID SSID) { + + llvm::AtomicRMWInst *RMW = + Builder.CreateAtomicRMW(Op, Addr, Val, Order, SSID); + getTargetHooks().setTargetAtomicMetadata(*this, *RMW); + return RMW; +} + void CodeGenFunction::EmitAtomicUpdate( LValue LVal, llvm::AtomicOrdering AO, const llvm::function_ref &UpdateOp, bool IsVolatile) { diff --git a/clang/lib/CodeGen/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h index 0bc4fda62979c..5d59d5a4ae2c1 100644 --- a/clang/lib/CodeGen/CGBuilder.h +++ b/clang/lib/CodeGen/CGBuilder.h @@ -190,8 +190,8 @@ class CGBuilderTy : public CGBuilderBaseTy { const llvm::Twine &Name = "") { if (!Addr.hasOffset()) return Address(CreateAddrSpaceCast(Addr.getBasePointer(), Ty, Name), - ElementTy, Addr.getAlignment(), nullptr, - Addr.isKnownNonNull()); + ElementTy, Addr.getAlignment(), Addr.getPointerAuthInfo(), + /*Offset=*/nullptr, Addr.isKnownNonNull()); // Eagerly force a raw address if these is an offset. return RawAddress( CreateAddrSpaceCast(Addr.emitRawPointer(*getCGF()), Ty, Name), diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index e192f5c701d8a..0ca0e8787ea08 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -63,6 +63,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/TargetParser/AArch64TargetParser.h" +#include "llvm/TargetParser/RISCVISAInfo.h" #include "llvm/TargetParser/X86TargetParser.h" #include #include @@ -766,7 +767,26 @@ static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD, const CallExpr *E, llvm::Constant *calleeValue) { CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E); CGCallee callee = CGCallee::forDirect(calleeValue, GlobalDecl(FD)); - return CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot()); + RValue Call = + CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot()); + + if (unsigned BuiltinID = FD->getBuiltinID()) { + // Check whether a FP math builtin function, such as BI__builtin_expf + ASTContext &Context = CGF.getContext(); + bool ConstWithoutErrnoAndExceptions = + Context.BuiltinInfo.isConstWithoutErrnoAndExceptions(BuiltinID); + // Restrict to target with errno, for example, MacOS doesn't set errno. + // TODO: Support builtin function with complex type returned, eg: cacosh + if (ConstWithoutErrnoAndExceptions && CGF.CGM.getLangOpts().MathErrno && + !CGF.Builder.getIsFPConstrained() && Call.isScalar()) { + // Emit "int" TBAA metadata on FP math libcalls. + clang::QualType IntTy = Context.IntTy; + TBAAAccessInfo TBAAInfo = CGF.CGM.getTBAAAccessInfo(IntTy); + Instruction *Inst = cast(Call.getScalarVal()); + CGF.CGM.DecorateInstructionWithTBAA(Inst, TBAAInfo); + } + } + return Call; } /// Emit a call to llvm.{sadd,uadd,ssub,usub,smul,umul}.with.overflow.* @@ -1054,7 +1074,7 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, // Build a load of the counted_by field. bool IsSigned = CountedByFD->getType()->isSignedIntegerType(); - Value *CountedByInst = EmitCountedByFieldExpr(Base, FAMDecl, CountedByFD); + Value *CountedByInst = EmitLoadOfCountedByField(Base, FAMDecl, CountedByFD); if (!CountedByInst) return getDefaultBuiltinObjectSizeResult(Type, ResType); @@ -2721,6 +2741,42 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, if (GenerateIntrinsics && !(getLangOpts().SYCLIsDevice && getTarget().getTriple().isNVPTX())) { switch (BuiltinIDIfNoAsmLabel) { + case Builtin::BIacos: + case Builtin::BIacosf: + case Builtin::BIacosl: + case Builtin::BI__builtin_acos: + case Builtin::BI__builtin_acosf: + case Builtin::BI__builtin_acosf16: + case Builtin::BI__builtin_acosl: + case Builtin::BI__builtin_acosf128: + return RValue::get(emitUnaryMaybeConstrainedFPBuiltin( + *this, E, Intrinsic::acos, Intrinsic::experimental_constrained_acos, + Intrinsic::fpbuiltin_acos)); + + case Builtin::BIasin: + case Builtin::BIasinf: + case Builtin::BIasinl: + case Builtin::BI__builtin_asin: + case Builtin::BI__builtin_asinf: + case Builtin::BI__builtin_asinf16: + case Builtin::BI__builtin_asinl: + case Builtin::BI__builtin_asinf128: + return RValue::get(emitUnaryMaybeConstrainedFPBuiltin( + *this, E, Intrinsic::asin, Intrinsic::experimental_constrained_asin, + Intrinsic::fpbuiltin_asin)); + + case Builtin::BIatan: + case Builtin::BIatanf: + case Builtin::BIatanl: + case Builtin::BI__builtin_atan: + case Builtin::BI__builtin_atanf: + case Builtin::BI__builtin_atanf16: + case Builtin::BI__builtin_atanl: + case Builtin::BI__builtin_atanf128: + return RValue::get(emitUnaryMaybeConstrainedFPBuiltin( + *this, E, Intrinsic::atan, Intrinsic::experimental_constrained_atan, + Intrinsic::fpbuiltin_atan)); + case Builtin::BIceil: case Builtin::BIceilf: case Builtin::BIceill: @@ -2756,6 +2812,18 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, *this, E, Intrinsic::cos, Intrinsic::experimental_constrained_cos, Intrinsic::fpbuiltin_cos)); + case Builtin::BIcosh: + case Builtin::BIcoshf: + case Builtin::BIcoshl: + case Builtin::BI__builtin_cosh: + case Builtin::BI__builtin_coshf: + case Builtin::BI__builtin_coshf16: + case Builtin::BI__builtin_coshl: + case Builtin::BI__builtin_coshf128: + return RValue::get(emitUnaryMaybeConstrainedFPBuiltin( + *this, E, Intrinsic::cosh, Intrinsic::experimental_constrained_cosh, + Intrinsic::fpbuiltin_cosh)); + case Builtin::BIexp: case Builtin::BIexpf: case Builtin::BIexpl: @@ -2972,6 +3040,18 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, *this, E, Intrinsic::sin, Intrinsic::experimental_constrained_sin, Intrinsic::fpbuiltin_sin)); + case Builtin::BIsinh: + case Builtin::BIsinhf: + case Builtin::BIsinhl: + case Builtin::BI__builtin_sinh: + case Builtin::BI__builtin_sinhf: + case Builtin::BI__builtin_sinhf16: + case Builtin::BI__builtin_sinhl: + case Builtin::BI__builtin_sinhf128: + return RValue::get(emitUnaryMaybeConstrainedFPBuiltin( + *this, E, Intrinsic::sinh, Intrinsic::experimental_constrained_sinh, + Intrinsic::fpbuiltin_sinh)); + case Builtin::BIsqrt: case Builtin::BIsqrtf: case Builtin::BIsqrtl: @@ -2999,6 +3079,18 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, *this, E, Intrinsic::tan, Intrinsic::experimental_constrained_tan, Intrinsic::fpbuiltin_tan)); + case Builtin::BItanh: + case Builtin::BItanhf: + case Builtin::BItanhl: + case Builtin::BI__builtin_tanh: + case Builtin::BI__builtin_tanhf: + case Builtin::BI__builtin_tanhf16: + case Builtin::BI__builtin_tanhl: + case Builtin::BI__builtin_tanhf128: + return RValue::get(emitUnaryMaybeConstrainedFPBuiltin( + *this, E, Intrinsic::tanh, Intrinsic::experimental_constrained_tanh, + Intrinsic::fpbuiltin_tanh)); + case Builtin::BItrunc: case Builtin::BItruncf: case Builtin::BItruncl: @@ -5974,8 +6066,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, getTarget().getTriple().isAMDGCN() || (getTarget().getTriple().isSPIRV() && getTarget().getTriple().getVendor() == Triple::VendorType::AMD)) { - if (getLangOpts().OpenMPIsTargetDevice) - return EmitOpenMPDevicePrintfCallExpr(E); if (getTarget().getTriple().isNVPTX()) return EmitNVPTXDevicePrintfCallExpr(E); if ((getTarget().getTriple().isAMDGCN() || @@ -14316,6 +14406,16 @@ Value *CodeGenFunction::EmitAArch64CpuInit() { return Builder.CreateCall(Func); } +Value *CodeGenFunction::EmitRISCVCpuInit() { + llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); + llvm::FunctionCallee Func = + CGM.CreateRuntimeFunction(FTy, "__init_riscv_feature_bits"); + auto *CalleeGV = cast(Func.getCallee()); + CalleeGV->setDSOLocal(true); + CalleeGV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); + return Builder.CreateCall(Func); +} + Value *CodeGenFunction::EmitX86CpuInit() { llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, /*Variadic*/ false); @@ -14368,6 +14468,42 @@ CodeGenFunction::EmitAArch64CpuSupports(ArrayRef FeaturesStrs) { return Result; } +Value *CodeGenFunction::EmitRISCVCpuSupports(const CallExpr *E) { + + const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts(); + StringRef FeatureStr = cast(FeatureExpr)->getString(); + if (!getContext().getTargetInfo().validateCpuSupports(FeatureStr)) + return Builder.getFalse(); + + // Note: We are making an unchecked assumption that the size of the + // feature array is >= 1. This holds for any version of compiler-rt + // which defines this interface. + llvm::ArrayType *ArrayOfInt64Ty = llvm::ArrayType::get(Int64Ty, 1); + llvm::Type *StructTy = llvm::StructType::get(Int32Ty, ArrayOfInt64Ty); + llvm::Constant *RISCVFeaturesBits = + CGM.CreateRuntimeVariable(StructTy, "__riscv_feature_bits"); + auto *GV = cast(RISCVFeaturesBits); + GV->setDSOLocal(true); + + auto LoadFeatureBit = [&](unsigned Index) { + // Create GEP then load. + Value *IndexVal = llvm::ConstantInt::get(Int32Ty, Index); + llvm::Value *GEPIndices[] = {Builder.getInt32(0), Builder.getInt32(1), + IndexVal}; + Value *Ptr = + Builder.CreateInBoundsGEP(StructTy, RISCVFeaturesBits, GEPIndices); + Value *FeaturesBit = + Builder.CreateAlignedLoad(Int64Ty, Ptr, CharUnits::fromQuantity(8)); + return FeaturesBit; + }; + + int BitPos = RISCVISAInfo::getRISCVFeaturesBitPosition(FeatureStr); + assert(BitPos != -1 && "validation should have rejected this feature"); + Value *MaskV = Builder.getInt64(1ULL << BitPos); + Value *Bitset = Builder.CreateAnd(LoadFeatureBit(0), MaskV); + return Builder.CreateICmpEQ(Bitset, MaskV); +} + Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E) { if (BuiltinID == Builtin::BI__builtin_cpu_is) @@ -14484,12 +14620,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, // TODO: If we had a "freeze" IR instruction to generate a fixed undef // value, we should use that here instead of a zero. return llvm::Constant::getNullValue(ConvertType(E->getType())); - case X86::BI__builtin_ia32_vec_init_v8qi: - case X86::BI__builtin_ia32_vec_init_v4hi: - case X86::BI__builtin_ia32_vec_init_v2si: - return Builder.CreateBitCast(BuildVector(Ops), - llvm::Type::getX86_MMXTy(getLLVMContext())); - case X86::BI__builtin_ia32_vec_ext_v2si: + case X86::BI__builtin_ia32_vec_ext_v4hi: case X86::BI__builtin_ia32_vec_ext_v16qi: case X86::BI__builtin_ia32_vec_ext_v8hi: case X86::BI__builtin_ia32_vec_ext_v4si: @@ -14507,6 +14638,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, // Otherwise we could just do this in the header file. return Builder.CreateExtractElement(Ops[0], Index); } + case X86::BI__builtin_ia32_vec_set_v4hi: case X86::BI__builtin_ia32_vec_set_v16qi: case X86::BI__builtin_ia32_vec_set_v8hi: case X86::BI__builtin_ia32_vec_set_v4si: @@ -18352,14 +18484,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, return nullptr; switch (BuiltinID) { - case Builtin::BI__builtin_hlsl_elementwise_all: { + case Builtin::BI__builtin_hlsl_all: { Value *Op0 = EmitScalarExpr(E->getArg(0)); return Builder.CreateIntrinsic( /*ReturnType=*/llvm::Type::getInt1Ty(getLLVMContext()), CGM.getHLSLRuntime().getAllIntrinsic(), ArrayRef{Op0}, nullptr, "hlsl.all"); } - case Builtin::BI__builtin_hlsl_elementwise_any: { + case Builtin::BI__builtin_hlsl_any: { Value *Op0 = EmitScalarExpr(E->getArg(0)); return Builder.CreateIntrinsic( /*ReturnType=*/llvm::Type::getInt1Ty(getLLVMContext()), @@ -18433,10 +18565,10 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, if (!E->getArg(0)->getType()->hasFloatingRepresentation()) llvm_unreachable("frac operand must have a float representation"); return Builder.CreateIntrinsic( - /*ReturnType=*/Op0->getType(), Intrinsic::dx_frac, - ArrayRef{Op0}, nullptr, "dx.frac"); - } - case Builtin::BI__builtin_hlsl_elementwise_isinf: { + /*ReturnType=*/Op0->getType(), CGM.getHLSLRuntime().getFracIntrinsic(), + ArrayRef{Op0}, nullptr, "hlsl.frac"); +} +case Builtin::BI__builtin_hlsl_elementwise_isinf: { Value *Op0 = EmitScalarExpr(E->getArg(0)); llvm::Type *Xty = Op0->getType(); llvm::Type *retType = llvm::Type::getInt1Ty(this->getLLVMContext()); @@ -18827,7 +18959,11 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, case AMDGPU::BI__builtin_amdgcn_global_load_tr_b64_i32: case AMDGPU::BI__builtin_amdgcn_global_load_tr_b64_v2i32: case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v4i16: - case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v8i16: { + case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v4f16: + case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v4bf16: + case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v8i16: + case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v8f16: + case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v8bf16: { Intrinsic::ID IID; switch (BuiltinID) { @@ -18836,7 +18972,11 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, IID = Intrinsic::amdgcn_global_load_tr_b64; break; case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v4i16: + case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v4f16: + case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v4bf16: case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v8i16: + case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v8f16: + case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v8bf16: IID = Intrinsic::amdgcn_global_load_tr_b128; break; } @@ -19279,6 +19419,39 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, case AMDGPU::BI__builtin_amdgcn_raw_buffer_store_b128: return emitBuiltinWithOneOverloadedType<5>( *this, E, Intrinsic::amdgcn_raw_ptr_buffer_store); + case AMDGPU::BI__builtin_amdgcn_raw_buffer_load_b8: + case AMDGPU::BI__builtin_amdgcn_raw_buffer_load_b16: + case AMDGPU::BI__builtin_amdgcn_raw_buffer_load_b32: + case AMDGPU::BI__builtin_amdgcn_raw_buffer_load_b64: + case AMDGPU::BI__builtin_amdgcn_raw_buffer_load_b96: + case AMDGPU::BI__builtin_amdgcn_raw_buffer_load_b128: { + llvm::Type *RetTy = nullptr; + switch (BuiltinID) { + case AMDGPU::BI__builtin_amdgcn_raw_buffer_load_b8: + RetTy = Int8Ty; + break; + case AMDGPU::BI__builtin_amdgcn_raw_buffer_load_b16: + RetTy = Int16Ty; + break; + case AMDGPU::BI__builtin_amdgcn_raw_buffer_load_b32: + RetTy = Int32Ty; + break; + case AMDGPU::BI__builtin_amdgcn_raw_buffer_load_b64: + RetTy = llvm::FixedVectorType::get(Int32Ty, /*NumElements=*/2); + break; + case AMDGPU::BI__builtin_amdgcn_raw_buffer_load_b96: + RetTy = llvm::FixedVectorType::get(Int32Ty, /*NumElements=*/3); + break; + case AMDGPU::BI__builtin_amdgcn_raw_buffer_load_b128: + RetTy = llvm::FixedVectorType::get(Int32Ty, /*NumElements=*/4); + break; + } + Function *F = + CGM.getIntrinsic(Intrinsic::amdgcn_raw_ptr_buffer_load, RetTy); + return Builder.CreateCall( + F, {EmitScalarExpr(E->getArg(0)), EmitScalarExpr(E->getArg(1)), + EmitScalarExpr(E->getArg(2)), EmitScalarExpr(E->getArg(3))}); + } default: return nullptr; } @@ -23489,6 +23662,13 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_extract_lane_f16x8); return Builder.CreateCall(Callee, {Vector, Index}); } + case WebAssembly::BI__builtin_wasm_replace_lane_f16x8: { + Value *Vector = EmitScalarExpr(E->getArg(0)); + Value *Index = EmitScalarExpr(E->getArg(1)); + Value *Val = EmitScalarExpr(E->getArg(2)); + Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_replace_lane_f16x8); + return Builder.CreateCall(Callee, {Vector, Index, Val}); + } case WebAssembly::BI__builtin_wasm_table_get: { assert(E->getArg(0)->getType()->isArrayType()); Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this); @@ -24158,6 +24338,12 @@ RValue CodeGenFunction::EmitIntelSYCLAllocaBuiltin( Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, const CallExpr *E, ReturnValueSlot ReturnValue) { + + if (BuiltinID == Builtin::BI__builtin_cpu_supports) + return EmitRISCVCpuSupports(E); + if (BuiltinID == Builtin::BI__builtin_cpu_init) + return EmitRISCVCpuInit(); + SmallVector Ops; llvm::Type *ResultType = ConvertType(E->getType()); diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index c86804f7b072e..70758e6e17ec9 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1345,75 +1345,50 @@ static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty, return CGF.Builder.CreateLoad(Tmp); } -// Function to store a first-class aggregate into memory. We prefer to -// store the elements rather than the aggregate to be more friendly to -// fast-isel. -// FIXME: Do we need to recurse here? -void CodeGenFunction::EmitAggregateStore(llvm::Value *Val, Address Dest, - bool DestIsVolatile) { - // Prefer scalar stores to first-class aggregate stores. - if (llvm::StructType *STy = dyn_cast(Val->getType())) { - for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { - Address EltPtr = Builder.CreateStructGEP(Dest, i); - llvm::Value *Elt = Builder.CreateExtractValue(Val, i); - Builder.CreateStore(Elt, EltPtr, DestIsVolatile); - } - } else { - Builder.CreateStore(Val, Dest, DestIsVolatile); - } -} - -/// CreateCoercedStore - Create a store to \arg DstPtr from \arg Src, -/// where the source and destination may have different types. The -/// destination is known to be aligned to \arg DstAlign bytes. -/// -/// This safely handles the case when the src type is larger than the -/// destination type; the upper bits of the src will be lost. -static void CreateCoercedStore(llvm::Value *Src, - Address Dst, - bool DstIsVolatile, - CodeGenFunction &CGF) { - llvm::Type *SrcTy = Src->getType(); - llvm::Type *DstTy = Dst.getElementType(); - if (SrcTy == DstTy) { - CGF.Builder.CreateStore(Src, Dst, DstIsVolatile); +void CodeGenFunction::CreateCoercedStore(llvm::Value *Src, Address Dst, + llvm::TypeSize DstSize, + bool DstIsVolatile) { + if (!DstSize) return; - } - - llvm::TypeSize SrcSize = CGF.CGM.getDataLayout().getTypeAllocSize(SrcTy); - if (llvm::StructType *DstSTy = dyn_cast(DstTy)) { - Dst = EnterStructPointerForCoercedAccess(Dst, DstSTy, - SrcSize.getFixedValue(), CGF); - DstTy = Dst.getElementType(); - } - - llvm::PointerType *SrcPtrTy = llvm::dyn_cast(SrcTy); - llvm::PointerType *DstPtrTy = llvm::dyn_cast(DstTy); - if (SrcPtrTy && DstPtrTy && - SrcPtrTy->getAddressSpace() != DstPtrTy->getAddressSpace()) { - Src = CGF.Builder.CreateAddrSpaceCast(Src, DstTy); - CGF.Builder.CreateStore(Src, Dst, DstIsVolatile); - return; - } - - // If the source and destination are integer or pointer types, just do an - // extension or truncation to the desired type. - if ((isa(SrcTy) || isa(SrcTy)) && - (isa(DstTy) || isa(DstTy))) { - Src = CoerceIntOrPtrToIntOrPtr(Src, DstTy, CGF); - CGF.Builder.CreateStore(Src, Dst, DstIsVolatile); - return; + llvm::Type *SrcTy = Src->getType(); + llvm::TypeSize SrcSize = CGM.getDataLayout().getTypeAllocSize(SrcTy); + + // GEP into structs to try to make types match. + // FIXME: This isn't really that useful with opaque types, but it impacts a + // lot of regression tests. + if (SrcTy != Dst.getElementType()) { + if (llvm::StructType *DstSTy = + dyn_cast(Dst.getElementType())) { + assert(!SrcSize.isScalable()); + Dst = EnterStructPointerForCoercedAccess(Dst, DstSTy, + SrcSize.getFixedValue(), *this); + } } - llvm::TypeSize DstSize = CGF.CGM.getDataLayout().getTypeAllocSize(DstTy); - - // If store is legal, just bitcast the src pointer. - if (isa(SrcTy) || - isa(DstTy) || - SrcSize.getFixedValue() <= DstSize.getFixedValue()) { - Dst = Dst.withElementType(SrcTy); - CGF.EmitAggregateStore(Src, Dst, DstIsVolatile); + if (SrcSize.isScalable() || SrcSize <= DstSize) { + if (SrcTy->isIntegerTy() && Dst.getElementType()->isPointerTy() && + SrcSize == CGM.getDataLayout().getTypeAllocSize(Dst.getElementType())) { + // If the value is supposed to be a pointer, convert it before storing it. + Src = CoerceIntOrPtrToIntOrPtr(Src, Dst.getElementType(), *this); + Builder.CreateStore(Src, Dst, DstIsVolatile); + } else if (llvm::StructType *STy = + dyn_cast(Src->getType())) { + // Prefer scalar stores to first-class aggregate stores. + Dst = Dst.withElementType(SrcTy); + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + Address EltPtr = Builder.CreateStructGEP(Dst, i); + llvm::Value *Elt = Builder.CreateExtractValue(Src, i); + Builder.CreateStore(Elt, EltPtr, DstIsVolatile); + } + } else { + Builder.CreateStore(Src, Dst.withElementType(SrcTy), DstIsVolatile); + } + } else if (SrcTy->isIntegerTy()) { + // If the source is a simple integer, coerce it directly. + llvm::Type *DstIntTy = Builder.getIntNTy(DstSize.getFixedValue() * 8); + Src = CoerceIntOrPtrToIntOrPtr(Src, DstIntTy, *this); + Builder.CreateStore(Src, Dst.withElementType(DstIntTy), DstIsVolatile); } else { // Otherwise do coercion through memory. This is stupid, but // simple. @@ -1425,12 +1400,12 @@ static void CreateCoercedStore(llvm::Value *Src, // FIXME: Assert that we aren't truncating non-padding bits when have access // to that information. RawAddress Tmp = - CreateTempAllocaForCoercion(CGF, SrcTy, Dst.getAlignment()); - CGF.Builder.CreateStore(Src, Tmp); - CGF.Builder.CreateMemCpy( - Dst.emitRawPointer(CGF), Dst.getAlignment().getAsAlign(), - Tmp.getPointer(), Tmp.getAlignment().getAsAlign(), - llvm::ConstantInt::get(CGF.IntPtrTy, DstSize.getFixedValue())); + CreateTempAllocaForCoercion(*this, SrcTy, Dst.getAlignment()); + Builder.CreateStore(Src, Tmp); + Builder.CreateMemCpy(Dst.emitRawPointer(*this), + Dst.getAlignment().getAsAlign(), Tmp.getPointer(), + Tmp.getAlignment().getAsAlign(), + Builder.CreateTypeSize(IntPtrTy, DstSize)); } } @@ -2088,6 +2063,9 @@ static void getTrivialDefaultFunctionAttributes( FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); } + if (CodeGenOpts.SaveRegParams && !AttrOnCallSite) + FuncAttrs.addAttribute("save-reg-params"); + for (StringRef Attr : CodeGenOpts.DefaultFunctionAttrs) { StringRef Var, Value; std::tie(Var, Value) = Attr.split('='); @@ -2582,6 +2560,9 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, } } } + // Remove 'convergent' if requested. + if (TargetDecl->hasAttr()) + FuncAttrs.removeAttribute(llvm::Attribute::Convergent); } // Add "sample-profile-suffix-elision-policy" attribute for internal linkage @@ -3391,7 +3372,12 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, assert(NumIRArgs == 1); auto AI = Fn->getArg(FirstIRArg); AI->setName(Arg->getName() + ".coerce"); - CreateCoercedStore(AI, Ptr, /*DstIsVolatile=*/false, *this); + CreateCoercedStore( + AI, Ptr, + llvm::TypeSize::getFixed( + getContext().getTypeSizeInChars(Ty).getQuantity() - + ArgI.getDirectOffset()), + /*DstIsVolatile=*/false); } // Match to what EmitParmDecl is expecting for this type. @@ -5115,7 +5101,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, ReturnValueSlot ReturnValue, const CallArgList &CallArgs, llvm::CallBase **callOrInvoke, bool IsMustTail, - SourceLocation Loc) { + SourceLocation Loc, + bool IsVirtualFunctionPointerThunk) { // FIXME: We no longer need the types from CallArgs; lift up and simplify. assert(Callee.isOrdinary() || Callee.isVirtual()); @@ -5179,7 +5166,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, RawAddress SRetAlloca = RawAddress::invalid(); llvm::Value *UnusedReturnSizePtr = nullptr; if (RetAI.isIndirect() || RetAI.isInAlloca() || RetAI.isCoerceAndExpand()) { - if (!ReturnValue.isNull()) { + if (IsVirtualFunctionPointerThunk && RetAI.isIndirect()) { + SRetPtr = makeNaturalAddressForPointer(CurFn->arg_begin() + + IRFunctionArgs.getSRetArgNo(), + RetTy, CharUnits::fromQuantity(1)); + } else if (!ReturnValue.isNull()) { SRetPtr = ReturnValue.getAddress(); } else { SRetPtr = CreateMemTemp(RetTy, "tmp", &SRetAlloca); @@ -5715,6 +5706,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::AlwaysInline); + // Remove call-site convergent attribute if requested. + if (InNoConvergentAttributedStmt) + Attrs = + Attrs.removeFnAttribute(getLLVMContext(), llvm::Attribute::Convergent); + // Apply some call-site-specific attributes. // TODO: work this into building the attribute set. @@ -5992,119 +5988,127 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, CallArgs.freeArgumentMemory(*this); // Extract the return value. - RValue Ret = [&] { - switch (RetAI.getKind()) { - case ABIArgInfo::CoerceAndExpand: { - auto coercionType = RetAI.getCoerceAndExpandType(); + RValue Ret; - Address addr = SRetPtr.withElementType(coercionType); - - assert(CI->getType() == RetAI.getUnpaddedCoerceAndExpandType()); - bool requiresExtract = isa(CI->getType()); - - unsigned unpaddedIndex = 0; - for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) { - llvm::Type *eltType = coercionType->getElementType(i); - if (ABIArgInfo::isPaddingForCoerceAndExpand(eltType)) continue; - Address eltAddr = Builder.CreateStructGEP(addr, i); - llvm::Value *elt = CI; - if (requiresExtract) - elt = Builder.CreateExtractValue(elt, unpaddedIndex++); - else - assert(unpaddedIndex == 0); - Builder.CreateStore(elt, eltAddr); + // If the current function is a virtual function pointer thunk, avoid copying + // the return value of the musttail call to a temporary. + if (IsVirtualFunctionPointerThunk) { + Ret = RValue::get(CI); + } else { + Ret = [&] { + switch (RetAI.getKind()) { + case ABIArgInfo::CoerceAndExpand: { + auto coercionType = RetAI.getCoerceAndExpandType(); + + Address addr = SRetPtr.withElementType(coercionType); + + assert(CI->getType() == RetAI.getUnpaddedCoerceAndExpandType()); + bool requiresExtract = isa(CI->getType()); + + unsigned unpaddedIndex = 0; + for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) { + llvm::Type *eltType = coercionType->getElementType(i); + if (ABIArgInfo::isPaddingForCoerceAndExpand(eltType)) + continue; + Address eltAddr = Builder.CreateStructGEP(addr, i); + llvm::Value *elt = CI; + if (requiresExtract) + elt = Builder.CreateExtractValue(elt, unpaddedIndex++); + else + assert(unpaddedIndex == 0); + Builder.CreateStore(elt, eltAddr); + } + [[fallthrough]]; } - [[fallthrough]]; - } - - case ABIArgInfo::InAlloca: - case ABIArgInfo::Indirect: { - RValue ret = convertTempToRValue(SRetPtr, RetTy, SourceLocation()); - if (UnusedReturnSizePtr) - PopCleanupBlock(); - return ret; - } - - case ABIArgInfo::Ignore: - // If we are ignoring an argument that had a result, make sure to - // construct the appropriate return value for our caller. - return GetUndefRValue(RetTy); - case ABIArgInfo::Extend: - case ABIArgInfo::Direct: { - llvm::Type *RetIRTy = ConvertType(RetTy); - if (RetAI.getCoerceToType() == RetIRTy && RetAI.getDirectOffset() == 0) { - switch (getEvaluationKind(RetTy)) { - case TEK_Complex: { - llvm::Value *Real = Builder.CreateExtractValue(CI, 0); - llvm::Value *Imag = Builder.CreateExtractValue(CI, 1); - return RValue::getComplex(std::make_pair(Real, Imag)); - } - case TEK_Aggregate: { - Address DestPtr = ReturnValue.getAddress(); - bool DestIsVolatile = ReturnValue.isVolatile(); + case ABIArgInfo::InAlloca: + case ABIArgInfo::Indirect: { + RValue ret = convertTempToRValue(SRetPtr, RetTy, SourceLocation()); + if (UnusedReturnSizePtr) + PopCleanupBlock(); + return ret; + } - if (!DestPtr.isValid()) { - DestPtr = CreateMemTemp(RetTy, "agg.tmp"); - DestIsVolatile = false; + case ABIArgInfo::Ignore: + // If we are ignoring an argument that had a result, make sure to + // construct the appropriate return value for our caller. + return GetUndefRValue(RetTy); + + case ABIArgInfo::Extend: + case ABIArgInfo::Direct: { + llvm::Type *RetIRTy = ConvertType(RetTy); + if (RetAI.getCoerceToType() == RetIRTy && + RetAI.getDirectOffset() == 0) { + switch (getEvaluationKind(RetTy)) { + case TEK_Complex: { + llvm::Value *Real = Builder.CreateExtractValue(CI, 0); + llvm::Value *Imag = Builder.CreateExtractValue(CI, 1); + return RValue::getComplex(std::make_pair(Real, Imag)); + } + case TEK_Aggregate: + break; + case TEK_Scalar: { + // If the argument doesn't match, perform a bitcast to coerce it. + // This can happen due to trivial type mismatches. + llvm::Value *V = CI; + if (V->getType() != RetIRTy) + V = Builder.CreateBitCast(V, RetIRTy); + return RValue::get(V); + } } - EmitAggregateStore(CI, DestPtr, DestIsVolatile); - return RValue::getAggregate(DestPtr); } - case TEK_Scalar: { - // If the argument doesn't match, perform a bitcast to coerce it. This - // can happen due to trivial type mismatches. + + // If coercing a fixed vector from a scalable vector for ABI + // compatibility, and the types match, use the llvm.vector.extract + // intrinsic to perform the conversion. + if (auto *FixedDstTy = dyn_cast(RetIRTy)) { llvm::Value *V = CI; - if (V->getType() != RetIRTy) - V = Builder.CreateBitCast(V, RetIRTy); - return RValue::get(V); - } + if (auto *ScalableSrcTy = + dyn_cast(V->getType())) { + if (FixedDstTy->getElementType() == + ScalableSrcTy->getElementType()) { + llvm::Value *Zero = llvm::Constant::getNullValue(CGM.Int64Ty); + V = Builder.CreateExtractVector(FixedDstTy, V, Zero, + "cast.fixed"); + return RValue::get(V); + } + } } - llvm_unreachable("bad evaluation kind"); - } - // If coercing a fixed vector from a scalable vector for ABI - // compatibility, and the types match, use the llvm.vector.extract - // intrinsic to perform the conversion. - if (auto *FixedDstTy = dyn_cast(RetIRTy)) { - llvm::Value *V = CI; - if (auto *ScalableSrcTy = - dyn_cast(V->getType())) { - if (FixedDstTy->getElementType() == ScalableSrcTy->getElementType()) { - llvm::Value *Zero = llvm::Constant::getNullValue(CGM.Int64Ty); - V = Builder.CreateExtractVector(FixedDstTy, V, Zero, "cast.fixed"); - return RValue::get(V); - } + Address DestPtr = ReturnValue.getValue(); + bool DestIsVolatile = ReturnValue.isVolatile(); + uint64_t DestSize = + getContext().getTypeInfoDataSizeInChars(RetTy).Width.getQuantity(); + + if (!DestPtr.isValid()) { + DestPtr = CreateMemTemp(RetTy, "coerce"); + DestIsVolatile = false; + DestSize = getContext().getTypeSizeInChars(RetTy).getQuantity(); } - } - Address DestPtr = ReturnValue.getValue(); - bool DestIsVolatile = ReturnValue.isVolatile(); + // An empty record can overlap other data (if declared with + // no_unique_address); omit the store for such types - as there is no + // actual data to store. + if (!isEmptyRecord(getContext(), RetTy, true)) { + // If the value is offset in memory, apply the offset now. + Address StorePtr = emitAddressAtOffset(*this, DestPtr, RetAI); + CreateCoercedStore( + CI, StorePtr, + llvm::TypeSize::getFixed(DestSize - RetAI.getDirectOffset()), + DestIsVolatile); + } - if (!DestPtr.isValid()) { - DestPtr = CreateMemTemp(RetTy, "coerce"); - DestIsVolatile = false; + return convertTempToRValue(DestPtr, RetTy, SourceLocation()); } - // An empty record can overlap other data (if declared with - // no_unique_address); omit the store for such types - as there is no - // actual data to store. - if (!isEmptyRecord(getContext(), RetTy, true)) { - // If the value is offset in memory, apply the offset now. - Address StorePtr = emitAddressAtOffset(*this, DestPtr, RetAI); - CreateCoercedStore(CI, StorePtr, DestIsVolatile, *this); + case ABIArgInfo::Expand: + case ABIArgInfo::IndirectAliased: + llvm_unreachable("Invalid ABI kind for return argument"); } - return convertTempToRValue(DestPtr, RetTy, SourceLocation()); - } - - case ABIArgInfo::Expand: - case ABIArgInfo::IndirectAliased: - llvm_unreachable("Invalid ABI kind for return argument"); - } - - llvm_unreachable("Unhandled ABIArgInfo::Kind"); - } (); + llvm_unreachable("Unhandled ABIArgInfo::Kind"); + }(); + } // Emit the assume_aligned check on the return value. if (Ret.isScalar() && TargetDecl) { diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 4c8a95fbb105f..c5fd90fd2487c 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1996,7 +1996,12 @@ CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method, if (Method->isStatic()) return cast_or_null( getOrCreateType(QualType(Func, 0), Unit)); - return getOrCreateInstanceMethodType(Method->getThisType(), Func, Unit); + + QualType ThisType; + if (!Method->hasCXXExplicitFunctionObjectParameter()) + ThisType = Method->getThisType(); + + return getOrCreateInstanceMethodType(ThisType, Func, Unit); } llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType( @@ -2028,27 +2033,31 @@ llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType( Elts.push_back(Args[0]); // "this" pointer is always first argument. - const CXXRecordDecl *RD = ThisPtr->getPointeeCXXRecordDecl(); - if (isa(RD)) { - // Create pointer type directly in this case. - const PointerType *ThisPtrTy = cast(ThisPtr); - uint64_t Size = CGM.getContext().getTypeSize(ThisPtrTy); - auto Align = getTypeAlignIfRequired(ThisPtrTy, CGM.getContext()); - llvm::DIType *PointeeType = - getOrCreateType(ThisPtrTy->getPointeeType(), Unit); - llvm::DIType *ThisPtrType = - DBuilder.createPointerType(PointeeType, Size, Align); - TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType); - // TODO: This and the artificial type below are misleading, the - // types aren't artificial the argument is, but the current - // metadata doesn't represent that. - ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType); - Elts.push_back(ThisPtrType); - } else { - llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit); - TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType); - ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType); - Elts.push_back(ThisPtrType); + // ThisPtr may be null if the member function has an explicit 'this' + // parameter. + if (!ThisPtr.isNull()) { + const CXXRecordDecl *RD = ThisPtr->getPointeeCXXRecordDecl(); + if (isa(RD)) { + // Create pointer type directly in this case. + const PointerType *ThisPtrTy = cast(ThisPtr); + uint64_t Size = CGM.getContext().getTypeSize(ThisPtrTy); + auto Align = getTypeAlignIfRequired(ThisPtrTy, CGM.getContext()); + llvm::DIType *PointeeType = + getOrCreateType(ThisPtrTy->getPointeeType(), Unit); + llvm::DIType *ThisPtrType = + DBuilder.createPointerType(PointeeType, Size, Align); + TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType); + // TODO: This and the artificial type below are misleading, the + // types aren't artificial the argument is, but the current + // metadata doesn't represent that. + ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType); + Elts.push_back(ThisPtrType); + } else { + llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit); + TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType); + ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType); + Elts.push_back(ThisPtrType); + } } // Copy rest of the arguments. diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index f1681ffa4c606..1d5be8451d050 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -2845,7 +2845,7 @@ void CodeGenModule::EmitOMPRequiresDecl(const OMPRequiresDecl *D) { } void CodeGenModule::EmitOMPAllocateDecl(const OMPAllocateDecl *D) { - for (const Expr *E : D->varlists()) { + for (const Expr *E : D->varlist()) { const auto *DE = cast(E); const auto *VD = cast(DE->getDecl()); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index cced2ceafe7b8..e7fc9be54874b 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1068,28 +1068,31 @@ class StructAccessBase } // end anonymous namespace -using RecIndicesTy = - SmallVector, 8>; +using RecIndicesTy = SmallVector; static bool getGEPIndicesToField(CodeGenFunction &CGF, const RecordDecl *RD, - const FieldDecl *FD, RecIndicesTy &Indices) { + const FieldDecl *Field, + RecIndicesTy &Indices) { const CGRecordLayout &Layout = CGF.CGM.getTypes().getCGRecordLayout(RD); int64_t FieldNo = -1; - for (const Decl *D : RD->decls()) { - if (const auto *Field = dyn_cast(D)) { - FieldNo = Layout.getLLVMFieldNo(Field); - if (FD == Field) { - Indices.emplace_back(std::make_pair(RD, CGF.Builder.getInt32(FieldNo))); - return true; - } + for (const FieldDecl *FD : RD->fields()) { + if (!Layout.containsFieldDecl(FD)) + // This could happen if the field has a struct type that's empty. I don't + // know why either. + continue; + + FieldNo = Layout.getLLVMFieldNo(FD); + if (FD == Field) { + Indices.emplace_back(CGF.Builder.getInt32(FieldNo)); + return true; } - if (const auto *Record = dyn_cast(D)) { - ++FieldNo; - if (getGEPIndicesToField(CGF, Record, FD, Indices)) { + QualType Ty = FD->getType(); + if (Ty->isRecordType()) { + if (getGEPIndicesToField(CGF, Ty->getAsRecordDecl(), Field, Indices)) { if (RD->isUnion()) FieldNo = 0; - Indices.emplace_back(std::make_pair(RD, CGF.Builder.getInt32(FieldNo))); + Indices.emplace_back(CGF.Builder.getInt32(FieldNo)); return true; } } @@ -1106,7 +1109,7 @@ static bool getGEPIndicesToField(CodeGenFunction &CGF, const RecordDecl *RD, /// - \p FAMDecl: the \p Decl for the flexible array member. It may not be /// within the top-level struct. /// - \p CountDecl: must be within the same non-anonymous struct as \p FAMDecl. -llvm::Value *CodeGenFunction::EmitCountedByFieldExpr( +llvm::Value *CodeGenFunction::EmitLoadOfCountedByField( const Expr *Base, const FieldDecl *FAMDecl, const FieldDecl *CountDecl) { const RecordDecl *RD = CountDecl->getParent()->getOuterLexicalRecordContext(); @@ -1133,15 +1136,15 @@ llvm::Value *CodeGenFunction::EmitCountedByFieldExpr( return nullptr; } - llvm::Value *Zero = Builder.getInt32(0); RecIndicesTy Indices; - getGEPIndicesToField(*this, RD, CountDecl, Indices); + if (Indices.empty()) + return nullptr; - for (auto I = Indices.rbegin(), E = Indices.rend(); I != E; ++I) - Res = Builder.CreateInBoundsGEP( - ConvertType(QualType(I->first->getTypeForDecl(), 0)), Res, - {Zero, I->second}, "..counted_by.gep"); + Indices.push_back(Builder.getInt32(0)); + Res = Builder.CreateInBoundsGEP( + ConvertType(QualType(RD->getTypeForDecl(), 0)), Res, + RecIndicesTy(llvm::reverse(Indices)), "..counted_by.gep"); return Builder.CreateAlignedLoad(ConvertType(CountDecl->getType()), Res, getIntAlign(), "..counted_by.load"); @@ -1313,7 +1316,8 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo, if (CE->getCastKind() == CK_AddressSpaceConversion) Addr = CGF.Builder.CreateAddrSpaceCast( Addr, CGF.ConvertType(E->getType()), ElemTy); - return Addr; + return CGF.authPointerToPointerCast(Addr, CE->getSubExpr()->getType(), + CE->getType()); } break; @@ -3887,6 +3891,8 @@ llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) { TrapCall->addFnAttr(A); } + if (InNoMergeAttributedStmt) + TrapCall->addFnAttr(llvm::Attribute::NoMerge); return TrapCall; } @@ -4124,25 +4130,25 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr, /// The offset of a field from the beginning of the record. static bool getFieldOffsetInBits(CodeGenFunction &CGF, const RecordDecl *RD, - const FieldDecl *FD, int64_t &Offset) { + const FieldDecl *Field, int64_t &Offset) { ASTContext &Ctx = CGF.getContext(); const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); unsigned FieldNo = 0; - for (const Decl *D : RD->decls()) { - if (const auto *Record = dyn_cast(D)) - if (getFieldOffsetInBits(CGF, Record, FD, Offset)) { - Offset += Layout.getFieldOffset(FieldNo); - return true; - } + for (const FieldDecl *FD : RD->fields()) { + if (FD == Field) { + Offset += Layout.getFieldOffset(FieldNo); + return true; + } - if (const auto *Field = dyn_cast(D)) - if (FD == Field) { + QualType Ty = FD->getType(); + if (Ty->isRecordType()) + if (getFieldOffsetInBits(CGF, Ty->getAsRecordDecl(), Field, Offset)) { Offset += Layout.getFieldOffset(FieldNo); return true; } - if (isa(D)) + if (!RD->isUnion()) ++FieldNo; } @@ -5884,6 +5890,15 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee CGM.getLLVMContext(), {PrefixSigType, Int32Ty}, /*isPacked=*/true); llvm::Value *CalleePtr = Callee.getFunctionPointer(); + if (CGM.getCodeGenOpts().PointerAuth.FunctionPointers) { + // Use raw pointer since we are using the callee pointer as data here. + Address Addr = + Address(CalleePtr, CalleePtr->getType(), + CharUnits::fromQuantity( + CalleePtr->getPointerAlignment(CGM.getDataLayout())), + Callee.getPointerAuthInfo(), nullptr); + CalleePtr = Addr.emitRawPointer(*this); + } // On 32-bit Arm, the low bit of a function pointer indicates whether // it's using the Arm or Thumb instruction set. The actual first diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index e50d3c5bd9951..d9f44f4be617e 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -131,14 +131,12 @@ class AggExprEmitter : public StmtVisitor { EnsureDest(E->getType()); if (llvm::Value *Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) { - Address StoreDest = Dest.getAddress(); - // The emitted value is guaranteed to have the same size as the - // destination but can have a different type. Just do a bitcast in this - // case to avoid incorrect GEPs. - if (Result->getType() != StoreDest.getType()) - StoreDest = StoreDest.withElementType(Result->getType()); - CGF.EmitAggregateStore(Result, StoreDest, - E->getType().isVolatileQualified()); + CGF.CreateCoercedStore( + Result, Dest.getAddress(), + llvm::TypeSize::getFixed( + Dest.getPreferredSize(CGF.getContext(), E->getType()) + .getQuantity()), + E->getType().isVolatileQualified()); return; } return Visit(E->getSubExpr()); @@ -2049,6 +2047,10 @@ CodeGenFunction::getOverlapForFieldInit(const FieldDecl *FD) { if (!FD->hasAttr() || !FD->getType()->isRecordType()) return AggValueSlot::DoesNotOverlap; + // Empty fields can overlap earlier fields. + if (FD->getType()->getAsCXXRecordDecl()->isEmpty()) + return AggValueSlot::MayOverlap; + // If the field lies entirely within the enclosing class's nvsize, its tail // padding cannot overlap any already-initialized object. (The only subobjects // with greater addresses that might already be initialized are vbases.) @@ -2071,6 +2073,10 @@ AggValueSlot::Overlap_t CodeGenFunction::getOverlapForBaseInit( if (IsVirtual) return AggValueSlot::MayOverlap; + // Empty bases can overlap earlier bases. + if (BaseRD->isEmpty()) + return AggValueSlot::MayOverlap; + // If the base class is laid out entirely within the nvsize of the derived // class, its tail padding cannot yet be initialized, so we can issue // stores at the full width of the base class. diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 4d45f6d64c1cd..828a09856099a 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -649,7 +649,6 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op, ComplexPairTy ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *E, QualType PromotionType) { - E->hasStoredFPFeatures(); QualType promotionTy = PromotionType.isNull() ? getPromotionType(E->getStoredFPFeaturesOrDefault(), diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 7c65fccb60855..f22321f0e738a 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -814,8 +814,7 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD, llvm::Constant *VTableAddressPoint = CGM.getCXXABI().getVTableAddressPoint(BaseSubobject(CD, Offset), VTableClass); - if (auto Authentication = - CGM.getVTablePointerAuthentication(VTableClass)) { + if (auto Authentication = CGM.getVTablePointerAuthentication(CD)) { VTableAddressPoint = Emitter.tryEmitConstantSignedPointer( VTableAddressPoint, *Authentication); if (!VTableAddressPoint) diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index e29d9b1f0b0e1..ef1f849814d45 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -2400,7 +2400,9 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo()); return EmitLoadOfLValue(DestLV, CE->getExprLoc()); } - return Builder.CreateBitCast(Src, DstTy); + + llvm::Value *Result = Builder.CreateBitCast(Src, DstTy); + return CGF.authPointerToPointerCast(Result, E->getType(), DestTy); } case CK_AddressSpaceConversion: { Expr::EvalResult Result; @@ -2550,6 +2552,8 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { if (DestTy.mayBeDynamicClass()) IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr); } + + IntToPtr = CGF.authPointerToPointerCast(IntToPtr, E->getType(), DestTy); return IntToPtr; } case CK_PointerToIntegral: { @@ -2565,6 +2569,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr); } + PtrExpr = CGF.authPointerToPointerCast(PtrExpr, E->getType(), DestTy); return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy)); } case CK_ToVoid: { @@ -2862,9 +2867,10 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub; llvm::Value *amt = llvm::ConstantFP::get( VMContext, llvm::APFloat(static_cast(1.0))); - llvm::Value *old = - Builder.CreateAtomicRMW(aop, LV.getAddress(), amt, - llvm::AtomicOrdering::SequentiallyConsistent); + llvm::AtomicRMWInst *old = + CGF.emitAtomicRMWInst(aop, LV.getAddress(), amt, + llvm::AtomicOrdering::SequentiallyConsistent); + return isPre ? Builder.CreateBinOp(op, old, amt) : old; } value = EmitLoadOfLValue(LV, E->getExprLoc()); @@ -3604,9 +3610,9 @@ LValue ScalarExprEmitter::EmitCompoundAssignLValue( EmitScalarConversion(OpInfo.RHS, E->getRHS()->getType(), LHSTy, E->getExprLoc()), LHSTy); - Value *OldVal = Builder.CreateAtomicRMW( - AtomicOp, LHSLV.getAddress(), Amt, - llvm::AtomicOrdering::SequentiallyConsistent); + + llvm::AtomicRMWInst *OldVal = + CGF.emitAtomicRMWInst(AtomicOp, LHSLV.getAddress(), Amt); // Since operation is atomic, the result type is guaranteed to be the // same as the input in LLVM terms. diff --git a/clang/lib/CodeGen/CGGPUBuiltin.cpp b/clang/lib/CodeGen/CGGPUBuiltin.cpp index 1937622618b6f..eb1cdacfd46a7 100644 --- a/clang/lib/CodeGen/CGGPUBuiltin.cpp +++ b/clang/lib/CodeGen/CGGPUBuiltin.cpp @@ -42,28 +42,6 @@ llvm::Function *GetVprintfDeclaration(llvm::Module &M) { VprintfFuncType, llvm::GlobalVariable::ExternalLinkage, "vprintf", &M); } -llvm::Function *GetOpenMPVprintfDeclaration(CodeGenModule &CGM) { - const char *Name = "__llvm_omp_vprintf"; - llvm::Module &M = CGM.getModule(); - llvm::Type *ArgTypes[] = {llvm::PointerType::getUnqual(M.getContext()), - llvm::PointerType::getUnqual(M.getContext()), - llvm::Type::getInt32Ty(M.getContext())}; - llvm::FunctionType *VprintfFuncType = llvm::FunctionType::get( - llvm::Type::getInt32Ty(M.getContext()), ArgTypes, false); - - if (auto *F = M.getFunction(Name)) { - if (F->getFunctionType() != VprintfFuncType) { - CGM.Error(SourceLocation(), - "Invalid type declaration for __llvm_omp_vprintf"); - return nullptr; - } - return F; - } - - return llvm::Function::Create( - VprintfFuncType, llvm::GlobalVariable::ExternalLinkage, Name, &M); -} - // Transforms a call to printf into a call to the NVPTX vprintf syscall (which // isn't particularly special; it's invoked just like a regular function). // vprintf takes two args: A format string, and a pointer to a buffer containing @@ -221,10 +199,3 @@ RValue CodeGenFunction::EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E) { Builder.SetInsertPoint(IRB.GetInsertBlock(), IRB.GetInsertPoint()); return RValue::get(Printf); } - -RValue CodeGenFunction::EmitOpenMPDevicePrintfCallExpr(const CallExpr *E) { - assert(getTarget().getTriple().isNVPTX() || - getTarget().getTriple().isAMDGCN()); - return EmitDevicePrintfCallExpr(E, this, GetOpenMPVprintfDeclaration(CGM), - true); -} diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index 4036ce711bea1..8c067f4963955 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -74,6 +74,7 @@ class CGHLSLRuntime { GENERATE_HLSL_INTRINSIC_FUNCTION(All, all) GENERATE_HLSL_INTRINSIC_FUNCTION(Any, any) + GENERATE_HLSL_INTRINSIC_FUNCTION(Frac, frac) GENERATE_HLSL_INTRINSIC_FUNCTION(Lerp, lerp) GENERATE_HLSL_INTRINSIC_FUNCTION(Rsqrt, rsqrt) GENERATE_HLSL_INTRINSIC_FUNCTION(ThreadId, thread_id) diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 9e0cf1ba8fb44..a5fd660d77ac9 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -3861,7 +3861,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, HasIterator = true; continue; } - for (const Expr *E : C->varlists()) { + for (const Expr *E : C->varlist()) { llvm::Value *Addr; llvm::Value *Size; std::tie(Addr, Size) = getPointerAndSize(CGF, E); @@ -3894,7 +3894,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, continue; OMPIteratorGeneratorScope IteratorScope( CGF, cast_or_null(Modifier->IgnoreParenImpCasts())); - for (const Expr *E : C->varlists()) { + for (const Expr *E : C->varlist()) { llvm::Value *Addr; llvm::Value *Size; std::tie(Addr, Size) = getPointerAndSize(CGF, E); @@ -6049,11 +6049,6 @@ const Expr *CGOpenMPRuntime::getNumTeamsExprForTargetDirective( MinTeamsVal = MaxTeamsVal = 0; return nullptr; } - if (isOpenMPParallelDirective(NestedDir->getDirectiveKind()) || - isOpenMPSimdDirective(NestedDir->getDirectiveKind())) { - MinTeamsVal = MaxTeamsVal = 1; - return nullptr; - } MinTeamsVal = MaxTeamsVal = 1; return nullptr; } @@ -8194,7 +8189,7 @@ class MappableExprsHandler { : CurDir(&Dir), CGF(CGF) { // Extract firstprivate clause information. for (const auto *C : Dir.getClausesOfKind()) - for (const auto *D : C->varlists()) + for (const auto *D : C->varlist()) FirstPrivateDecls.try_emplace( cast(cast(D)->getDecl()), C->isImplicit()); // Extract implicit firstprivates from uses_allocators clauses. @@ -8874,36 +8869,21 @@ emitMappingInformation(CodeGenFunction &CGF, llvm::OpenMPIRBuilder &OMPBuilder, PLoc.getLine(), PLoc.getColumn(), SrcLocStrSize); } - /// Emit the arrays used to pass the captures and map information to the /// offloading runtime library. If there is no map or capture information, /// return nullptr by reference. -static void emitOffloadingArrays( +static void emitOffloadingArraysAndArgs( CodeGenFunction &CGF, MappableExprsHandler::MapCombinedInfoTy &CombinedInfo, CGOpenMPRuntime::TargetDataInfo &Info, llvm::OpenMPIRBuilder &OMPBuilder, - bool IsNonContiguous = false) { + bool IsNonContiguous = false, bool ForEndCall = false) { CodeGenModule &CGM = CGF.CGM; - // Reset the array information. - Info.clearArrayInfo(); - Info.NumberOfPtrs = CombinedInfo.BasePointers.size(); - using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; InsertPointTy AllocaIP(CGF.AllocaInsertPt->getParent(), CGF.AllocaInsertPt->getIterator()); InsertPointTy CodeGenIP(CGF.Builder.GetInsertBlock(), CGF.Builder.GetInsertPoint()); - auto FillInfoMap = [&](MappableExprsHandler::MappingExprInfo &MapExpr) { - return emitMappingInformation(CGF, OMPBuilder, MapExpr); - }; - if (CGM.getCodeGenOpts().getDebugInfo() != - llvm::codegenoptions::NoDebugInfo) { - CombinedInfo.Names.resize(CombinedInfo.Exprs.size()); - llvm::transform(CombinedInfo.Exprs, CombinedInfo.Names.begin(), - FillInfoMap); - } - auto DeviceAddrCB = [&](unsigned int I, llvm::Value *NewDecl) { if (const ValueDecl *DevVD = CombinedInfo.DevicePtrDecls[I]) { Info.CaptureDeviceAddrMap.try_emplace(DevVD, NewDecl); @@ -8914,14 +8894,14 @@ static void emitOffloadingArrays( llvm::Value *MFunc = nullptr; if (CombinedInfo.Mappers[I]) { Info.HasMapper = true; - MFunc = CGF.CGM.getOpenMPRuntime().getOrCreateUserDefinedMapperFunc( + MFunc = CGM.getOpenMPRuntime().getOrCreateUserDefinedMapperFunc( cast(CombinedInfo.Mappers[I])); } return MFunc; }; - OMPBuilder.emitOffloadingArrays(AllocaIP, CodeGenIP, CombinedInfo, Info, - /*IsNonContiguous=*/true, DeviceAddrCB, - CustomMapperCB); + OMPBuilder.emitOffloadingArraysAndArgs( + AllocaIP, CodeGenIP, Info, Info.RTArgs, CombinedInfo, IsNonContiguous, + ForEndCall, DeviceAddrCB, CustomMapperCB); } /// Check for inner distribute directive. @@ -9486,29 +9466,14 @@ llvm::Value *emitDynCGGroupMem(const OMPExecutableDirective &D, } return DynCGroupMem; } +static void genMapInfoForCaptures( + MappableExprsHandler &MEHandler, CodeGenFunction &CGF, + const CapturedStmt &CS, llvm::SmallVectorImpl &CapturedVars, + llvm::OpenMPIRBuilder &OMPBuilder, + llvm::DenseSet> &MappedVarSet, + MappableExprsHandler::MapCombinedInfoTy &CombinedInfo) { -static void emitTargetCallKernelLaunch( - CGOpenMPRuntime *OMPRuntime, llvm::Function *OutlinedFn, - const OMPExecutableDirective &D, - llvm::SmallVectorImpl &CapturedVars, bool RequiresOuterTask, - const CapturedStmt &CS, bool OffloadingMandatory, - llvm::PointerIntPair Device, - llvm::Value *OutlinedFnID, CodeGenFunction::OMPTargetDataInfo &InputInfo, - llvm::Value *&MapTypesArray, llvm::Value *&MapNamesArray, - llvm::function_ref - SizeEmitter, - CodeGenFunction &CGF, CodeGenModule &CGM) { - llvm::OpenMPIRBuilder &OMPBuilder = OMPRuntime->getOMPBuilder(); - - // Fill up the arrays with all the captured variables. - MappableExprsHandler::MapCombinedInfoTy CombinedInfo; - - // Get mappable expression information. - MappableExprsHandler MEHandler(D, CGF); llvm::DenseMap LambdaPointers; - llvm::DenseSet> MappedVarSet; - auto RI = CS.getCapturedRecordDecl()->field_begin(); auto *CV = CapturedVars.begin(); for (CapturedStmt::const_capture_iterator CI = CS.capture_begin(), @@ -9575,18 +9540,64 @@ static void emitTargetCallKernelLaunch( MEHandler.adjustMemberOfForLambdaCaptures( OMPBuilder, LambdaPointers, CombinedInfo.BasePointers, CombinedInfo.Pointers, CombinedInfo.Types); +} +static void +genMapInfo(MappableExprsHandler &MEHandler, CodeGenFunction &CGF, + MappableExprsHandler::MapCombinedInfoTy &CombinedInfo, + llvm::OpenMPIRBuilder &OMPBuilder, + const llvm::DenseSet> &SkippedVarSet = + llvm::DenseSet>()) { + + CodeGenModule &CGM = CGF.CGM; // Map any list items in a map clause that were not captures because they // weren't referenced within the construct. - MEHandler.generateAllInfo(CombinedInfo, OMPBuilder, MappedVarSet); + MEHandler.generateAllInfo(CombinedInfo, OMPBuilder, SkippedVarSet); + auto FillInfoMap = [&](MappableExprsHandler::MappingExprInfo &MapExpr) { + return emitMappingInformation(CGF, OMPBuilder, MapExpr); + }; + if (CGM.getCodeGenOpts().getDebugInfo() != + llvm::codegenoptions::NoDebugInfo) { + CombinedInfo.Names.resize(CombinedInfo.Exprs.size()); + llvm::transform(CombinedInfo.Exprs, CombinedInfo.Names.begin(), + FillInfoMap); + } +} + +static void genMapInfo(const OMPExecutableDirective &D, CodeGenFunction &CGF, + const CapturedStmt &CS, + llvm::SmallVectorImpl &CapturedVars, + llvm::OpenMPIRBuilder &OMPBuilder, + MappableExprsHandler::MapCombinedInfoTy &CombinedInfo) { + // Get mappable expression information. + MappableExprsHandler MEHandler(D, CGF); + llvm::DenseSet> MappedVarSet; + + genMapInfoForCaptures(MEHandler, CGF, CS, CapturedVars, OMPBuilder, + MappedVarSet, CombinedInfo); + genMapInfo(MEHandler, CGF, CombinedInfo, OMPBuilder, MappedVarSet); +} +static void emitTargetCallKernelLaunch( + CGOpenMPRuntime *OMPRuntime, llvm::Function *OutlinedFn, + const OMPExecutableDirective &D, + llvm::SmallVectorImpl &CapturedVars, bool RequiresOuterTask, + const CapturedStmt &CS, bool OffloadingMandatory, + llvm::PointerIntPair Device, + llvm::Value *OutlinedFnID, CodeGenFunction::OMPTargetDataInfo &InputInfo, + llvm::Value *&MapTypesArray, llvm::Value *&MapNamesArray, + llvm::function_ref + SizeEmitter, + CodeGenFunction &CGF, CodeGenModule &CGM) { + llvm::OpenMPIRBuilder &OMPBuilder = OMPRuntime->getOMPBuilder(); + + // Fill up the arrays with all the captured variables. + MappableExprsHandler::MapCombinedInfoTy CombinedInfo; CGOpenMPRuntime::TargetDataInfo Info; - // Fill up the arrays and create the arguments. - emitOffloadingArrays(CGF, CombinedInfo, Info, OMPBuilder); - bool EmitDebug = CGF.CGM.getCodeGenOpts().getDebugInfo() != - llvm::codegenoptions::NoDebugInfo; - OMPBuilder.emitOffloadingArraysArgument(CGF.Builder, Info.RTArgs, Info, - EmitDebug, - /*ForEndCall=*/false); + genMapInfo(D, CGF, CS, CapturedVars, OMPBuilder, CombinedInfo); + + emitOffloadingArraysAndArgs(CGF, CombinedInfo, Info, OMPBuilder, + /*IsNonContiguous=*/true, /*ForEndCall=*/false); InputInfo.NumberOfTargetItems = Info.NumberOfPtrs; InputInfo.BasePointersArray = Address(Info.RTArgs.BasePointersArray, @@ -10481,22 +10492,15 @@ void CGOpenMPRuntime::emitTargetDataStandAloneCall( PrePostActionTy &) { // Fill up the arrays with all the mapped variables. MappableExprsHandler::MapCombinedInfoTy CombinedInfo; - - // Get map clause information. + CGOpenMPRuntime::TargetDataInfo Info; MappableExprsHandler MEHandler(D, CGF); - MEHandler.generateAllInfo(CombinedInfo, OMPBuilder); + genMapInfo(MEHandler, CGF, CombinedInfo, OMPBuilder); + emitOffloadingArraysAndArgs(CGF, CombinedInfo, Info, OMPBuilder, + /*IsNonContiguous=*/true, /*ForEndCall=*/false); - CGOpenMPRuntime::TargetDataInfo Info; - // Fill up the arrays and create the arguments. - emitOffloadingArrays(CGF, CombinedInfo, Info, OMPBuilder, - /*IsNonContiguous=*/true); bool RequiresOuterTask = D.hasClausesOfKind() || D.hasClausesOfKind(); - bool EmitDebug = CGF.CGM.getCodeGenOpts().getDebugInfo() != - llvm::codegenoptions::NoDebugInfo; - OMPBuilder.emitOffloadingArraysArgument(CGF.Builder, Info.RTArgs, Info, - EmitDebug, - /*ForEndCall=*/false); + InputInfo.NumberOfTargetItems = Info.NumberOfPtrs; InputInfo.BasePointersArray = Address(Info.RTArgs.BasePointersArray, CGF.VoidPtrTy, CGM.getPointerAlign()); @@ -11504,7 +11508,7 @@ void CGOpenMPRuntime::LastprivateConditionalRAII::tryToDisableInnerAnalysis( } // Exclude vars in private clauses. for (const auto *C : S.getClausesOfKind()) { - for (const Expr *Ref : C->varlists()) { + for (const Expr *Ref : C->varlist()) { if (!Ref->getType()->isScalarType()) continue; const auto *DRE = dyn_cast(Ref->IgnoreParenImpCasts()); @@ -11514,7 +11518,7 @@ void CGOpenMPRuntime::LastprivateConditionalRAII::tryToDisableInnerAnalysis( } } for (const auto *C : S.getClausesOfKind()) { - for (const Expr *Ref : C->varlists()) { + for (const Expr *Ref : C->varlist()) { if (!Ref->getType()->isScalarType()) continue; const auto *DRE = dyn_cast(Ref->IgnoreParenImpCasts()); @@ -11524,7 +11528,7 @@ void CGOpenMPRuntime::LastprivateConditionalRAII::tryToDisableInnerAnalysis( } } for (const auto *C : S.getClausesOfKind()) { - for (const Expr *Ref : C->varlists()) { + for (const Expr *Ref : C->varlist()) { if (!Ref->getType()->isScalarType()) continue; const auto *DRE = dyn_cast(Ref->IgnoreParenImpCasts()); @@ -11534,7 +11538,7 @@ void CGOpenMPRuntime::LastprivateConditionalRAII::tryToDisableInnerAnalysis( } } for (const auto *C : S.getClausesOfKind()) { - for (const Expr *Ref : C->varlists()) { + for (const Expr *Ref : C->varlist()) { if (!Ref->getType()->isScalarType()) continue; const auto *DRE = dyn_cast(Ref->IgnoreParenImpCasts()); @@ -11544,7 +11548,7 @@ void CGOpenMPRuntime::LastprivateConditionalRAII::tryToDisableInnerAnalysis( } } for (const auto *C : S.getClausesOfKind()) { - for (const Expr *Ref : C->varlists()) { + for (const Expr *Ref : C->varlist()) { if (!Ref->getType()->isScalarType()) continue; const auto *DRE = dyn_cast(Ref->IgnoreParenImpCasts()); @@ -11587,7 +11591,7 @@ CGOpenMPRuntime::LastprivateConditionalRAII::LastprivateConditionalRAII( if (C->getKind() != OMPC_LASTPRIVATE_conditional) continue; - for (const Expr *Ref : C->varlists()) { + for (const Expr *Ref : C->varlist()) { Data.DeclToUniqueName.insert(std::make_pair( cast(Ref->IgnoreParenImpCasts())->getDecl(), SmallString<16>(generateUniqueName(CGM, "pl_cond", Ref)))); diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp index f5bd4a141cc2d..8965a14d88a6f 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp @@ -1695,7 +1695,8 @@ void CGOpenMPRuntimeGPU::emitReduction( CGF.AllocaInsertPt->getIterator()); InsertPointTy CodeGenIP(CGF.Builder.GetInsertBlock(), CGF.Builder.GetInsertPoint()); - llvm::OpenMPIRBuilder::LocationDescription OmpLoc(CodeGenIP); + llvm::OpenMPIRBuilder::LocationDescription OmpLoc( + CodeGenIP, CGF.SourceLocToDebugLoc(Loc)); llvm::SmallVector ReductionInfos; CodeGenFunction::OMPPrivateScope Scope(CGF); diff --git a/clang/lib/CodeGen/CGPointerAuth.cpp b/clang/lib/CodeGen/CGPointerAuth.cpp index 621d567dde721..0c63b9d6bb7e7 100644 --- a/clang/lib/CodeGen/CGPointerAuth.cpp +++ b/clang/lib/CodeGen/CGPointerAuth.cpp @@ -15,6 +15,7 @@ #include "CodeGenModule.h" #include "clang/CodeGen/CodeGenABITypes.h" #include "clang/CodeGen/ConstantInitBuilder.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/Support/SipHash.h" using namespace clang; @@ -165,6 +166,128 @@ CGPointerAuthInfo CodeGenModule::getPointerAuthInfoForType(QualType T) { return ::getPointerAuthInfoForType(*this, T); } +static bool isZeroConstant(const llvm::Value *Value) { + if (const auto *CI = dyn_cast(Value)) + return CI->isZero(); + return false; +} + +static bool equalAuthPolicies(const CGPointerAuthInfo &Left, + const CGPointerAuthInfo &Right) { + assert((Left.isSigned() || Right.isSigned()) && + "shouldn't be called if neither is signed"); + if (Left.isSigned() != Right.isSigned()) + return false; + return Left.getKey() == Right.getKey() && + Left.getAuthenticationMode() == Right.getAuthenticationMode(); +} + +// Return the discriminator or return zero if the discriminator is null. +static llvm::Value *getDiscriminatorOrZero(const CGPointerAuthInfo &Info, + CGBuilderTy &Builder) { + llvm::Value *Discriminator = Info.getDiscriminator(); + return Discriminator ? Discriminator : Builder.getSize(0); +} + +llvm::Value * +CodeGenFunction::emitPointerAuthResignCall(llvm::Value *Value, + const CGPointerAuthInfo &CurAuth, + const CGPointerAuthInfo &NewAuth) { + assert(CurAuth && NewAuth); + + if (CurAuth.getAuthenticationMode() != + PointerAuthenticationMode::SignAndAuth || + NewAuth.getAuthenticationMode() != + PointerAuthenticationMode::SignAndAuth) { + llvm::Value *AuthedValue = EmitPointerAuthAuth(CurAuth, Value); + return EmitPointerAuthSign(NewAuth, AuthedValue); + } + // Convert the pointer to intptr_t before signing it. + auto *OrigType = Value->getType(); + Value = Builder.CreatePtrToInt(Value, IntPtrTy); + + auto *CurKey = Builder.getInt32(CurAuth.getKey()); + auto *NewKey = Builder.getInt32(NewAuth.getKey()); + + llvm::Value *CurDiscriminator = getDiscriminatorOrZero(CurAuth, Builder); + llvm::Value *NewDiscriminator = getDiscriminatorOrZero(NewAuth, Builder); + + // call i64 @llvm.ptrauth.resign(i64 %pointer, + // i32 %curKey, i64 %curDiscriminator, + // i32 %newKey, i64 %newDiscriminator) + auto *Intrinsic = CGM.getIntrinsic(llvm::Intrinsic::ptrauth_resign); + Value = EmitRuntimeCall( + Intrinsic, {Value, CurKey, CurDiscriminator, NewKey, NewDiscriminator}); + + // Convert back to the original type. + Value = Builder.CreateIntToPtr(Value, OrigType); + return Value; +} + +llvm::Value *CodeGenFunction::emitPointerAuthResign( + llvm::Value *Value, QualType Type, const CGPointerAuthInfo &CurAuthInfo, + const CGPointerAuthInfo &NewAuthInfo, bool IsKnownNonNull) { + // Fast path: if neither schema wants a signature, we're done. + if (!CurAuthInfo && !NewAuthInfo) + return Value; + + llvm::Value *Null = nullptr; + // If the value is obviously null, we're done. + if (auto *PointerValue = dyn_cast(Value->getType())) { + Null = CGM.getNullPointer(PointerValue, Type); + } else { + assert(Value->getType()->isIntegerTy()); + Null = llvm::ConstantInt::get(IntPtrTy, 0); + } + if (Value == Null) + return Value; + + // If both schemas sign the same way, we're done. + if (equalAuthPolicies(CurAuthInfo, NewAuthInfo)) { + const llvm::Value *CurD = CurAuthInfo.getDiscriminator(); + const llvm::Value *NewD = NewAuthInfo.getDiscriminator(); + if (CurD == NewD) + return Value; + + if ((CurD == nullptr && isZeroConstant(NewD)) || + (NewD == nullptr && isZeroConstant(CurD))) + return Value; + } + + llvm::BasicBlock *InitBB = Builder.GetInsertBlock(); + llvm::BasicBlock *ResignBB = nullptr, *ContBB = nullptr; + + // Null pointers have to be mapped to null, and the ptrauth_resign + // intrinsic doesn't do that. + if (!IsKnownNonNull && !llvm::isKnownNonZero(Value, CGM.getDataLayout())) { + ContBB = createBasicBlock("resign.cont"); + ResignBB = createBasicBlock("resign.nonnull"); + + auto *IsNonNull = Builder.CreateICmpNE(Value, Null); + Builder.CreateCondBr(IsNonNull, ResignBB, ContBB); + EmitBlock(ResignBB); + } + + // Perform the auth/sign/resign operation. + if (!NewAuthInfo) + Value = EmitPointerAuthAuth(CurAuthInfo, Value); + else if (!CurAuthInfo) + Value = EmitPointerAuthSign(NewAuthInfo, Value); + else + Value = emitPointerAuthResignCall(Value, CurAuthInfo, NewAuthInfo); + + // Clean up with a phi if we branched before. + if (ContBB) { + EmitBlock(ContBB); + auto *Phi = Builder.CreatePHI(Value->getType(), 2); + Phi->addIncoming(Null, InitBB); + Phi->addIncoming(Value, ResignBB); + Value = Phi; + } + + return Value; +} + llvm::Constant * CodeGenModule::getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key, llvm::Constant *StorageAddress, @@ -242,6 +365,40 @@ llvm::Constant *CodeGenModule::getFunctionPointer(GlobalDecl GD, return getFunctionPointer(getRawFunctionPointer(GD, Ty), FuncType); } +CGPointerAuthInfo CodeGenModule::getMemberFunctionPointerAuthInfo(QualType FT) { + assert(FT->getAs() && "MemberPointerType expected"); + const auto &Schema = getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers; + if (!Schema) + return CGPointerAuthInfo(); + + assert(!Schema.isAddressDiscriminated() && + "function pointers cannot use address-specific discrimination"); + + llvm::ConstantInt *Discriminator = + getPointerAuthOtherDiscriminator(Schema, GlobalDecl(), FT); + return CGPointerAuthInfo(Schema.getKey(), Schema.getAuthenticationMode(), + /* IsIsaPointer */ false, + /* AuthenticatesNullValues */ false, Discriminator); +} + +llvm::Constant *CodeGenModule::getMemberFunctionPointer(llvm::Constant *Pointer, + QualType FT) { + if (CGPointerAuthInfo PointerAuth = getMemberFunctionPointerAuthInfo(FT)) + return getConstantSignedPointer( + Pointer, PointerAuth.getKey(), nullptr, + cast_or_null(PointerAuth.getDiscriminator())); + + return Pointer; +} + +llvm::Constant *CodeGenModule::getMemberFunctionPointer(const FunctionDecl *FD, + llvm::Type *Ty) { + QualType FT = FD->getType(); + FT = getContext().getMemberPointerType( + FT, cast(FD)->getParent()->getTypeForDecl()); + return getMemberFunctionPointer(getRawFunctionPointer(FD, Ty), FT); +} + std::optional CodeGenModule::computeVTPointerAuthentication(const CXXRecordDecl *ThisClass) { auto DefaultAuthentication = getCodeGenOpts().PointerAuth.CXXVTablePointers; @@ -351,3 +508,114 @@ CodeGenModule::getVTablePointerAuthInfo(CodeGenFunction *CGF, /* IsIsaPointer */ false, /* AuthenticatesNullValues */ false, Discriminator); } + +llvm::Value *CodeGenFunction::authPointerToPointerCast(llvm::Value *ResultPtr, + QualType SourceType, + QualType DestType) { + CGPointerAuthInfo CurAuthInfo, NewAuthInfo; + if (SourceType->isSignableType()) + CurAuthInfo = getPointerAuthInfoForType(CGM, SourceType); + + if (DestType->isSignableType()) + NewAuthInfo = getPointerAuthInfoForType(CGM, DestType); + + if (!CurAuthInfo && !NewAuthInfo) + return ResultPtr; + + // If only one side of the cast is a function pointer, then we still need to + // resign to handle casts to/from opaque pointers. + if (!CurAuthInfo && DestType->isFunctionPointerType()) + CurAuthInfo = CGM.getFunctionPointerAuthInfo(SourceType); + + if (!NewAuthInfo && SourceType->isFunctionPointerType()) + NewAuthInfo = CGM.getFunctionPointerAuthInfo(DestType); + + return emitPointerAuthResign(ResultPtr, DestType, CurAuthInfo, NewAuthInfo, + /*IsKnownNonNull=*/false); +} + +Address CodeGenFunction::authPointerToPointerCast(Address Ptr, + QualType SourceType, + QualType DestType) { + CGPointerAuthInfo CurAuthInfo, NewAuthInfo; + if (SourceType->isSignableType()) + CurAuthInfo = getPointerAuthInfoForType(CGM, SourceType); + + if (DestType->isSignableType()) + NewAuthInfo = getPointerAuthInfoForType(CGM, DestType); + + if (!CurAuthInfo && !NewAuthInfo) + return Ptr; + + if (!CurAuthInfo && DestType->isFunctionPointerType()) { + // When casting a non-signed pointer to a function pointer, just set the + // auth info on Ptr to the assumed schema. The pointer will be resigned to + // the effective type when used. + Ptr.setPointerAuthInfo(CGM.getFunctionPointerAuthInfo(SourceType)); + return Ptr; + } + + if (!NewAuthInfo && SourceType->isFunctionPointerType()) { + NewAuthInfo = CGM.getFunctionPointerAuthInfo(DestType); + Ptr = Ptr.getResignedAddress(NewAuthInfo, *this); + Ptr.setPointerAuthInfo(CGPointerAuthInfo()); + return Ptr; + } + + return Ptr; +} + +Address CodeGenFunction::getAsNaturalAddressOf(Address Addr, + QualType PointeeTy) { + CGPointerAuthInfo Info = + PointeeTy.isNull() ? CGPointerAuthInfo() + : CGM.getPointerAuthInfoForPointeeType(PointeeTy); + return Addr.getResignedAddress(Info, *this); +} + +Address Address::getResignedAddress(const CGPointerAuthInfo &NewInfo, + CodeGenFunction &CGF) const { + assert(isValid() && "pointer isn't valid"); + CGPointerAuthInfo CurInfo = getPointerAuthInfo(); + llvm::Value *Val; + + // Nothing to do if neither the current or the new ptrauth info needs signing. + if (!CurInfo.isSigned() && !NewInfo.isSigned()) + return Address(getBasePointer(), getElementType(), getAlignment(), + isKnownNonNull()); + + assert(ElementType && "Effective type has to be set"); + assert(!Offset && "unexpected non-null offset"); + + // If the current and the new ptrauth infos are the same and the offset is + // null, just cast the base pointer to the effective type. + if (CurInfo == NewInfo && !hasOffset()) + Val = getBasePointer(); + else + Val = CGF.emitPointerAuthResign(getBasePointer(), QualType(), CurInfo, + NewInfo, isKnownNonNull()); + + Val = CGF.Builder.CreateBitCast(Val, getType()); + return Address(Val, getElementType(), getAlignment(), NewInfo, + /*Offset=*/nullptr, isKnownNonNull()); +} + +llvm::Value *Address::emitRawPointerSlow(CodeGenFunction &CGF) const { + return CGF.getAsNaturalPointerTo(*this, QualType()); +} + +llvm::Value *LValue::getPointer(CodeGenFunction &CGF) const { + assert(isSimple()); + return emitResignedPointer(getType(), CGF); +} + +llvm::Value *LValue::emitResignedPointer(QualType PointeeTy, + CodeGenFunction &CGF) const { + assert(isSimple()); + return CGF.getAsNaturalAddressOf(Addr, PointeeTy).getBasePointer(); +} + +llvm::Value *LValue::emitRawPointer(CodeGenFunction &CGF) const { + assert(isSimple()); + return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr; +} diff --git a/clang/lib/CodeGen/CGRecordLayout.h b/clang/lib/CodeGen/CGRecordLayout.h index 6c06ad20fbe56..44e888c93108f 100644 --- a/clang/lib/CodeGen/CGRecordLayout.h +++ b/clang/lib/CodeGen/CGRecordLayout.h @@ -193,6 +193,10 @@ class CGRecordLayout { return IsZeroInitializableAsBase; } + bool containsFieldDecl(const FieldDecl *FD) const { + return FieldInfo.count(FD) != 0; + } + /// Return llvm::StructType element number that corresponds to the /// field FD. unsigned getLLVMFieldNo(const FieldDecl *FD) const { diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 2e65e9fd26099..30b6fce5d016a 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -222,6 +222,12 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef Attrs) { case Stmt::OMPUnrollDirectiveClass: EmitOMPUnrollDirective(cast(*S)); break; + case Stmt::OMPReverseDirectiveClass: + EmitOMPReverseDirective(cast(*S)); + break; + case Stmt::OMPInterchangeDirectiveClass: + EmitOMPInterchangeDirective(cast(*S)); + break; case Stmt::OMPForDirectiveClass: EmitOMPForDirective(cast(*S)); break; @@ -717,6 +723,7 @@ void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) { bool nomerge = false; bool noinline = false; bool alwaysinline = false; + bool noconvergent = false; const CallExpr *musttail = nullptr; for (const auto *A : S.getAttrs()) { @@ -732,6 +739,9 @@ void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) { case attr::AlwaysInline: alwaysinline = true; break; + case attr::NoConvergent: + noconvergent = true; + break; case attr::MustTail: { const Stmt *Sub = S.getSubStmt(); const ReturnStmt *R = cast(Sub); @@ -750,6 +760,7 @@ void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) { SaveAndRestore save_nomerge(InNoMergeAttributedStmt, nomerge); SaveAndRestore save_noinline(InNoInlineAttributedStmt, noinline); SaveAndRestore save_alwaysinline(InAlwaysInlineAttributedStmt, alwaysinline); + SaveAndRestore save_noconvergent(InNoConvergentAttributedStmt, noconvergent); SaveAndRestore save_musttail(MustTailCall, musttail); EmitStmt(S.getSubStmt(), S.getAttrs()); } @@ -2459,7 +2470,8 @@ static llvm::MDNode *getAsmSrcLocInfo(const StringLiteral *Str, static void UpdateAsmCallInst(llvm::CallBase &Result, bool HasSideEffect, bool HasUnwindClobber, bool ReadOnly, - bool ReadNone, bool NoMerge, const AsmStmt &S, + bool ReadNone, bool NoMerge, bool NoConvergent, + const AsmStmt &S, const std::vector &ResultRegTypes, const std::vector &ArgElemTypes, CodeGenFunction &CGF, @@ -2500,11 +2512,11 @@ static void UpdateAsmCallInst(llvm::CallBase &Result, bool HasSideEffect, llvm::ConstantAsMetadata::get(Loc))); } - if (CGF.getLangOpts().assumeFunctionsAreConvergent()) + if (!NoConvergent && CGF.getLangOpts().assumeFunctionsAreConvergent()) // Conservatively, mark all inline asm blocks in CUDA or OpenCL as // convergent (meaning, they may call an intrinsically convergent op, such // as bar.sync, and so can't have certain optimizations applied around - // them). + // them) unless it's explicitly marked 'noconvergent'. Result.addFnAttr(llvm::Attribute::Convergent); // Extract all of the register value results from the asm. if (ResultRegTypes.size() == 1) { @@ -2745,7 +2757,10 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { if (RequiresCast) { unsigned Size = getContext().getTypeSize(QTy); - Ty = llvm::IntegerType::get(getLLVMContext(), Size); + if (Size) + Ty = llvm::IntegerType::get(getLLVMContext(), Size); + else + CGM.Error(OutExpr->getExprLoc(), "output size should not be zero"); } ResultRegTypes.push_back(Ty); // If this output is tied to an input, and if the input is larger, then @@ -3031,9 +3046,10 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { if (IsGCCAsmGoto) { CBR = Builder.CreateCallBr(IA, Fallthrough, Transfer, Args); EmitBlock(Fallthrough); - UpdateAsmCallInst(*CBR, HasSideEffect, false, ReadOnly, ReadNone, - InNoMergeAttributedStmt, S, ResultRegTypes, ArgElemTypes, - *this, RegResults); + UpdateAsmCallInst(*CBR, HasSideEffect, /*HasUnwindClobber=*/false, ReadOnly, + ReadNone, InNoMergeAttributedStmt, + InNoConvergentAttributedStmt, S, ResultRegTypes, + ArgElemTypes, *this, RegResults); // Because we are emitting code top to bottom, we don't have enough // information at this point to know precisely whether we have a critical // edge. If we have outputs, split all indirect destinations. @@ -3061,15 +3077,17 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { } } else if (HasUnwindClobber) { llvm::CallBase *Result = EmitCallOrInvoke(IA, Args, ""); - UpdateAsmCallInst(*Result, HasSideEffect, true, ReadOnly, ReadNone, - InNoMergeAttributedStmt, S, ResultRegTypes, ArgElemTypes, - *this, RegResults); + UpdateAsmCallInst(*Result, HasSideEffect, /*HasUnwindClobber=*/true, + ReadOnly, ReadNone, InNoMergeAttributedStmt, + InNoConvergentAttributedStmt, S, ResultRegTypes, + ArgElemTypes, *this, RegResults); } else { llvm::CallInst *Result = Builder.CreateCall(IA, Args, getBundlesForFunclet(IA)); - UpdateAsmCallInst(*Result, HasSideEffect, false, ReadOnly, ReadNone, - InNoMergeAttributedStmt, S, ResultRegTypes, ArgElemTypes, - *this, RegResults); + UpdateAsmCallInst(*Result, HasSideEffect, /*HasUnwindClobber=*/false, + ReadOnly, ReadNone, InNoMergeAttributedStmt, + InNoConvergentAttributedStmt, S, ResultRegTypes, + ArgElemTypes, *this, RegResults); } EmitAsmStores(*this, S, RegResults, ResultRegTypes, ResultTruncRegTypes, diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 08b569352fe81..1673508cfdfaa 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -44,6 +44,8 @@ using namespace llvm::omp; #define TTL_CODEGEN_TYPE "target-teams-loop-codegen" static const VarDecl *getBaseDecl(const Expr *Ref); +static OpenMPDirectiveKind +getEffectiveDirectiveKind(const OMPExecutableDirective &S); namespace { /// Lexical scope for OpenMP executable constructs, that handles correct codegen @@ -111,10 +113,10 @@ class OMPLexicalScope : public CodeGenFunction::LexicalScope { /// for captured expressions. class OMPParallelScope final : public OMPLexicalScope { bool EmitPreInitStmt(const OMPExecutableDirective &S) { - OpenMPDirectiveKind Kind = S.getDirectiveKind(); - return !(isOpenMPTargetExecutionDirective(Kind) || - isOpenMPLoopBoundSharingDirective(Kind)) && - isOpenMPParallelDirective(Kind); + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(S); + return !(isOpenMPTargetExecutionDirective(EKind) || + isOpenMPLoopBoundSharingDirective(EKind)) && + isOpenMPParallelDirective(EKind); } public: @@ -127,9 +129,9 @@ class OMPParallelScope final : public OMPLexicalScope { /// for captured expressions. class OMPTeamsScope final : public OMPLexicalScope { bool EmitPreInitStmt(const OMPExecutableDirective &S) { - OpenMPDirectiveKind Kind = S.getDirectiveKind(); - return !isOpenMPTargetExecutionDirective(Kind) && - isOpenMPTeamsDirective(Kind); + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(S); + return !isOpenMPTargetExecutionDirective(EKind) && + isOpenMPTeamsDirective(EKind); } public: @@ -154,7 +156,7 @@ class OMPLoopScope : public CodeGenFunction::RunCleanupsScope { } // Mark private vars as undefs. for (const auto *C : LD->getClausesOfKind()) { - for (const Expr *IRef : C->varlists()) { + for (const Expr *IRef : C->varlist()) { const auto *OrigVD = cast(cast(IRef)->getDecl()); if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) { @@ -187,6 +189,11 @@ class OMPLoopScope : public CodeGenFunction::RunCleanupsScope { PreInits = Tile->getPreInits(); } else if (const auto *Unroll = dyn_cast(&S)) { PreInits = Unroll->getPreInits(); + } else if (const auto *Reverse = dyn_cast(&S)) { + PreInits = Reverse->getPreInits(); + } else if (const auto *Interchange = + dyn_cast(&S)) { + PreInits = Interchange->getPreInits(); } else { llvm_unreachable("Unknown loop-based directive kind."); } @@ -250,20 +257,20 @@ class OMPSimdLexicalScope : public CodeGenFunction::LexicalScope { } } } else if (const auto *UDP = dyn_cast(C)) { - for (const Expr *E : UDP->varlists()) { + for (const Expr *E : UDP->varlist()) { const Decl *D = cast(E)->getDecl(); if (const auto *OED = dyn_cast(D)) CGF.EmitVarDecl(*OED); } } else if (const auto *UDP = dyn_cast(C)) { - for (const Expr *E : UDP->varlists()) { + for (const Expr *E : UDP->varlist()) { const Decl *D = getBaseDecl(E); if (const auto *OED = dyn_cast(D)) CGF.EmitVarDecl(*OED); } } } - if (!isOpenMPSimdDirective(S.getDirectiveKind())) + if (!isOpenMPSimdDirective(getEffectiveDirectiveKind(S))) CGF.EmitOMPPrivateClause(S, InlinedShareds); if (const auto *TG = dyn_cast(&S)) { if (const Expr *E = TG->getReductionRef()) @@ -304,6 +311,30 @@ class OMPSimdLexicalScope : public CodeGenFunction::LexicalScope { } // namespace +// The loop directive with a bind clause will be mapped to a different +// directive with corresponding semantics. +static OpenMPDirectiveKind +getEffectiveDirectiveKind(const OMPExecutableDirective &S) { + OpenMPDirectiveKind Kind = S.getDirectiveKind(); + if (Kind != OMPD_loop) + return Kind; + + OpenMPBindClauseKind BindKind = OMPC_BIND_unknown; + if (const auto *C = S.getSingleClause()) + BindKind = C->getBindKind(); + + switch (BindKind) { + case OMPC_BIND_parallel: + return OMPD_for; + case OMPC_BIND_teams: + return OMPD_distribute; + case OMPC_BIND_thread: + return OMPD_simd; + default: + return OMPD_loop; + } +} + static void emitCommonOMPTargetDirective(CodeGenFunction &CGF, const OMPExecutableDirective &S, const RegionCodeGenTy &CodeGen); @@ -639,27 +670,42 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S, // Build the argument list. bool NeedWrapperFunction = getDebugInfo() && CGM.getCodeGenOpts().hasReducedDebugInfo(); - FunctionArgList Args; - llvm::MapVector> LocalAddrs; - llvm::DenseMap> VLASizes; + FunctionArgList Args, WrapperArgs; + llvm::MapVector> LocalAddrs, + WrapperLocalAddrs; + llvm::DenseMap> VLASizes, + WrapperVLASizes; SmallString<256> Buffer; llvm::raw_svector_ostream Out(Buffer); Out << CapturedStmtInfo->getHelperName(); - if (NeedWrapperFunction) + + CodeGenFunction WrapperCGF(CGM, /*suppressNewContext=*/true); + llvm::Function *WrapperF = nullptr; + if (NeedWrapperFunction) { + // Emit the final kernel early to allow attributes to be added by the + // OpenMPI-IR-Builder. + FunctionOptions WrapperFO(&S, /*UIntPtrCastRequired=*/true, + /*RegisterCastedArgsOnly=*/true, + CapturedStmtInfo->getHelperName(), Loc); + WrapperCGF.CapturedStmtInfo = CapturedStmtInfo; + WrapperF = + emitOutlinedFunctionPrologue(WrapperCGF, Args, LocalAddrs, VLASizes, + WrapperCGF.CXXThisValue, WrapperFO); Out << "_debug__"; + } FunctionOptions FO(&S, !NeedWrapperFunction, /*RegisterCastedArgsOnly=*/false, Out.str(), Loc); - llvm::Function *F = emitOutlinedFunctionPrologue(*this, Args, LocalAddrs, - VLASizes, CXXThisValue, FO); + llvm::Function *F = emitOutlinedFunctionPrologue( + *this, WrapperArgs, WrapperLocalAddrs, WrapperVLASizes, CXXThisValue, FO); CodeGenFunction::OMPPrivateScope LocalScope(*this); - for (const auto &LocalAddrPair : LocalAddrs) { + for (const auto &LocalAddrPair : WrapperLocalAddrs) { if (LocalAddrPair.second.first) { LocalScope.addPrivate(LocalAddrPair.second.first, LocalAddrPair.second.second); } } (void)LocalScope.Privatize(); - for (const auto &VLASizePair : VLASizes) + for (const auto &VLASizePair : WrapperVLASizes) VLASizeMap[VLASizePair.second.first] = VLASizePair.second.second; PGO.assignRegionCounters(GlobalDecl(CD), F); CapturedStmtInfo->EmitBody(*this, CD->getBody()); @@ -668,17 +714,10 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S, if (!NeedWrapperFunction) return F; - FunctionOptions WrapperFO(&S, /*UIntPtrCastRequired=*/true, - /*RegisterCastedArgsOnly=*/true, - CapturedStmtInfo->getHelperName(), Loc); - CodeGenFunction WrapperCGF(CGM, /*suppressNewContext=*/true); - WrapperCGF.CapturedStmtInfo = CapturedStmtInfo; - Args.clear(); - LocalAddrs.clear(); - VLASizes.clear(); - llvm::Function *WrapperF = - emitOutlinedFunctionPrologue(WrapperCGF, Args, LocalAddrs, VLASizes, - WrapperCGF.CXXThisValue, WrapperFO); + // Reverse the order. + WrapperF->removeFromParent(); + F->getParent()->getFunctionList().insertAfter(F->getIterator(), WrapperF); + llvm::SmallVector CallArgs; auto *PI = F->arg_begin(); for (const auto *Arg : Args) { @@ -820,20 +859,20 @@ bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) { if (!HaveInsertPoint()) return false; - bool DeviceConstTarget = - getLangOpts().OpenMPIsTargetDevice && - isOpenMPTargetExecutionDirective(D.getDirectiveKind()); + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(D); + bool DeviceConstTarget = getLangOpts().OpenMPIsTargetDevice && + isOpenMPTargetExecutionDirective(EKind); bool FirstprivateIsLastprivate = false; llvm::DenseMap Lastprivates; for (const auto *C : D.getClausesOfKind()) { - for (const auto *D : C->varlists()) + for (const auto *D : C->varlist()) Lastprivates.try_emplace( cast(cast(D)->getDecl())->getCanonicalDecl(), C->getKind()); } llvm::DenseSet EmittedAsFirstprivate; llvm::SmallVector CaptureRegions; - getOpenMPCaptureRegions(CaptureRegions, D.getDirectiveKind()); + getOpenMPCaptureRegions(CaptureRegions, EKind); // Force emission of the firstprivate copy if the directive does not emit // outlined function, like omp for, omp simd, omp distribute etc. bool MustEmitFirstprivateCopy = @@ -1062,8 +1101,9 @@ bool CodeGenFunction::EmitOMPLastprivateClauseInit( if (!HaveInsertPoint()) return false; bool HasAtLeastOneLastprivate = false; + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(D); llvm::DenseSet SIMDLCVs; - if (isOpenMPSimdDirective(D.getDirectiveKind())) { + if (isOpenMPSimdDirective(EKind)) { const auto *LoopDirective = cast(&D); for (const Expr *C : LoopDirective->counters()) { SIMDLCVs.insert( @@ -1073,8 +1113,7 @@ bool CodeGenFunction::EmitOMPLastprivateClauseInit( llvm::DenseSet AlreadyEmittedVars; for (const auto *C : D.getClausesOfKind()) { HasAtLeastOneLastprivate = true; - if (isOpenMPTaskLoopDirective(D.getDirectiveKind()) && - !getLangOpts().OpenMPSimd) + if (isOpenMPTaskLoopDirective(EKind) && !getLangOpts().OpenMPSimd) break; const auto *IRef = C->varlist_begin(); const auto *IDestRef = C->destination_exprs().begin(); @@ -1307,13 +1346,13 @@ void CodeGenFunction::EmitOMPReductionClauseInit( ++Count; } if (!Data.ReductionVars.empty()) { + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(D); Data.IsReductionWithTaskMod = true; - Data.IsWorksharingReduction = - isOpenMPWorksharingDirective(D.getDirectiveKind()); + Data.IsWorksharingReduction = isOpenMPWorksharingDirective(EKind); llvm::Value *ReductionDesc = CGM.getOpenMPRuntime().emitTaskReductionInit( *this, D.getBeginLoc(), TaskLHSs, TaskRHSs, Data); const Expr *TaskRedRef = nullptr; - switch (D.getDirectiveKind()) { + switch (EKind) { case OMPD_parallel: TaskRedRef = cast(D).getTaskReductionRefExpr(); break; @@ -1444,16 +1483,16 @@ void CodeGenFunction::EmitOMPReductionClauseFinal( IsReductionWithTaskMod || C->getModifier() == OMPC_REDUCTION_task; } if (HasAtLeastOneReduction) { + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(D); if (IsReductionWithTaskMod) { CGM.getOpenMPRuntime().emitTaskReductionFini( - *this, D.getBeginLoc(), - isOpenMPWorksharingDirective(D.getDirectiveKind())); + *this, D.getBeginLoc(), isOpenMPWorksharingDirective(EKind)); } bool TeamsLoopCanBeParallel = false; if (auto *TTLD = dyn_cast(&D)) TeamsLoopCanBeParallel = TTLD->canBeParallelFor(); bool WithNowait = D.getSingleClause() || - isOpenMPParallelDirective(D.getDirectiveKind()) || + isOpenMPParallelDirective(EKind) || TeamsLoopCanBeParallel || ReductionKind == OMPD_simd; bool SimpleReduction = ReductionKind == OMPD_simd; // Emit nowait reduction if nowait clause is present or directive is a @@ -1506,7 +1545,7 @@ checkForLastprivateConditionalUpdate(CodeGenFunction &CGF, return; llvm::DenseSet> PrivateDecls; for (const auto *C : S.getClausesOfKind()) { - for (const Expr *Ref : C->varlists()) { + for (const Expr *Ref : C->varlist()) { if (!Ref->getType()->isScalarType()) continue; const auto *DRE = dyn_cast(Ref->IgnoreParenImpCasts()); @@ -1517,7 +1556,7 @@ checkForLastprivateConditionalUpdate(CodeGenFunction &CGF, } } for (const auto *C : S.getClausesOfKind()) { - for (const Expr *Ref : C->varlists()) { + for (const Expr *Ref : C->varlist()) { if (!Ref->getType()->isScalarType()) continue; const auto *DRE = dyn_cast(Ref->IgnoreParenImpCasts()); @@ -1528,7 +1567,7 @@ checkForLastprivateConditionalUpdate(CodeGenFunction &CGF, } } for (const auto *C : S.getClausesOfKind()) { - for (const Expr *Ref : C->varlists()) { + for (const Expr *Ref : C->varlist()) { if (!Ref->getType()->isScalarType()) continue; const auto *DRE = dyn_cast(Ref->IgnoreParenImpCasts()); @@ -1543,7 +1582,7 @@ checkForLastprivateConditionalUpdate(CodeGenFunction &CGF, // Firstprivates do not return value but may be passed by reference - no need // to check for updated lastprivate conditional. for (const auto *C : S.getClausesOfKind()) { - for (const Expr *Ref : C->varlists()) { + for (const Expr *Ref : C->varlist()) { if (!Ref->getType()->isScalarType()) continue; const auto *DRE = dyn_cast(Ref->IgnoreParenImpCasts()); @@ -1910,7 +1949,8 @@ void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D, // Update the linear variables. // In distribute directives only loop counters may be marked as linear, no // need to generate the code for them. - if (!isOpenMPDistributeDirective(D.getDirectiveKind())) { + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(D); + if (!isOpenMPDistributeDirective(EKind)) { for (const auto *C : D.getClausesOfKind()) { for (const Expr *UE : C->updates()) EmitIgnoredExpr(UE); @@ -1944,7 +1984,7 @@ void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D, OMPAfterScanBlock = createBasicBlock("omp.after.scan.bb"); // No need to allocate inscan exit block, in simd mode it is selected in the // codegen for the scan directive. - if (D.getDirectiveKind() != OMPD_simd && !getLangOpts().OpenMPSimd) + if (EKind != OMPD_simd && !getLangOpts().OpenMPSimd) OMPScanExitBlock = createBasicBlock("omp.exit.inscan.bb"); OMPScanDispatch = createBasicBlock("omp.inscan.dispatch"); EmitBranch(OMPScanDispatch); @@ -2248,7 +2288,7 @@ static void emitAlignedClause(CodeGenFunction &CGF, cast(CGF.EmitScalarExpr(AlignmentExpr)); ClauseAlignment = AlignmentCI->getValue(); } - for (const Expr *E : Clause->varlists()) { + for (const Expr *E : Clause->varlist()) { llvm::APInt Alignment(ClauseAlignment); if (Alignment == 0) { // OpenMP [2.8.1, Description] @@ -2357,7 +2397,8 @@ void CodeGenFunction::EmitOMPLinearClause( if (!HaveInsertPoint()) return; llvm::DenseSet SIMDLCVs; - if (isOpenMPSimdDirective(D.getDirectiveKind())) { + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(D); + if (isOpenMPSimdDirective(EKind)) { const auto *LoopDirective = cast(&D); for (const Expr *C : LoopDirective->counters()) { SIMDLCVs.insert( @@ -2366,7 +2407,7 @@ void CodeGenFunction::EmitOMPLinearClause( } for (const auto *C : D.getClausesOfKind()) { auto CurPrivate = C->privates().begin(); - for (const Expr *E : C->varlists()) { + for (const Expr *E : C->varlist()) { const auto *VD = cast(cast(E)->getDecl()); const auto *PrivateVD = cast(cast(*CurPrivate)->getDecl()); @@ -2419,9 +2460,9 @@ void CodeGenFunction::EmitOMPSimdInit(const OMPLoopDirective &D) { if (const auto *C = D.getSingleClause()) if (C->getKind() == OMPC_ORDER_concurrent) LoopStack.setParallel(/*Enable=*/true); - if ((D.getDirectiveKind() == OMPD_simd || - (getLangOpts().OpenMPSimd && - isOpenMPSimdDirective(D.getDirectiveKind()))) && + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(D); + if ((EKind == OMPD_simd || + (getLangOpts().OpenMPSimd && isOpenMPSimdDirective(EKind))) && llvm::any_of(D.getClausesOfKind(), [](const OMPReductionClause *C) { return C->getModifier() == OMPC_REDUCTION_inscan; @@ -2508,7 +2549,8 @@ static void emitCommonSimdLoop(CodeGenFunction &CGF, const OMPLoopDirective &S, BodyCodeGen(CGF); }; const Expr *IfCond = nullptr; - if (isOpenMPSimdDirective(S.getDirectiveKind())) { + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(S); + if (isOpenMPSimdDirective(EKind)) { for (const auto *C : S.getClausesOfKind()) { if (CGF.getLangOpts().OpenMP >= 50 && (C->getNameModifier() == OMPD_unknown || @@ -2529,21 +2571,24 @@ static void emitCommonSimdLoop(CodeGenFunction &CGF, const OMPLoopDirective &S, static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S, PrePostActionTy &Action) { Action.Enter(CGF); - assert(isOpenMPSimdDirective(S.getDirectiveKind()) && - "Expected simd directive"); OMPLoopScope PreInitScope(CGF, S); // if (PreCond) { // for (IV in 0..LastIteration) BODY; // ; // } - // - if (isOpenMPDistributeDirective(S.getDirectiveKind()) || - isOpenMPWorksharingDirective(S.getDirectiveKind()) || - isOpenMPTaskLoopDirective(S.getDirectiveKind())) { + + // The presence of lower/upper bound variable depends on the actual directive + // kind in the AST node. The variables must be emitted because some of the + // expressions associated with the loop will use them. + OpenMPDirectiveKind DKind = S.getDirectiveKind(); + if (isOpenMPDistributeDirective(DKind) || + isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || + isOpenMPGenericLoopDirective(DKind)) { (void)EmitOMPHelperVar(CGF, cast(S.getLowerBoundVariable())); (void)EmitOMPHelperVar(CGF, cast(S.getUpperBoundVariable())); } + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(S); // Emit: if (PreCond) - begin. // If the condition constant folds and can be elided, avoid emitting the // whole loop. @@ -2588,7 +2633,7 @@ static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S, CGF, S, CGF.EmitLValue(S.getIterationVariable())); bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope); (void)LoopScope.Privatize(); - if (isOpenMPTargetExecutionDirective(S.getDirectiveKind())) + if (isOpenMPTargetExecutionDirective(EKind)) CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S); emitCommonSimdLoop( @@ -2622,7 +2667,9 @@ static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S, } } -static bool isSupportedByOpenMPIRBuilder(const OMPSimdDirective &S) { +// Pass OMPLoopDirective (instead of OMPSimdDirective) to make this function +// available for "loop bind(thread)", which maps to "simd". +static bool isSimdSupportedByOpenMPIRBuilder(const OMPLoopDirective &S) { // Check for unsupported clauses for (OMPClause *C : S.clauses()) { // Currently only order, simdlen and safelen clauses are supported @@ -2653,8 +2700,9 @@ static bool isSupportedByOpenMPIRBuilder(const OMPSimdDirective &S) { } return true; } + static llvm::MapVector -GetAlignedMapping(const OMPSimdDirective &S, CodeGenFunction &CGF) { +GetAlignedMapping(const OMPLoopDirective &S, CodeGenFunction &CGF) { llvm::MapVector AlignedVars; for (const auto *Clause : S.getClausesOfKind()) { llvm::APInt ClauseAlignment(64, 0); @@ -2663,7 +2711,7 @@ GetAlignedMapping(const OMPSimdDirective &S, CodeGenFunction &CGF) { cast(CGF.EmitScalarExpr(AlignmentExpr)); ClauseAlignment = AlignmentCI->getValue(); } - for (const Expr *E : Clause->varlists()) { + for (const Expr *E : Clause->varlist()) { llvm::APInt Alignment(ClauseAlignment); if (Alignment == 0) { // OpenMP [2.8.1, Description] @@ -2684,11 +2732,14 @@ GetAlignedMapping(const OMPSimdDirective &S, CodeGenFunction &CGF) { return AlignedVars; } -void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { +// Pass OMPLoopDirective (instead of OMPSimdDirective) to make this function +// available for "loop bind(thread)", which maps to "simd". +void emitOMPSimdDirective(const OMPLoopDirective &S, CodeGenFunction &CGF, + CodeGenModule &CGM) { bool UseOMPIRBuilder = - CGM.getLangOpts().OpenMPIRBuilder && isSupportedByOpenMPIRBuilder(S); + CGM.getLangOpts().OpenMPIRBuilder && isSimdSupportedByOpenMPIRBuilder(S); if (UseOMPIRBuilder) { - auto &&CodeGenIRBuilder = [this, &S, UseOMPIRBuilder](CodeGenFunction &CGF, + auto &&CodeGenIRBuilder = [&S, &CGM, UseOMPIRBuilder](CodeGenFunction &CGF, PrePostActionTy &) { // Use the OpenMPIRBuilder if enabled. if (UseOMPIRBuilder) { @@ -2697,30 +2748,28 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { // Emit the associated statement and get its loop representation. const Stmt *Inner = S.getRawStmt(); llvm::CanonicalLoopInfo *CLI = - EmitOMPCollapsedCanonicalLoopNest(Inner, 1); + CGF.EmitOMPCollapsedCanonicalLoopNest(Inner, 1); llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder(); // Add SIMD specific metadata llvm::ConstantInt *Simdlen = nullptr; if (const auto *C = S.getSingleClause()) { - RValue Len = - this->EmitAnyExpr(C->getSimdlen(), AggValueSlot::ignored(), - /*ignoreResult=*/true); + RValue Len = CGF.EmitAnyExpr(C->getSimdlen(), AggValueSlot::ignored(), + /*ignoreResult=*/true); auto *Val = cast(Len.getScalarVal()); Simdlen = Val; } llvm::ConstantInt *Safelen = nullptr; if (const auto *C = S.getSingleClause()) { - RValue Len = - this->EmitAnyExpr(C->getSafelen(), AggValueSlot::ignored(), - /*ignoreResult=*/true); + RValue Len = CGF.EmitAnyExpr(C->getSafelen(), AggValueSlot::ignored(), + /*ignoreResult=*/true); auto *Val = cast(Len.getScalarVal()); Safelen = Val; } llvm::omp::OrderKind Order = llvm::omp::OrderKind::OMP_ORDER_unknown; if (const auto *C = S.getSingleClause()) { - if (C->getKind() == OpenMPOrderClauseKind ::OMPC_ORDER_concurrent) { + if (C->getKind() == OpenMPOrderClauseKind::OMPC_ORDER_concurrent) { Order = llvm::omp::OrderKind::OMP_ORDER_concurrent; } } @@ -2733,27 +2782,31 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { }; { auto LPCRegion = - CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); - OMPLexicalScope Scope(*this, S, OMPD_unknown); - CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, + CGOpenMPRuntime::LastprivateConditionalRAII::disable(CGF, S); + OMPLexicalScope Scope(CGF, S, OMPD_unknown); + CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_simd, CodeGenIRBuilder); } return; } - ParentLoopDirectiveForScanRegion ScanRegion(*this, S); - OMPFirstScanLoop = true; + CodeGenFunction::ParentLoopDirectiveForScanRegion ScanRegion(CGF, S); + CGF.OMPFirstScanLoop = true; auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { emitOMPSimdRegion(CGF, S, Action); }; { auto LPCRegion = - CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); - OMPLexicalScope Scope(*this, S, OMPD_unknown); - CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen); + CGOpenMPRuntime::LastprivateConditionalRAII::disable(CGF, S); + OMPLexicalScope Scope(CGF, S, OMPD_unknown); + CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_simd, CodeGen); } // Check for outer lastprivate conditional update. - checkForLastprivateConditionalUpdate(*this, S); + checkForLastprivateConditionalUpdate(CGF, S); +} + +void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { + emitOMPSimdDirective(S, *this, CGM); } void CodeGenFunction::EmitOMPTileDirective(const OMPTileDirective &S) { @@ -2762,6 +2815,19 @@ void CodeGenFunction::EmitOMPTileDirective(const OMPTileDirective &S) { EmitStmt(S.getTransformedStmt()); } +void CodeGenFunction::EmitOMPReverseDirective(const OMPReverseDirective &S) { + // Emit the de-sugared statement. + OMPTransformDirectiveScopeRAII ReverseScope(*this, &S); + EmitStmt(S.getTransformedStmt()); +} + +void CodeGenFunction::EmitOMPInterchangeDirective( + const OMPInterchangeDirective &S) { + // Emit the de-sugared statement. + OMPTransformDirectiveScopeRAII InterchangeScope(*this, &S); + EmitStmt(S.getTransformedStmt()); +} + void CodeGenFunction::EmitOMPUnrollDirective(const OMPUnrollDirective &S) { bool UseOMPIRBuilder = CGM.getLangOpts().OpenMPIRBuilder; @@ -2885,12 +2951,13 @@ void CodeGenFunction::EmitOMPOuterLoop( JumpDest Continue = getJumpDestInCurrentScope("omp.dispatch.inc"); BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(S); emitCommonSimdLoop( *this, S, - [&S, IsMonotonic](CodeGenFunction &CGF, PrePostActionTy &) { + [&S, IsMonotonic, EKind](CodeGenFunction &CGF, PrePostActionTy &) { // Generate !llvm.loop.parallel metadata for loads and stores for loops // with dynamic/guided scheduling and without ordered clause. - if (!isOpenMPSimdDirective(S.getDirectiveKind())) { + if (!isOpenMPSimdDirective(EKind)) { CGF.LoopStack.setParallel(!IsMonotonic); if (const auto *C = S.getSingleClause()) if (C->getKind() == OMPC_ORDER_concurrent) @@ -2937,7 +3004,7 @@ void CodeGenFunction::EmitOMPOuterLoop( CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(), LoopArgs.DKind); }; - OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen); + OMPCancelStack.emitExit(*this, EKind, CodeGen); } void CodeGenFunction::EmitOMPForOuterLoop( @@ -3023,8 +3090,9 @@ void CodeGenFunction::EmitOMPForOuterLoop( CGOpenMPRuntime::StaticRTInput StaticInit( IVSize, IVSigned, Ordered, LoopArgs.IL, LoopArgs.LB, LoopArgs.UB, LoopArgs.ST, LoopArgs.Chunk); - RT.emitForStaticInit(*this, S.getBeginLoc(), S.getDirectiveKind(), - ScheduleKind, StaticInit); + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(S); + RT.emitForStaticInit(*this, S.getBeginLoc(), EKind, ScheduleKind, + StaticInit); } auto &&CodeGenOrdered = [Ordered](CodeGenFunction &CGF, SourceLocation Loc, @@ -3069,6 +3137,7 @@ void CodeGenFunction::EmitOMPDistributeOuterLoop( const Expr *IVExpr = S.getIterationVariable(); const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(S); CGOpenMPRuntime::StaticRTInput StaticInit( IVSize, IVSigned, /* Ordered = */ false, LoopArgs.IL, LoopArgs.LB, @@ -3078,7 +3147,7 @@ void CodeGenFunction::EmitOMPDistributeOuterLoop( // for combined 'distribute' and 'for' the increment expression of distribute // is stored in DistInc. For 'distribute' alone, it is in Inc. Expr *IncExpr; - if (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())) + if (isOpenMPLoopBoundSharingDirective(EKind)) IncExpr = S.getDistInc(); else IncExpr = S.getInc(); @@ -3092,20 +3161,20 @@ void CodeGenFunction::EmitOMPDistributeOuterLoop( OuterLoopArgs.ST = LoopArgs.ST; OuterLoopArgs.IL = LoopArgs.IL; OuterLoopArgs.Chunk = LoopArgs.Chunk; - OuterLoopArgs.EUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) + OuterLoopArgs.EUB = isOpenMPLoopBoundSharingDirective(EKind) ? S.getCombinedEnsureUpperBound() : S.getEnsureUpperBound(); OuterLoopArgs.IncExpr = IncExpr; - OuterLoopArgs.Init = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) + OuterLoopArgs.Init = isOpenMPLoopBoundSharingDirective(EKind) ? S.getCombinedInit() : S.getInit(); - OuterLoopArgs.Cond = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) + OuterLoopArgs.Cond = isOpenMPLoopBoundSharingDirective(EKind) ? S.getCombinedCond() : S.getCond(); - OuterLoopArgs.NextLB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) + OuterLoopArgs.NextLB = isOpenMPLoopBoundSharingDirective(EKind) ? S.getCombinedNextLowerBound() : S.getNextLowerBound(); - OuterLoopArgs.NextUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) + OuterLoopArgs.NextUB = isOpenMPLoopBoundSharingDirective(EKind) ? S.getCombinedNextUpperBound() : S.getNextUpperBound(); OuterLoopArgs.DKind = OMPD_distribute; @@ -3197,11 +3266,12 @@ static void emitInnerParallelForWhenCombined(CodeGenFunction &CGF, const OMPLoopDirective &S, CodeGenFunction::JumpDest LoopExit) { - auto &&CGInlinedWorksharingLoop = [&S](CodeGenFunction &CGF, - PrePostActionTy &Action) { + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(S); + auto &&CGInlinedWorksharingLoop = [&S, EKind](CodeGenFunction &CGF, + PrePostActionTy &Action) { Action.Enter(CGF); bool HasCancel = false; - if (!isOpenMPSimdDirective(S.getDirectiveKind())) { + if (!isOpenMPSimdDirective(EKind)) { if (const auto *D = dyn_cast(&S)) HasCancel = D->hasCancel(); else if (const auto *D = dyn_cast(&S)) @@ -3210,16 +3280,14 @@ emitInnerParallelForWhenCombined(CodeGenFunction &CGF, dyn_cast(&S)) HasCancel = D->hasCancel(); } - CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, S.getDirectiveKind(), - HasCancel); + CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, EKind, HasCancel); CGF.EmitOMPWorksharingLoop(S, S.getPrevEnsureUpperBound(), emitDistributeParallelForInnerBounds, emitDistributeParallelForDispatchBounds); }; emitCommonOMPParallelDirective( - CGF, S, - isOpenMPSimdDirective(S.getDirectiveKind()) ? OMPD_for_simd : OMPD_for, + CGF, S, isOpenMPSimdDirective(EKind) ? OMPD_for_simd : OMPD_for, CGInlinedWorksharingLoop, emitDistributeParallelForDistributeInnerBoundParams); } @@ -3352,6 +3420,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop( // Emit 'then' code. { + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(S); OMPPrivateScope LoopScope(*this); if (EmitOMPFirstprivateClause(S, LoopScope) || HasLinears) { // Emit implicit barrier to synchronize threads and avoid data races on @@ -3369,7 +3438,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop( EmitOMPPrivateLoopCounters(S, LoopScope); EmitOMPLinearClause(S, LoopScope); (void)LoopScope.Privatize(); - if (isOpenMPTargetExecutionDirective(S.getDirectiveKind())) + if (isOpenMPTargetExecutionDirective(EKind)) CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(*this, S); // Detect the loop schedule kind and chunk. @@ -3407,8 +3476,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop( bool StaticChunkedOne = RT.isStaticChunked(ScheduleKind.Schedule, /* Chunked */ Chunk != nullptr) && - HasChunkSizeOne && - isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()); + HasChunkSizeOne && isOpenMPLoopBoundSharingDirective(EKind); bool IsMonotonic = Ordered || (ScheduleKind.Schedule == OMPC_SCHEDULE_static && @@ -3424,8 +3492,8 @@ bool CodeGenFunction::EmitOMPWorksharingLoop( getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit")); emitCommonSimdLoop( *this, S, - [&S](CodeGenFunction &CGF, PrePostActionTy &) { - if (isOpenMPSimdDirective(S.getDirectiveKind())) { + [&S, EKind](CodeGenFunction &CGF, PrePostActionTy &) { + if (isOpenMPSimdDirective(EKind)) { CGF.EmitOMPSimdInit(S); } else if (const auto *C = S.getSingleClause()) { if (C->getKind() == OMPC_ORDER_concurrent) @@ -3433,7 +3501,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop( } }, [IVSize, IVSigned, Ordered, IL, LB, UB, ST, StaticChunkedOne, Chunk, - &S, ScheduleKind, LoopExit, + &S, ScheduleKind, LoopExit, EKind, &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) { // OpenMP [2.7.1, Loop Construct, Description, table 2-1] // When no chunk_size is specified, the iteration space is divided @@ -3445,8 +3513,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop( UB.getAddress(), ST.getAddress(), StaticChunkedOne ? Chunk : nullptr); CGF.CGM.getOpenMPRuntime().emitForStaticInit( - CGF, S.getBeginLoc(), S.getDirectiveKind(), ScheduleKind, - StaticInit); + CGF, S.getBeginLoc(), EKind, ScheduleKind, StaticInit); // UB = min(UB, GlobalUB); if (!StaticChunkedOne) CGF.EmitIgnoredExpr(S.getEnsureUpperBound()); @@ -3481,7 +3548,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop( CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(), OMPD_for); }; - OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen); + OMPCancelStack.emitExit(*this, EKind, CodeGen); } else { // Emit the outer loop, which requests its work chunk [LB..UB] from // runtime and runs the inner loop to process it. @@ -3492,14 +3559,14 @@ bool CodeGenFunction::EmitOMPWorksharingLoop( EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered, LoopArguments, CGDispatchBounds); } - if (isOpenMPSimdDirective(S.getDirectiveKind())) { + if (isOpenMPSimdDirective(EKind)) { EmitOMPSimdFinal(S, [IL, &S](CodeGenFunction &CGF) { return CGF.Builder.CreateIsNotNull( CGF.EmitLoadOfScalar(IL, S.getBeginLoc())); }); } EmitOMPReductionClauseFinal( - S, /*ReductionKind=*/isOpenMPSimdDirective(S.getDirectiveKind()) + S, /*ReductionKind=*/isOpenMPSimdDirective(EKind) ? /*Parallel and Simd*/ OMPD_parallel_for_simd : /*Parallel only*/ OMPD_parallel); // Emit post-update of the reduction variables if IsLastIter != 0. @@ -3511,7 +3578,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop( // Emit final copy of the lastprivate variables if IsLastIter != 0. if (HasLastprivateClause) EmitOMPLastprivateClauseFinal( - S, isOpenMPSimdDirective(S.getDirectiveKind()), + S, isOpenMPSimdDirective(EKind), Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.getBeginLoc()))); LoopScope.restoreMap(); EmitOMPLinearClauseFinal(S, [IL, &S](CodeGenFunction &CGF) { @@ -3807,7 +3874,8 @@ static void emitScanBasedDirective( auto DL1 = ApplyDebugLocation::CreateDefaultArtificial(CGF, S.getEndLoc()); CGF.EmitBlock(ExitBB); }; - if (isOpenMPParallelDirective(S.getDirectiveKind())) { + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(S); + if (isOpenMPParallelDirective(EKind)) { CGF.CGM.getOpenMPRuntime().emitMasterRegion(CGF, CodeGen, S.getBeginLoc()); CGF.CGM.getOpenMPRuntime().emitBarrierCall( CGF, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false, @@ -3825,6 +3893,7 @@ static bool emitWorksharingDirective(CodeGenFunction &CGF, const OMPLoopDirective &S, bool HasCancel) { bool HasLastprivates; + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(S); if (llvm::any_of(S.getClausesOfKind(), [](const OMPReductionClause *C) { return C->getModifier() == OMPC_REDUCTION_inscan; @@ -3834,9 +3903,8 @@ static bool emitWorksharingDirective(CodeGenFunction &CGF, OMPLoopScope LoopScope(CGF, S); return CGF.EmitScalarExpr(S.getNumIterations()); }; - const auto &&FirstGen = [&S, HasCancel](CodeGenFunction &CGF) { - CodeGenFunction::OMPCancelStackRAII CancelRegion( - CGF, S.getDirectiveKind(), HasCancel); + const auto &&FirstGen = [&S, HasCancel, EKind](CodeGenFunction &CGF) { + CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, EKind, HasCancel); (void)CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds, emitDispatchForLoopBounds); @@ -3844,22 +3912,20 @@ static bool emitWorksharingDirective(CodeGenFunction &CGF, CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getBeginLoc(), OMPD_for); }; - const auto &&SecondGen = [&S, HasCancel, + const auto &&SecondGen = [&S, HasCancel, EKind, &HasLastprivates](CodeGenFunction &CGF) { - CodeGenFunction::OMPCancelStackRAII CancelRegion( - CGF, S.getDirectiveKind(), HasCancel); + CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, EKind, HasCancel); HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds, emitDispatchForLoopBounds); }; - if (!isOpenMPParallelDirective(S.getDirectiveKind())) + if (!isOpenMPParallelDirective(EKind)) emitScanBasedDirectiveDecls(CGF, S, NumIteratorsGen); emitScanBasedDirective(CGF, S, NumIteratorsGen, FirstGen, SecondGen); - if (!isOpenMPParallelDirective(S.getDirectiveKind())) + if (!isOpenMPParallelDirective(EKind)) emitScanBasedDirectiveFinals(CGF, S, NumIteratorsGen); } else { - CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, S.getDirectiveKind(), - HasCancel); + CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, EKind, HasCancel); HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds, emitDispatchForLoopBounds); @@ -3867,11 +3933,14 @@ static bool emitWorksharingDirective(CodeGenFunction &CGF, return HasLastprivates; } -static bool isSupportedByOpenMPIRBuilder(const OMPForDirective &S) { - if (S.hasCancel()) +// Pass OMPLoopDirective (instead of OMPForDirective) to make this check +// available for "loop bind(parallel)", which maps to "for". +static bool isForSupportedByOpenMPIRBuilder(const OMPLoopDirective &S, + bool HasCancel) { + if (HasCancel) return false; for (OMPClause *C : S.clauses()) { - if (isa(C)) + if (isa(C)) continue; if (auto *SC = dyn_cast(C)) { @@ -3916,11 +3985,14 @@ convertClauseKindToSchedKind(OpenMPScheduleClauseKind ScheduleClauseKind) { llvm_unreachable("Unhandled schedule kind"); } -void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) { +// Pass OMPLoopDirective (instead of OMPForDirective) to make this function +// available for "loop bind(parallel)", which maps to "for". +void emitOMPForDirective(const OMPLoopDirective &S, CodeGenFunction &CGF, + CodeGenModule &CGM, bool HasCancel) { bool HasLastprivates = false; - bool UseOMPIRBuilder = - CGM.getLangOpts().OpenMPIRBuilder && isSupportedByOpenMPIRBuilder(S); - auto &&CodeGen = [this, &S, &HasLastprivates, + bool UseOMPIRBuilder = CGM.getLangOpts().OpenMPIRBuilder && + isForSupportedByOpenMPIRBuilder(S, HasCancel); + auto &&CodeGen = [&S, &CGM, HasCancel, &HasLastprivates, UseOMPIRBuilder](CodeGenFunction &CGF, PrePostActionTy &) { // Use the OpenMPIRBuilder if enabled. if (UseOMPIRBuilder) { @@ -3932,43 +4004,47 @@ void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) { SchedKind = convertClauseKindToSchedKind(SchedClause->getScheduleKind()); if (const Expr *ChunkSizeExpr = SchedClause->getChunkSize()) - ChunkSize = EmitScalarExpr(ChunkSizeExpr); + ChunkSize = CGF.EmitScalarExpr(ChunkSizeExpr); } // Emit the associated statement and get its loop representation. const Stmt *Inner = S.getRawStmt(); llvm::CanonicalLoopInfo *CLI = - EmitOMPCollapsedCanonicalLoopNest(Inner, 1); + CGF.EmitOMPCollapsedCanonicalLoopNest(Inner, 1); llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder(); llvm::OpenMPIRBuilder::InsertPointTy AllocaIP( - AllocaInsertPt->getParent(), AllocaInsertPt->getIterator()); + CGF.AllocaInsertPt->getParent(), CGF.AllocaInsertPt->getIterator()); OMPBuilder.applyWorkshareLoop( - Builder.getCurrentDebugLocation(), CLI, AllocaIP, NeedsBarrier, + CGF.Builder.getCurrentDebugLocation(), CLI, AllocaIP, NeedsBarrier, SchedKind, ChunkSize, /*HasSimdModifier=*/false, /*HasMonotonicModifier=*/false, /*HasNonmonotonicModifier=*/false, /*HasOrderedClause=*/false); return; } - HasLastprivates = emitWorksharingDirective(CGF, S, S.hasCancel()); + HasLastprivates = emitWorksharingDirective(CGF, S, HasCancel); }; { auto LPCRegion = - CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); - OMPLexicalScope Scope(*this, S, OMPD_unknown); - CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen, - S.hasCancel()); + CGOpenMPRuntime::LastprivateConditionalRAII::disable(CGF, S); + OMPLexicalScope Scope(CGF, S, OMPD_unknown); + CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_for, CodeGen, + HasCancel); } if (!UseOMPIRBuilder) { // Emit an implicit barrier at the end. if (!S.getSingleClause() || HasLastprivates) - CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_for); + CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getBeginLoc(), OMPD_for); } // Check for outer lastprivate conditional update. - checkForLastprivateConditionalUpdate(*this, S); + checkForLastprivateConditionalUpdate(CGF, S); +} + +void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) { + return emitOMPForDirective(S, *this, CGM, S.hasCancel()); } void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) { @@ -4004,7 +4080,8 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { const Stmt *CapturedStmt = S.getInnermostCapturedStmt()->getCapturedStmt(); const auto *CS = dyn_cast(CapturedStmt); bool HasLastprivates = false; - auto &&CodeGen = [&S, CapturedStmt, CS, + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(S); + auto &&CodeGen = [&S, CapturedStmt, CS, EKind, &HasLastprivates](CodeGenFunction &CGF, PrePostActionTy &) { const ASTContext &C = CGF.getContext(); QualType KmpInt32Ty = @@ -4085,7 +4162,7 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope); CGF.EmitOMPReductionClauseInit(S, LoopScope); (void)LoopScope.Privatize(); - if (isOpenMPTargetExecutionDirective(S.getDirectiveKind())) + if (isOpenMPTargetExecutionDirective(EKind)) CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S); // Emit static non-chunked loop. @@ -4094,8 +4171,8 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { CGOpenMPRuntime::StaticRTInput StaticInit( /*IVSize=*/32, /*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(), LB.getAddress(), UB.getAddress(), ST.getAddress()); - CGF.CGM.getOpenMPRuntime().emitForStaticInit( - CGF, S.getBeginLoc(), S.getDirectiveKind(), ScheduleKind, StaticInit); + CGF.CGM.getOpenMPRuntime().emitForStaticInit(CGF, S.getBeginLoc(), EKind, + ScheduleKind, StaticInit); // UB = min(UB, GlobalUB); llvm::Value *UBVal = CGF.EmitLoadOfScalar(UB, S.getBeginLoc()); llvm::Value *MinUBGlobalUB = CGF.Builder.CreateSelect( @@ -4111,7 +4188,7 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(), OMPD_sections); }; - CGF.OMPCancelStack.emitExit(CGF, S.getDirectiveKind(), CodeGen); + CGF.OMPCancelStack.emitExit(CGF, EKind, CodeGen); CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel); // Emit post-update of the reduction variables if IsLastIter != 0. emitPostUpdateForReductionClause(CGF, S, [IL, &S](CodeGenFunction &CGF) { @@ -4132,7 +4209,7 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { HasCancel = OSD->hasCancel(); else if (auto *OPSD = dyn_cast(&S)) HasCancel = OPSD->hasCancel(); - OMPCancelStackRAII CancelRegion(*this, S.getDirectiveKind(), HasCancel); + OMPCancelStackRAII CancelRegion(*this, EKind, HasCancel); CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen, HasCancel); // Emit barrier for lastprivates only if 'sections' directive has 'nowait' @@ -4252,7 +4329,7 @@ void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { // Build a list of copyprivate variables along with helper expressions // (, , = expressions) for (const auto *C : S.getClausesOfKind()) { - CopyprivateVars.append(C->varlists().begin(), C->varlists().end()); + CopyprivateVars.append(C->varlist_begin(), C->varlist_end()); DestExprs.append(C->destination_exprs().begin(), C->destination_exprs().end()); SrcExprs.append(C->source_exprs().begin(), C->source_exprs().end()); @@ -4958,7 +5035,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( auto IPriv = C->privates().begin(); auto IRed = C->reduction_ops().begin(); auto ITD = C->taskgroup_descriptors().begin(); - for (const Expr *Ref : C->varlists()) { + for (const Expr *Ref : C->varlist()) { InRedVars.emplace_back(Ref); InRedPrivs.emplace_back(*IPriv); InRedOps.emplace_back(*IRed); @@ -5010,12 +5087,12 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( Action.Enter(CGF); BodyGen(CGF); }; + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(S); llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction( - S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, Data.Tied, - Data.NumberOfParts); + S, *I, *PartId, *TaskT, EKind, CodeGen, Data.Tied, Data.NumberOfParts); OMPLexicalScope Scope(*this, S, std::nullopt, - !isOpenMPParallelDirective(S.getDirectiveKind()) && - !isOpenMPSimdDirective(S.getDirectiveKind())); + !isOpenMPParallelDirective(EKind) && + !isOpenMPSimdDirective(EKind)); TaskGen(*this, OutlinedFn, Data); } @@ -5121,7 +5198,8 @@ void CodeGenFunction::EmitOMPTargetTaskBasedDirective( } (void)TargetScope.Privatize(); buildDependences(S, Data); - auto &&CodeGen = [&Data, &S, CS, &BodyGen, BPVD, PVD, SVD, MVD, + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(S); + auto &&CodeGen = [&Data, &S, CS, &BodyGen, BPVD, PVD, SVD, MVD, EKind, &InputInfo](CodeGenFunction &CGF, PrePostActionTy &Action) { // Set proper addresses for generated private copies. OMPPrivateScope Scope(CGF); @@ -5176,7 +5254,7 @@ void CodeGenFunction::EmitOMPTargetTaskBasedDirective( OMPLexicalScope LexScope(CGF, S, OMPD_task, /*EmitPreInitStmt=*/false); auto *TL = S.getSingleClause(); if (CGF.CGM.getLangOpts().OpenMP >= 51 && - needsTaskBasedThreadLimit(S.getDirectiveKind()) && TL) { + needsTaskBasedThreadLimit(EKind) && TL) { // Emit __kmpc_set_thread_limit() to set the thread_limit for the task // enclosing this target region. This will indirectly set the thread_limit // for every applicable construct within target region. @@ -5186,7 +5264,7 @@ void CodeGenFunction::EmitOMPTargetTaskBasedDirective( BodyGen(CGF); }; llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction( - S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, /*Tied=*/true, + S, *I, *PartId, *TaskT, EKind, CodeGen, /*Tied=*/true, Data.NumberOfParts); llvm::APInt TrueOrFalse(32, S.hasClausesOfKind() ? 1 : 0); IntegerLiteral IfCond(getContext(), TrueOrFalse, @@ -5201,8 +5279,9 @@ void CodeGenFunction::processInReduction(const OMPExecutableDirective &S, CodeGenFunction &CGF, const CapturedStmt *CS, OMPPrivateScope &Scope) { + OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(S); if (Data.Reductions) { - OpenMPDirectiveKind CapturedRegion = S.getDirectiveKind(); + OpenMPDirectiveKind CapturedRegion = EKind; OMPLexicalScope LexScope(CGF, S, CapturedRegion); ReductionCodeGen RedCG(Data.ReductionVars, Data.ReductionVars, Data.ReductionCopies, Data.ReductionOps); @@ -5239,7 +5318,7 @@ void CodeGenFunction::processInReduction(const OMPExecutableDirective &S, auto IPriv = C->privates().begin(); auto IRed = C->reduction_ops().begin(); auto ITD = C->taskgroup_descriptors().begin(); - for (const Expr *Ref : C->varlists()) { + for (const Expr *Ref : C->varlist()) { InRedVars.emplace_back(Ref); InRedPrivs.emplace_back(*IPriv); InRedOps.emplace_back(*IRed); @@ -5861,13 +5940,20 @@ void CodeGenFunction::EmitOMPDistributeLoop(const OMPLoopDirective &S, } } -void CodeGenFunction::EmitOMPDistributeDirective( - const OMPDistributeDirective &S) { +// Pass OMPLoopDirective (instead of OMPDistributeDirective) to make this +// function available for "loop bind(teams)", which maps to "distribute". +void emitOMPDistributeDirective(const OMPLoopDirective &S, CodeGenFunction &CGF, + CodeGenModule &CGM) { auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc()); }; - OMPLexicalScope Scope(*this, S, OMPD_unknown); - CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen); + OMPLexicalScope Scope(CGF, S, OMPD_unknown); + CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute, CodeGen); +} + +void CodeGenFunction::EmitOMPDistributeDirective( + const OMPDistributeDirective &S) { + emitOMPDistributeDirective(S, *this, CGM); } static llvm::Function *emitOutlinedOrderedFunction(CodeGenModule &CGM, @@ -6240,8 +6326,8 @@ static std::pair emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X, UpdateVal = CGF.Builder.CreateCast(llvm::Instruction::CastOps::UIToFP, IC, X.getAddress().getElementType()); } - llvm::Value *Res = - CGF.Builder.CreateAtomicRMW(RMWOp, X.getAddress(), UpdateVal, AO); + llvm::AtomicRMWInst *Res = + CGF.emitAtomicRMWInst(RMWOp, X.getAddress(), UpdateVal, AO); return std::make_pair(true, RValue::get(Res)); } @@ -7260,7 +7346,7 @@ void CodeGenFunction::EmitOMPUseDevicePtrClause( const llvm::DenseMap CaptureDeviceAddrMap) { llvm::SmallDenseSet, 4> Processed; - for (const Expr *OrigVarIt : C.varlists()) { + for (const Expr *OrigVarIt : C.varlist()) { const auto *OrigVD = cast(cast(OrigVarIt)->getDecl()); if (!Processed.insert(OrigVD).second) continue; @@ -7311,7 +7397,7 @@ void CodeGenFunction::EmitOMPUseDeviceAddrClause( const llvm::DenseMap CaptureDeviceAddrMap) { llvm::SmallDenseSet, 4> Processed; - for (const Expr *Ref : C.varlists()) { + for (const Expr *Ref : C.varlist()) { const VarDecl *OrigVD = getBaseDecl(Ref); if (!Processed.insert(OrigVD).second) continue; @@ -7408,13 +7494,13 @@ void CodeGenFunction::EmitOMPTargetDataDirective( if (CGM.getLangOpts().OMPTargetTriples.empty()) { // Emit helper decls of the use_device_ptr/use_device_addr clauses. for (const auto *C : S.getClausesOfKind()) - for (const Expr *E : C->varlists()) { + for (const Expr *E : C->varlist()) { const Decl *D = cast(E)->getDecl(); if (const auto *OED = dyn_cast(D)) CGF.EmitVarDecl(*OED); } for (const auto *C : S.getClausesOfKind()) - for (const Expr *E : C->varlists()) { + for (const Expr *E : C->varlist()) { const Decl *D = getBaseDecl(E); if (const auto *OED = dyn_cast(D)) CGF.EmitVarDecl(*OED); @@ -7903,6 +7989,24 @@ void CodeGenFunction::EmitOMPTargetUpdateDirective( void CodeGenFunction::EmitOMPGenericLoopDirective( const OMPGenericLoopDirective &S) { + // Always expect a bind clause on the loop directive. It it wasn't + // in the source, it should have been added in sema. + + OpenMPBindClauseKind BindKind = OMPC_BIND_unknown; + if (const auto *C = S.getSingleClause()) + BindKind = C->getBindKind(); + + switch (BindKind) { + case OMPC_BIND_parallel: // for + return emitOMPForDirective(S, *this, CGM, /*HasCancel=*/false); + case OMPC_BIND_teams: // distribute + return emitOMPDistributeDirective(S, *this, CGM); + case OMPC_BIND_thread: // simd + return emitOMPSimdDirective(S, *this, CGM); + case OMPC_BIND_unknown: + break; + } + // Unimplemented, just inline the underlying statement for now. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { // Emit the loop iteration variable. @@ -8128,7 +8232,7 @@ void CodeGenFunction::EmitSimpleOMPExecutableDirective( if (isOpenMPTaskingDirective(D.getDirectiveKind())) { // Capture global firstprivates to avoid crash. for (const auto *C : D.getClausesOfKind()) { - for (const Expr *Ref : C->varlists()) { + for (const Expr *Ref : C->varlist()) { const auto *DRE = cast(Ref->IgnoreParenImpCasts()); if (!DRE) continue; diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h index f1ba3cf95ae59..c4ec8d207d2e3 100644 --- a/clang/lib/CodeGen/CGValue.h +++ b/clang/lib/CodeGen/CGValue.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_LIB_CODEGEN_CGVALUE_H #include "Address.h" +#include "CGPointerAuthInfo.h" #include "CodeGenTBAA.h" #include "EHScopeStack.h" #include "clang/AST/ASTContext.h" @@ -233,9 +234,6 @@ class LValue { // this lvalue. bool Nontemporal : 1; - // The pointer is known not to be null. - bool IsKnownNonNull : 1; - LValueBaseInfo BaseInfo; TBAAAccessInfo TBAAInfo; @@ -263,7 +261,6 @@ class LValue { this->ImpreciseLifetime = false; this->Nontemporal = false; this->ThreadLocalRef = false; - this->IsKnownNonNull = false; this->BaseIvarExp = nullptr; } @@ -349,28 +346,26 @@ class LValue { LValueBaseInfo getBaseInfo() const { return BaseInfo; } void setBaseInfo(LValueBaseInfo Info) { BaseInfo = Info; } - KnownNonNull_t isKnownNonNull() const { - return (KnownNonNull_t)IsKnownNonNull; - } + KnownNonNull_t isKnownNonNull() const { return Addr.isKnownNonNull(); } LValue setKnownNonNull() { - IsKnownNonNull = true; + Addr.setKnownNonNull(); return *this; } // simple lvalue - llvm::Value *getPointer(CodeGenFunction &CGF) const { - assert(isSimple()); - return Addr.getBasePointer(); - } - llvm::Value *emitRawPointer(CodeGenFunction &CGF) const { - assert(isSimple()); - return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr; - } + llvm::Value *getPointer(CodeGenFunction &CGF) const; + llvm::Value *emitResignedPointer(QualType PointeeTy, + CodeGenFunction &CGF) const; + llvm::Value *emitRawPointer(CodeGenFunction &CGF) const; Address getAddress() const { return Addr; } void setAddress(Address address) { Addr = address; } + CGPointerAuthInfo getPointerAuthInfo() const { + return Addr.getPointerAuthInfo(); + } + // vector elt lvalue Address getVectorAddress() const { assert(isVectorElt()); diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt index dd147f45d1351..dd2f7ed021029 100644 --- a/clang/lib/CodeGen/CMakeLists.txt +++ b/clang/lib/CodeGen/CMakeLists.txt @@ -113,7 +113,7 @@ add_clang_library(clangCodeGen MacroPPCallbacks.cpp MicrosoftCXXABI.cpp ModuleBuilder.cpp - ObjectFilePCHContainerOperations.cpp + ObjectFilePCHContainerWriter.cpp PatternInit.cpp SanitizerMetadata.cpp SwiftCallingConv.cpp diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 3cc4e093d2cf8..dc9eb90079458 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -197,34 +197,46 @@ CodeGenFunction::CGFPOptionsRAII::~CGFPOptionsRAII() { CGF.Builder.setDefaultConstrainedRounding(OldRounding); } -static LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, - bool ForPointeeType, - CodeGenFunction &CGF) { +static LValue +makeNaturalAlignAddrLValue(llvm::Value *V, QualType T, bool ForPointeeType, + bool MightBeSigned, CodeGenFunction &CGF, + KnownNonNull_t IsKnownNonNull = NotKnownNonNull) { LValueBaseInfo BaseInfo; TBAAAccessInfo TBAAInfo; CharUnits Alignment = CGF.CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo, ForPointeeType); - Address Addr = Address(V, CGF.ConvertTypeForMem(T), Alignment); + Address Addr = + MightBeSigned + ? CGF.makeNaturalAddressForPointer(V, T, Alignment, false, nullptr, + nullptr, IsKnownNonNull) + : Address(V, CGF.ConvertTypeForMem(T), Alignment, IsKnownNonNull); return CGF.MakeAddrLValue(Addr, T, BaseInfo, TBAAInfo); } -LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) { - return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false, *this); +LValue +CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, + KnownNonNull_t IsKnownNonNull) { + return ::makeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false, + /*MightBeSigned*/ true, *this, + IsKnownNonNull); } LValue CodeGenFunction::MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T) { - return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true, *this); + return ::makeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true, + /*MightBeSigned*/ true, *this); } LValue CodeGenFunction::MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T) { - return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false, *this); + return ::makeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false, + /*MightBeSigned*/ false, *this); } LValue CodeGenFunction::MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V, QualType T) { - return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true, *this); + return ::makeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true, + /*MightBeSigned*/ false, *this); } llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) { @@ -1074,6 +1086,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, const CodeGenOptions &CodeGenOpts = CGM.getCodeGenOpts(); if (CodeGenOpts.PointerAuth.FunctionPointers) Fn->addFnAttr("ptrauth-calls"); + if (CodeGenOpts.PointerAuth.IndirectGotos) + Fn->addFnAttr("ptrauth-indirect-gotos"); // Apply xray attributes to the function (as a string, for now) bool AlwaysXRayAttr = false; @@ -1181,6 +1195,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, if (D && D->hasAttr()) Fn->addFnAttr(llvm::Attribute::NoProfile); + if (D && D->hasAttr()) + Fn->addFnAttr(llvm::Attribute::HybridPatchable); + if (D) { // Function attributes take precedence over command line flags. if (auto *A = D->getAttr()) { @@ -3174,16 +3191,8 @@ void CodeGenFunction::EmitKCFIOperandBundle( llvm::Value *CodeGenFunction::FormAArch64ResolverCondition( const MultiVersionResolverOption &RO) { llvm::SmallVector CondFeatures; - for (const StringRef &Feature : RO.Conditions.Features) { - // Optimize the Function Multi Versioning resolver by creating conditions - // only for features that are not enabled in the target. The exception is - // for features whose extension instructions are executed as NOP on targets - // without extension support. - if (!getContext().getTargetInfo().hasFeature(Feature) || Feature == "bti" || - Feature == "memtag" || Feature == "memtag2" || Feature == "memtag3" || - Feature == "dgh") - CondFeatures.push_back(Feature); - } + for (const StringRef &Feature : RO.Conditions.Features) + CondFeatures.push_back(Feature); if (!CondFeatures.empty()) { return EmitAArch64CpuSupports(CondFeatures); } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index f38088e7de803..9f612c3e19b8f 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -202,7 +202,7 @@ template <> struct DominatingValue
{ } static type restore(CodeGenFunction &CGF, saved_type value) { return Address(DominatingLLVMValue::restore(CGF, value.BasePtr), - value.ElementType, value.Alignment, + value.ElementType, value.Alignment, CGPointerAuthInfo(), DominatingLLVMValue::restore(CGF, value.Offset)); } }; @@ -612,6 +612,9 @@ class CodeGenFunction : public CodeGenTypeCache { /// True if the current statement has always_inline attribute. bool InAlwaysInlineAttributedStmt = false; + /// True if the current statement has noconvergent attribute. + bool InNoConvergentAttributedStmt = false; + // The CallExpr within the current statement that the musttail attribute // applies to. nullptr if there is no 'musttail' on the current statement. const CallExpr *MustTailCall = nullptr; @@ -2711,7 +2714,8 @@ class CodeGenFunction : public CodeGenTypeCache { if (Alignment.isZero()) Alignment = CGM.getNaturalTypeAlignment(T, BaseInfo, TBAAInfo, ForPointeeType); - return Address(Ptr, ConvertTypeForMem(T), Alignment, nullptr, + return Address(Ptr, ConvertTypeForMem(T), Alignment, + CGM.getPointerAuthInfoForPointeeType(T), /*Offset=*/nullptr, IsKnownNonNull); } @@ -2752,7 +2756,9 @@ class CodeGenFunction : public CodeGenTypeCache { /// an l-value with the natural pointee alignment of T. LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T); - LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T); + LValue + MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, + KnownNonNull_t IsKnownNonNull = NotKnownNonNull); /// Same as MakeNaturalAlignPointeeAddrLValue except that the pointer is known /// to be unsigned. @@ -3326,9 +3332,9 @@ class CodeGenFunction : public CodeGenTypeCache { const FieldDecl *FindCountedByField(const FieldDecl *FD); /// Build an expression accessing the "counted_by" field. - llvm::Value *EmitCountedByFieldExpr(const Expr *Base, - const FieldDecl *FAMDecl, - const FieldDecl *CountDecl); + llvm::Value *EmitLoadOfCountedByField(const Expr *Base, + const FieldDecl *FAMDecl, + const FieldDecl *CountDecl); llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre); @@ -3839,6 +3845,8 @@ class CodeGenFunction : public CodeGenTypeCache { void EmitOMPSimdDirective(const OMPSimdDirective &S); void EmitOMPTileDirective(const OMPTileDirective &S); void EmitOMPUnrollDirective(const OMPUnrollDirective &S); + void EmitOMPReverseDirective(const OMPReverseDirective &S); + void EmitOMPInterchangeDirective(const OMPInterchangeDirective &S); void EmitOMPForDirective(const OMPForDirective &S); void EmitOMPForSimdDirective(const OMPForSimdDirective &S); void EmitOMPSectionsDirective(const OMPSectionsDirective &S); @@ -4177,6 +4185,13 @@ class CodeGenFunction : public CodeGenTypeCache { llvm::AtomicOrdering::SequentiallyConsistent, bool IsWeak = false, AggValueSlot Slot = AggValueSlot::ignored()); + /// Emit an atomicrmw instruction, and applying relevant metadata when + /// applicable. + llvm::AtomicRMWInst *emitAtomicRMWInst( + llvm::AtomicRMWInst::BinOp Op, Address Addr, llvm::Value *Val, + llvm::AtomicOrdering Order = llvm::AtomicOrdering::SequentiallyConsistent, + llvm::SyncScope::ID SSID = llvm::SyncScope::System); + void EmitAtomicUpdate(LValue LVal, llvm::AtomicOrdering AO, const llvm::function_ref &UpdateOp, bool IsVolatile); @@ -4391,7 +4406,8 @@ class CodeGenFunction : public CodeGenTypeCache { RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, - SourceLocation Loc); + SourceLocation Loc, + bool IsVirtualFunctionPointerThunk = false); RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke = nullptr, @@ -4445,10 +4461,6 @@ class CodeGenFunction : public CodeGenTypeCache { CXXDtorType Type, const CXXRecordDecl *RD); - llvm::Value *getAsNaturalPointerTo(Address Addr, QualType PointeeType) { - return Addr.getBasePointer(); - } - bool isPointerKnownNonNull(const Expr *E); /// Create the discriminator from the storage address and the entity hash. @@ -4458,16 +4470,36 @@ class CodeGenFunction : public CodeGenTypeCache { llvm::Value *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType); - llvm::Value *EmitPointerAuthSign(QualType PointeeType, llvm::Value *Pointer); + llvm::Value *EmitPointerAuthSign(const CGPointerAuthInfo &Info, llvm::Value *Pointer); + llvm::Value *EmitPointerAuthAuth(const CGPointerAuthInfo &Info, llvm::Value *Pointer); + llvm::Value *emitPointerAuthResign(llvm::Value *Pointer, QualType PointerType, + const CGPointerAuthInfo &CurAuthInfo, + const CGPointerAuthInfo &NewAuthInfo, + bool IsKnownNonNull); + llvm::Value *emitPointerAuthResignCall(llvm::Value *Pointer, + const CGPointerAuthInfo &CurInfo, + const CGPointerAuthInfo &NewInfo); + void EmitPointerAuthOperandBundle( const CGPointerAuthInfo &Info, SmallVectorImpl &Bundles); + llvm::Value *authPointerToPointerCast(llvm::Value *ResultPtr, + QualType SourceType, QualType DestType); + Address authPointerToPointerCast(Address Ptr, QualType SourceType, + QualType DestType); + + Address getAsNaturalAddressOf(Address Addr, QualType PointeeTy); + + llvm::Value *getAsNaturalPointerTo(Address Addr, QualType PointeeType) { + return getAsNaturalAddressOf(Addr, PointeeType).getBasePointer(); + } + // Return the copy constructor name with the prefix "__copy_constructor_" // removed. static std::string getNonTrivialCopyConstructorStr(QualType QT, @@ -4529,7 +4561,6 @@ class CodeGenFunction : public CodeGenTypeCache { RValue EmitNVPTXDevicePrintfCallExpr(const CallExpr *E); RValue EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E); - RValue EmitOpenMPDevicePrintfCallExpr(const CallExpr *E); RValue EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, const CallExpr *E, ReturnValueSlot ReturnValue); @@ -4697,6 +4728,9 @@ class CodeGenFunction : public CodeGenTypeCache { llvm::Value *EmitRISCVBuiltinExpr(unsigned BuiltinID, const CallExpr *E, ReturnValueSlot ReturnValue); + llvm::Value *EmitRISCVCpuSupports(const CallExpr *E); + llvm::Value *EmitRISCVCpuInit(); + void AddAMDGPUFenceAddressSpaceMMRA(llvm::Instruction *Inst, const CallExpr *E); void ProcessOrderScopeAMDGCN(llvm::Value *Order, llvm::Value *Scope, @@ -4852,9 +4886,10 @@ class CodeGenFunction : public CodeGenTypeCache { void EmitAggFinalDestCopy(QualType Type, AggValueSlot Dest, const LValue &Src, ExprValueKind SrcKind); - /// Build all the stores needed to initialize an aggregate at Dest with the - /// value Val. - void EmitAggregateStore(llvm::Value *Val, Address Dest, bool DestIsVolatile); + /// Create a store to \arg DstPtr from \arg Src, truncating the stored value + /// to at most \arg DstSize bytes. + void CreateCoercedStore(llvm::Value *Src, Address Dst, llvm::TypeSize DstSize, + bool DstIsVolatile); /// EmitExtendGCLifetime - Given a pointer to an Objective-C object, /// make sure it survives garbage collection until this point. diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index df5fd474494fc..7989964a7dc3c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -161,6 +161,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { return createWindowsAArch64TargetCodeGenInfo(CGM, AArch64ABIKind::Win64); else if (Target.getABI() == "aapcs-soft") Kind = AArch64ABIKind::AAPCSSoft; + else if (Target.getABI() == "pauthtest") + Kind = AArch64ABIKind::PAuthTest; return createAArch64TargetCodeGenInfo(CGM, Kind); } @@ -4193,8 +4195,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { // Forward declarations are emitted lazily on first use. if (!FD->doesThisDeclarationHaveABody()) { if (!FD->doesDeclarationForceExternallyVisibleDefinition() && - (!FD->isMultiVersion() || - !FD->getASTContext().getTargetInfo().getTriple().isAArch64())) + (!FD->isMultiVersion() || !getTarget().getTriple().isAArch64())) return; StringRef MangledName = getMangledName(GD); @@ -4472,6 +4473,11 @@ bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) { return true; const auto *F = cast(GD.getDecl()); + // Inline builtins declaration must be emitted. They often are fortified + // functions. + if (F->isInlineBuiltinDeclaration()) + return true; + if (CodeGenOpts.OptimizationLevel == 0 && !F->hasAttr()) return false; @@ -4517,11 +4523,6 @@ bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) { } } - // Inline builtins declaration must be emitted. They often are fortified - // functions. - if (F->isInlineBuiltinDeclaration()) - return true; - // PR9614. Avoid cases where the source code is lying to us. An available // externally function should have an equivalent function somewhere else, // but a function that calls itself through asm label/`__builtin_` trickery is @@ -4641,23 +4642,6 @@ llvm::GlobalValue::LinkageTypes getMultiversionLinkage(CodeGenModule &CGM, return llvm::GlobalValue::WeakODRLinkage; } -static FunctionDecl *createDefaultTargetVersionFrom(const FunctionDecl *FD) { - auto *DeclCtx = const_cast(FD->getDeclContext()); - TypeSourceInfo *TInfo = FD->getTypeSourceInfo(); - StorageClass SC = FD->getStorageClass(); - DeclarationName Name = FD->getNameInfo().getName(); - - FunctionDecl *NewDecl = - FunctionDecl::Create(FD->getASTContext(), DeclCtx, FD->getBeginLoc(), - FD->getEndLoc(), Name, TInfo->getType(), TInfo, SC); - - NewDecl->setIsMultiVersion(); - NewDecl->addAttr(TargetVersionAttr::CreateImplicit( - NewDecl->getASTContext(), "default", NewDecl->getSourceRange())); - - return NewDecl; -} - void CodeGenModule::emitMultiVersionFunctions() { std::vector MVFuncsToEmit; MultiVersionFuncs.swap(MVFuncsToEmit); @@ -4684,29 +4668,30 @@ void CodeGenModule::emitMultiVersionFunctions() { return cast(Func); }; - bool HasDefaultDecl = !FD->isTargetVersionMultiVersion(); - bool ShouldEmitResolver = - !getContext().getTargetInfo().getTriple().isAArch64(); + // For AArch64, a resolver is only emitted if a function marked with + // target_version("default")) or target_clones() is present and defined + // in this TU. For other architectures it is always emitted. + bool ShouldEmitResolver = !getTarget().getTriple().isAArch64(); SmallVector Options; getContext().forEachMultiversionedFunctionVersion( FD, [&](const FunctionDecl *CurFD) { llvm::SmallVector Feats; + bool IsDefined = CurFD->doesThisDeclarationHaveABody(); if (const auto *TA = CurFD->getAttr()) { TA->getAddedFeatures(Feats); llvm::Function *Func = createFunction(CurFD); Options.emplace_back(Func, TA->getArchitecture(), Feats); } else if (const auto *TVA = CurFD->getAttr()) { - bool HasDefaultDef = TVA->isDefaultVersion() && - CurFD->doesThisDeclarationHaveABody(); - HasDefaultDecl |= TVA->isDefaultVersion(); - ShouldEmitResolver |= (CurFD->isUsed() || HasDefaultDef); + if (TVA->isDefaultVersion() && IsDefined) + ShouldEmitResolver = true; TVA->getFeatures(Feats); llvm::Function *Func = createFunction(CurFD); Options.emplace_back(Func, /*Architecture*/ "", Feats); } else if (const auto *TC = CurFD->getAttr()) { - ShouldEmitResolver |= CurFD->doesThisDeclarationHaveABody(); + if (IsDefined) + ShouldEmitResolver = true; for (unsigned I = 0; I < TC->featuresStrs_size(); ++I) { if (!TC->isFirstOfVersion(I)) continue; @@ -4732,13 +4717,6 @@ void CodeGenModule::emitMultiVersionFunctions() { if (!ShouldEmitResolver) continue; - if (!HasDefaultDecl) { - FunctionDecl *NewFD = createDefaultTargetVersionFrom(FD); - llvm::Function *Func = createFunction(NewFD); - llvm::SmallVector Feats; - Options.emplace_back(Func, /*Architecture*/ "", Feats); - } - llvm::Constant *ResolverConstant = GetOrCreateMultiVersionResolver(GD); if (auto *IFunc = dyn_cast(ResolverConstant)) { ResolverConstant = IFunc->getResolver(); @@ -4787,6 +4765,14 @@ void CodeGenModule::emitMultiVersionFunctions() { emitMultiVersionFunctions(); } +static void replaceDeclarationWith(llvm::GlobalValue *Old, + llvm::Constant *New) { + assert(cast(Old)->isDeclaration() && "Not a declaration"); + New->takeName(Old); + Old->replaceAllUsesWith(New); + Old->eraseFromParent(); +} + void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { const auto *FD = cast(GD.getDecl()); assert(FD && "Not a FunctionDecl?"); @@ -4891,12 +4877,9 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { // Fix up function declarations that were created for cpu_specific before // cpu_dispatch was known if (!isa(IFunc)) { - assert(cast(IFunc)->isDeclaration()); auto *GI = llvm::GlobalIFunc::create(DeclTy, 0, Linkage, "", ResolverFunc, &getModule()); - GI->takeName(IFunc); - IFunc->replaceAllUsesWith(GI); - IFunc->eraseFromParent(); + replaceDeclarationWith(IFunc, GI); IFunc = GI; } @@ -4926,7 +4909,8 @@ void CodeGenModule::AddDeferredMultiVersionResolverToEmit(GlobalDecl GD) { } /// If a dispatcher for the specified mangled name is not in the module, create -/// and return an llvm Function with the specified type. +/// and return it. The dispatcher is either an llvm Function with the specified +/// type, or a global ifunc. llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { const auto *FD = cast(GD.getDecl()); assert(FD && "Not a FunctionDecl?"); @@ -4954,8 +4938,15 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { ResolverName += ".resolver"; } - // If the resolver has already been created, just return it. - if (llvm::GlobalValue *ResolverGV = GetGlobalValue(ResolverName)) + // If the resolver has already been created, just return it. This lookup may + // yield a function declaration instead of a resolver on AArch64. That is + // because we didn't know whether a resolver will be generated when we first + // encountered a use of the symbol named after this resolver. Therefore, + // targets which support ifuncs should not return here unless we actually + // found an ifunc. + llvm::GlobalValue *ResolverGV = GetGlobalValue(ResolverName); + if (ResolverGV && + (isa(ResolverGV) || !getTarget().supportsIFunc())) return ResolverGV; const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD); @@ -4981,7 +4972,8 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { "", Resolver, &getModule()); GIF->setName(ResolverName); SetCommonAttributes(FD, GIF); - + if (ResolverGV) + replaceDeclarationWith(ResolverGV, GIF); return GIF; } @@ -4990,6 +4982,8 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { assert(isa(Resolver) && "Resolver should be created for the first time"); SetCommonAttributes(FD, cast(Resolver)); + if (ResolverGV) + replaceDeclarationWith(ResolverGV, Resolver); return Resolver; } @@ -5019,6 +5013,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( ForDefinition_t IsForDefinition) { const Decl *D = GD.getDecl(); + std::string NameWithoutMultiVersionMangling; // Any attempts to use a MultiVersion function should result in retrieving // the iFunc instead. Name Mangling will handle the rest of the changes. if (const FunctionDecl *FD = cast_or_null(D)) { @@ -5040,14 +5035,24 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( if (FD->isMultiVersion()) { UpdateMultiVersionNames(GD, FD, MangledName); - if (FD->getASTContext().getTargetInfo().getTriple().isAArch64() && - !FD->isUsed()) - AddDeferredMultiVersionResolverToEmit(GD); - else if (!IsForDefinition) - return GetOrCreateMultiVersionResolver(GD); + if (!IsForDefinition) { + // On AArch64 we do not immediatelly emit an ifunc resolver when a + // function is used. Instead we defer the emission until we see a + // default definition. In the meantime we just reference the symbol + // without FMV mangling (it may or may not be replaced later). + if (getTarget().getTriple().isAArch64()) { + AddDeferredMultiVersionResolverToEmit(GD); + NameWithoutMultiVersionMangling = getMangledNameImpl( + *this, GD, FD, /*OmitMultiVersionMangling=*/true); + } else + return GetOrCreateMultiVersionResolver(GD); + } } } + if (!NameWithoutMultiVersionMangling.empty()) + MangledName = NameWithoutMultiVersionMangling; + // Lookup the entry, lazily creating it if necessary. llvm::GlobalValue *Entry = GetGlobalValue(MangledName); if (Entry) { @@ -6342,7 +6347,7 @@ void CodeGenModule::EmitExternalFunctionDeclaration(const FunctionDecl *FD) { if (getCodeGenOpts().hasReducedDebugInfo()) { auto *Ty = getTypes().ConvertType(FD->getType()); StringRef MangledName = getMangledName(FD); - auto *Fn = dyn_cast( + auto *Fn = cast( GetOrCreateLLVMFunction(MangledName, Ty, FD, /* ForVTable */ false)); if (!Fn->getSubprogram()) DI->EmitFunctionDecl(FD, FD->getLocation(), FD->getType(), Fn); @@ -8183,7 +8188,7 @@ void CodeGenModule::EmitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) { // Do not emit threadprivates in simd-only mode. if (LangOpts.OpenMP && LangOpts.OpenMPSimd) return; - for (auto RefExpr : D->varlists()) { + for (auto RefExpr : D->varlist()) { auto *VD = cast(cast(RefExpr)->getDecl()); bool PerformInit = VD->getAnyInitializer() && diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index de27d590ebdf3..6564a029bcfe9 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -993,8 +993,16 @@ class CodeGenModule : public CodeGenTypeCache { llvm::Constant *getFunctionPointer(llvm::Constant *Pointer, QualType FunctionType); + llvm::Constant *getMemberFunctionPointer(const FunctionDecl *FD, + llvm::Type *Ty = nullptr); + + llvm::Constant *getMemberFunctionPointer(llvm::Constant *Pointer, + QualType FT); + CGPointerAuthInfo getFunctionPointerAuthInfo(QualType T); + CGPointerAuthInfo getMemberFunctionPointerAuthInfo(QualType FT); + CGPointerAuthInfo getPointerAuthInfoForPointeeType(QualType type); CGPointerAuthInfo getPointerAuthInfoForType(QualType type); diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index b889d1bfe003f..b66b6234c9d3d 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -186,10 +186,56 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) { return getChar(); // Handle pointers and references. - // TODO: Implement C++'s type "similarity" and consider dis-"similar" - // pointers distinct. - if (Ty->isPointerType() || Ty->isReferenceType()) - return createScalarTypeNode("any pointer", getChar(), Size); + // + // C has a very strict rule for pointer aliasing. C23 6.7.6.1p2: + // For two pointer types to be compatible, both shall be identically + // qualified and both shall be pointers to compatible types. + // + // This rule is impractically strict; we want to at least ignore CVR + // qualifiers. Distinguishing by CVR qualifiers would make it UB to + // e.g. cast a `char **` to `const char * const *` and dereference it, + // which is too common and useful to invalidate. C++'s similar types + // rule permits qualifier differences in these nested positions; in fact, + // C++ even allows that cast as an implicit conversion. + // + // Other qualifiers could theoretically be distinguished, especially if + // they involve a significant representation difference. We don't + // currently do so, however. + // + // Computing the pointee type string recursively is implicitly more + // forgiving than the standards require. Effectively, we are turning + // the question "are these types compatible/similar" into "are + // accesses to these types allowed to alias". In both C and C++, + // the latter question has special carve-outs for signedness + // mismatches that only apply at the top level. As a result, we are + // allowing e.g. `int *` l-values to access `unsigned *` objects. + if (Ty->isPointerType() || Ty->isReferenceType()) { + llvm::MDNode *AnyPtr = createScalarTypeNode("any pointer", getChar(), Size); + if (!CodeGenOpts.PointerTBAA) + return AnyPtr; + // Compute the depth of the pointer and generate a tag of the form "p + // ". + unsigned PtrDepth = 0; + do { + PtrDepth++; + Ty = Ty->getPointeeType().getTypePtr(); + } while (Ty->isPointerType()); + // TODO: Implement C++'s type "similarity" and consider dis-"similar" + // pointers distinct for non-builtin types. + if (isa(Ty)) { + llvm::MDNode *ScalarMD = getTypeInfoHelper(Ty); + StringRef Name = + cast( + ScalarMD->getOperand(CodeGenOpts.NewStructPathTBAA ? 2 : 0)) + ->getString(); + SmallString<256> OutName("p"); + OutName += std::to_string(PtrDepth); + OutName += " "; + OutName += Name; + return createScalarTypeNode(OutName, AnyPtr, Size); + } + return AnyPtr; + } // Accesses to arrays are accesses to objects of their element types. if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType()) diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 63be23bf22527..5108712ca7e37 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -388,6 +388,9 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { bool NeedsVTTParameter(GlobalDecl GD) override; + llvm::Constant * + getOrCreateVirtualFunctionPointerThunk(const CXXMethodDecl *MD); + /**************************** RTTI Uniqueness ******************************/ protected: @@ -426,6 +429,9 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { const CXXRecordDecl *RD) override; private: + llvm::Constant * + getSignedVirtualMemberFunctionPointer(const CXXMethodDecl *MD); + bool hasAnyUnusedVirtualInlineFunction(const CXXRecordDecl *RD) const { const auto &VtableLayout = CGM.getItaniumVTableContext().getVTableLayout(RD); @@ -837,7 +843,25 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( CalleePtr->addIncoming(VirtualFn, FnVirtual); CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual); - CGCallee Callee(FPT, CalleePtr); + CGPointerAuthInfo PointerAuth; + + if (const auto &Schema = + CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers) { + llvm::PHINode *DiscriminatorPHI = Builder.CreatePHI(CGF.IntPtrTy, 2); + DiscriminatorPHI->addIncoming(llvm::ConstantInt::get(CGF.IntPtrTy, 0), + FnVirtual); + const auto &AuthInfo = + CGM.getMemberFunctionPointerAuthInfo(QualType(MPT, 0)); + assert(Schema.getKey() == AuthInfo.getKey() && + "Keys for virtual and non-virtual member functions must match"); + auto *NonVirtualDiscriminator = AuthInfo.getDiscriminator(); + DiscriminatorPHI->addIncoming(NonVirtualDiscriminator, FnNonVirtual); + PointerAuth = CGPointerAuthInfo( + Schema.getKey(), Schema.getAuthenticationMode(), Schema.isIsaPointer(), + Schema.authenticatesNullValues(), DiscriminatorPHI); + } + + CGCallee Callee(FPT, CalleePtr, PointerAuth); return Callee; } @@ -855,6 +879,25 @@ llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress( "memptr.offset"); } +// See if it's possible to return a constant signed pointer. +static llvm::Constant *pointerAuthResignConstant( + llvm::Value *Ptr, const CGPointerAuthInfo &CurAuthInfo, + const CGPointerAuthInfo &NewAuthInfo, CodeGenModule &CGM) { + const auto *CPA = dyn_cast(Ptr); + + if (!CPA) + return nullptr; + + assert(CPA->getKey()->getZExtValue() == CurAuthInfo.getKey() && + CPA->getAddrDiscriminator()->isZeroValue() && + CPA->getDiscriminator() == CurAuthInfo.getDiscriminator() && + "unexpected key or discriminators"); + + return CGM.getConstantSignedPointer( + CPA->getPointer(), NewAuthInfo.getKey(), nullptr, + cast(NewAuthInfo.getDiscriminator())); +} + /// Perform a bitcast, derived-to-base, or base-to-derived member pointer /// conversion. /// @@ -882,21 +925,63 @@ llvm::Value * ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *src) { + // Use constant emission if we can. + if (isa(src)) + return EmitMemberPointerConversion(E, cast(src)); + assert(E->getCastKind() == CK_DerivedToBaseMemberPointer || E->getCastKind() == CK_BaseToDerivedMemberPointer || E->getCastKind() == CK_ReinterpretMemberPointer); + CGBuilderTy &Builder = CGF.Builder; + QualType DstType = E->getType(); + + if (DstType->isMemberFunctionPointerType()) { + if (const auto &NewAuthInfo = + CGM.getMemberFunctionPointerAuthInfo(DstType)) { + QualType SrcType = E->getSubExpr()->getType(); + assert(SrcType->isMemberFunctionPointerType()); + const auto &CurAuthInfo = CGM.getMemberFunctionPointerAuthInfo(SrcType); + llvm::Value *MemFnPtr = Builder.CreateExtractValue(src, 0, "memptr.ptr"); + llvm::Type *OrigTy = MemFnPtr->getType(); + + llvm::BasicBlock *StartBB = Builder.GetInsertBlock(); + llvm::BasicBlock *ResignBB = CGF.createBasicBlock("resign"); + llvm::BasicBlock *MergeBB = CGF.createBasicBlock("merge"); + + // Check whether we have a virtual offset or a pointer to a function. + assert(UseARMMethodPtrABI && "ARM ABI expected"); + llvm::Value *Adj = Builder.CreateExtractValue(src, 1, "memptr.adj"); + llvm::Constant *Ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1); + llvm::Value *AndVal = Builder.CreateAnd(Adj, Ptrdiff_1); + llvm::Value *IsVirtualOffset = + Builder.CreateIsNotNull(AndVal, "is.virtual.offset"); + Builder.CreateCondBr(IsVirtualOffset, MergeBB, ResignBB); + + CGF.EmitBlock(ResignBB); + llvm::Type *PtrTy = llvm::PointerType::getUnqual(CGM.Int8Ty); + MemFnPtr = Builder.CreateIntToPtr(MemFnPtr, PtrTy); + MemFnPtr = + CGF.emitPointerAuthResign(MemFnPtr, SrcType, CurAuthInfo, NewAuthInfo, + isa(src)); + MemFnPtr = Builder.CreatePtrToInt(MemFnPtr, OrigTy); + llvm::Value *ResignedVal = Builder.CreateInsertValue(src, MemFnPtr, 0); + ResignBB = Builder.GetInsertBlock(); + + CGF.EmitBlock(MergeBB); + llvm::PHINode *NewSrc = Builder.CreatePHI(src->getType(), 2); + NewSrc->addIncoming(src, StartBB); + NewSrc->addIncoming(ResignedVal, ResignBB); + src = NewSrc; + } + } + // Under Itanium, reinterprets don't require any additional processing. if (E->getCastKind() == CK_ReinterpretMemberPointer) return src; - // Use constant emission if we can. - if (isa(src)) - return EmitMemberPointerConversion(E, cast(src)); - llvm::Constant *adj = getMemberPointerAdjustment(E); if (!adj) return src; - CGBuilderTy &Builder = CGF.Builder; bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); const MemberPointerType *destTy = @@ -934,6 +1019,34 @@ ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, return Builder.CreateInsertValue(src, dstAdj, 1); } +static llvm::Constant * +pointerAuthResignMemberFunctionPointer(llvm::Constant *Src, QualType DestType, + QualType SrcType, CodeGenModule &CGM) { + assert(DestType->isMemberFunctionPointerType() && + SrcType->isMemberFunctionPointerType() && + "member function pointers expected"); + if (DestType == SrcType) + return Src; + + const auto &NewAuthInfo = CGM.getMemberFunctionPointerAuthInfo(DestType); + const auto &CurAuthInfo = CGM.getMemberFunctionPointerAuthInfo(SrcType); + + if (!NewAuthInfo && !CurAuthInfo) + return Src; + + llvm::Constant *MemFnPtr = Src->getAggregateElement(0u); + if (MemFnPtr->getNumOperands() == 0) { + // src must be a pair of null pointers. + assert(isa(MemFnPtr) && "constant int expected"); + return Src; + } + + llvm::Constant *ConstPtr = pointerAuthResignConstant( + cast(MemFnPtr)->getOperand(0), CurAuthInfo, NewAuthInfo, CGM); + ConstPtr = llvm::ConstantExpr::getPtrToInt(ConstPtr, MemFnPtr->getType()); + return ConstantFoldInsertValueInstruction(Src, ConstPtr, 0); +} + llvm::Constant * ItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E, llvm::Constant *src) { @@ -941,6 +1054,12 @@ ItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E, E->getCastKind() == CK_BaseToDerivedMemberPointer || E->getCastKind() == CK_ReinterpretMemberPointer); + QualType DstType = E->getType(); + + if (DstType->isMemberFunctionPointerType()) + src = pointerAuthResignMemberFunctionPointer( + src, DstType, E->getSubExpr()->getType(), CGM); + // Under Itanium, reinterprets don't require any additional processing. if (E->getCastKind() == CK_ReinterpretMemberPointer) return src; @@ -1038,9 +1157,32 @@ llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD, // least significant bit of adj then makes exactly the same // discrimination as the least significant bit of ptr does for // Itanium. - MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset); - MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, - 2 * ThisAdjustment.getQuantity() + 1); + + // We cannot use the Itanium ABI's representation for virtual member + // function pointers under pointer authentication because it would + // require us to store both the virtual offset and the constant + // discriminator in the pointer, which would be immediately vulnerable + // to attack. Instead we introduce a thunk that does the virtual dispatch + // and store it as if it were a non-virtual member function. This means + // that virtual function pointers may not compare equal anymore, but + // fortunately they aren't required to by the standard, and we do make + // a best-effort attempt to re-use the thunk. + // + // To support interoperation with code in which pointer authentication + // is disabled, derefencing a member function pointer must still handle + // the virtual case, but it can use a discriminator which should never + // be valid. + const auto &Schema = + CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers; + if (Schema) + MemPtr[0] = llvm::ConstantExpr::getPtrToInt( + getSignedVirtualMemberFunctionPointer(MD), CGM.PtrDiffTy); + else + MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset); + // Don't set the LSB of adj to 1 if pointer authentication for member + // function pointers is enabled. + MemPtr[1] = llvm::ConstantInt::get( + CGM.PtrDiffTy, 2 * ThisAdjustment.getQuantity() + !Schema); } else { // Itanium C++ ABI 2.3: // For a virtual function, [the pointer field] is 1 plus the @@ -1062,7 +1204,7 @@ llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD, // function type is incomplete. Ty = CGM.PtrDiffTy; } - llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty); + llvm::Constant *addr = CGM.getMemberFunctionPointer(MD, Ty); MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy); MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, @@ -1082,8 +1224,12 @@ llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP, CharUnits ThisAdjustment = getContext().getMemberPointerPathAdjustment(MP); - if (const CXXMethodDecl *MD = dyn_cast(MPD)) - return BuildMemberPointer(MD, ThisAdjustment); + if (const CXXMethodDecl *MD = dyn_cast(MPD)) { + llvm::Constant *Src = BuildMemberPointer(MD, ThisAdjustment); + QualType SrcType = getContext().getMemberPointerType( + MD->getType(), MD->getParent()->getTypeForDecl()); + return pointerAuthResignMemberFunctionPointer(Src, MPType, SrcType, CGM); + } CharUnits FieldOffset = getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD)); @@ -3189,6 +3335,78 @@ bool ItaniumCXXABI::NeedsVTTParameter(GlobalDecl GD) { return false; } +llvm::Constant * +ItaniumCXXABI::getOrCreateVirtualFunctionPointerThunk(const CXXMethodDecl *MD) { + SmallString<256> MethodName; + llvm::raw_svector_ostream Out(MethodName); + getMangleContext().mangleCXXName(MD, Out); + MethodName += "_vfpthunk_"; + StringRef ThunkName = MethodName.str(); + llvm::Function *ThunkFn; + if ((ThunkFn = cast_or_null( + CGM.getModule().getNamedValue(ThunkName)))) + return ThunkFn; + + const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeCXXMethodDeclaration(MD); + llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo); + llvm::GlobalValue::LinkageTypes Linkage = + MD->isExternallyVisible() ? llvm::GlobalValue::LinkOnceODRLinkage + : llvm::GlobalValue::InternalLinkage; + ThunkFn = + llvm::Function::Create(ThunkTy, Linkage, ThunkName, &CGM.getModule()); + if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage) + ThunkFn->setVisibility(llvm::GlobalValue::HiddenVisibility); + assert(ThunkFn->getName() == ThunkName && "name was uniqued!"); + + CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn, /*IsThunk=*/true); + CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn); + + // Stack protection sometimes gets inserted after the musttail call. + ThunkFn->removeFnAttr(llvm::Attribute::StackProtect); + ThunkFn->removeFnAttr(llvm::Attribute::StackProtectStrong); + ThunkFn->removeFnAttr(llvm::Attribute::StackProtectReq); + + // Start codegen. + CodeGenFunction CGF(CGM); + CGF.CurGD = GlobalDecl(MD); + CGF.CurFuncIsThunk = true; + + // Build FunctionArgs. + FunctionArgList FunctionArgs; + CGF.BuildFunctionArgList(CGF.CurGD, FunctionArgs); + + CGF.StartFunction(GlobalDecl(), FnInfo.getReturnType(), ThunkFn, FnInfo, + FunctionArgs, MD->getLocation(), SourceLocation()); + llvm::Value *ThisVal = loadIncomingCXXThis(CGF); + setCXXABIThisValue(CGF, ThisVal); + + CallArgList CallArgs; + for (const VarDecl *VD : FunctionArgs) + CGF.EmitDelegateCallArg(CallArgs, VD, SourceLocation()); + + const FunctionProtoType *FPT = MD->getType()->getAs(); + RequiredArgs Required = RequiredArgs::forPrototypePlus(FPT, /*this*/ 1); + const CGFunctionInfo &CallInfo = + CGM.getTypes().arrangeCXXMethodCall(CallArgs, FPT, Required, 0); + CGCallee Callee = CGCallee::forVirtual(nullptr, GlobalDecl(MD), + getThisAddress(CGF), ThunkTy); + llvm::CallBase *CallOrInvoke; + CGF.EmitCall(CallInfo, Callee, ReturnValueSlot(), CallArgs, &CallOrInvoke, + /*IsMustTail=*/true, SourceLocation(), true); + auto *Call = cast(CallOrInvoke); + Call->setTailCallKind(llvm::CallInst::TCK_MustTail); + if (Call->getType()->isVoidTy()) + CGF.Builder.CreateRetVoid(); + else + CGF.Builder.CreateRet(Call); + + // Finish the function to maintain CodeGenFunction invariants. + // FIXME: Don't emit unreachable code. + CGF.EmitBlock(CGF.createBasicBlock()); + CGF.FinishFunction(); + return ThunkFn; +} + namespace { class ItaniumRTTIBuilder { CodeGenModule &CGM; // Per-module state. @@ -4885,6 +5103,18 @@ ItaniumCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This, return {CGF.GetVTablePtr(This, CGM.Int8PtrTy, RD), RD}; } +llvm::Constant * +ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(const CXXMethodDecl *MD) { + const CXXMethodDecl *origMD = + cast(CGM.getItaniumVTableContext() + .findOriginalMethod(MD->getCanonicalDecl()) + .getDecl()); + llvm::Constant *thunk = getOrCreateVirtualFunctionPointerThunk(origMD); + QualType funcType = CGM.getContext().getMemberPointerType( + MD->getType(), MD->getParent()->getTypeForDecl()); + return CGM.getMemberFunctionPointer(thunk, funcType); +} + void WebAssemblyCXXABI::emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C) { if (CGF.getTarget().hasFeature("exception-handling")) diff --git a/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp b/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp similarity index 89% rename from clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp rename to clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp index ee543e40b4609..3a1f745d9ed77 100644 --- a/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp +++ b/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp @@ -1,4 +1,4 @@ -//===--- ObjectFilePCHContainerOperations.cpp -----------------------------===// +//===--- ObjectFilePCHContainerWriter.cpp -----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "clang/CodeGen/ObjectFilePCHContainerOperations.h" +#include "clang/CodeGen/ObjectFilePCHContainerWriter.h" #include "CGDebugInfo.h" #include "CodeGenModule.h" #include "clang/AST/ASTContext.h" @@ -351,46 +351,3 @@ ObjectFilePCHContainerWriter::CreatePCHContainerGenerator( return std::make_unique( CI, MainFileName, OutputFileName, std::move(OS), Buffer); } - -ArrayRef ObjectFilePCHContainerReader::getFormats() const { - static StringRef Formats[] = {"obj", "raw"}; - return Formats; -} - -StringRef -ObjectFilePCHContainerReader::ExtractPCH(llvm::MemoryBufferRef Buffer) const { - StringRef PCH; - auto OFOrErr = llvm::object::ObjectFile::createObjectFile(Buffer); - if (OFOrErr) { - auto &OF = OFOrErr.get(); - bool IsCOFF = isa(*OF); - // Find the clang AST section in the container. - for (auto &Section : OF->sections()) { - StringRef Name; - if (Expected NameOrErr = Section.getName()) - Name = *NameOrErr; - else - consumeError(NameOrErr.takeError()); - - if ((!IsCOFF && Name == "__clangast") || (IsCOFF && Name == "clangast")) { - if (Expected E = Section.getContents()) - return *E; - else { - handleAllErrors(E.takeError(), [&](const llvm::ErrorInfoBase &EIB) { - EIB.log(llvm::errs()); - }); - return ""; - } - } - } - } - handleAllErrors(OFOrErr.takeError(), [&](const llvm::ErrorInfoBase &EIB) { - if (EIB.convertToErrorCode() == - llvm::object::object_error::invalid_file_type) - // As a fallback, treat the buffer as a raw AST. - PCH = Buffer.getBuffer(); - else - EIB.log(llvm::errs()); - }); - return PCH; -} diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index 0925609cc74aa..8f17c053f4783 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -334,6 +334,10 @@ class TargetCodeGenInfo { llvm::AtomicOrdering Ordering, llvm::LLVMContext &Ctx) const; + /// Allow the target to apply other metadata to an atomic instruction + virtual void setTargetAtomicMetadata(CodeGenFunction &CGF, + llvm::AtomicRMWInst &RMW) const {} + /// Interface class for filling custom fields of a block literal for OpenCL. class TargetOpenCLBlockHelper { public: @@ -437,6 +441,7 @@ enum class AArch64ABIKind { DarwinPCS, Win64, AAPCSSoft, + PAuthTest, }; std::unique_ptr diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index b9df54b0c67c4..1dec3cd40ebd2 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -883,8 +883,10 @@ void AArch64TargetCodeGenInfo::checkFunctionCallABIStreaming( if (!CalleeIsStreamingCompatible && (CallerIsStreaming != CalleeIsStreaming || CallerIsStreamingCompatible)) - CGM.getDiags().Report(CallLoc, - diag::err_function_always_inline_attribute_mismatch) + CGM.getDiags().Report( + CallLoc, CalleeIsStreaming + ? diag::err_function_always_inline_attribute_mismatch + : diag::warn_function_always_inline_attribute_mismatch) << Caller->getDeclName() << Callee->getDeclName() << "streaming"; if (auto *NewAttr = Callee->getAttr()) if (NewAttr->isNewZA()) diff --git a/clang/lib/CodeGen/Targets/AMDGPU.cpp b/clang/lib/CodeGen/Targets/AMDGPU.cpp index 4d3275e17c386..37e6af3d4196a 100644 --- a/clang/lib/CodeGen/Targets/AMDGPU.cpp +++ b/clang/lib/CodeGen/Targets/AMDGPU.cpp @@ -311,6 +311,8 @@ class AMDGPUTargetCodeGenInfo : public TargetCodeGenInfo { SyncScope Scope, llvm::AtomicOrdering Ordering, llvm::LLVMContext &Ctx) const override; + void setTargetAtomicMetadata(CodeGenFunction &CGF, + llvm::AtomicRMWInst &RMW) const override; llvm::Value *createEnqueuedBlockKernel(CodeGenFunction &CGF, llvm::Function *BlockInvokeFunc, llvm::Type *BlockTy) const override; @@ -546,6 +548,23 @@ AMDGPUTargetCodeGenInfo::getLLVMSyncScopeID(const LangOptions &LangOpts, return Ctx.getOrInsertSyncScopeID(Name); } +void AMDGPUTargetCodeGenInfo::setTargetAtomicMetadata( + CodeGenFunction &CGF, llvm::AtomicRMWInst &RMW) const { + if (!CGF.getTarget().allowAMDGPUUnsafeFPAtomics()) + return; + + // TODO: Introduce new, more controlled options that also work for integers, + // and deprecate allowAMDGPUUnsafeFPAtomics. + llvm::AtomicRMWInst::BinOp RMWOp = RMW.getOperation(); + if (llvm::AtomicRMWInst::isFPOperation(RMWOp)) { + llvm::MDNode *Empty = llvm::MDNode::get(CGF.getLLVMContext(), {}); + RMW.setMetadata("amdgpu.no.fine.grained.memory", Empty); + + if (RMWOp == llvm::AtomicRMWInst::FAdd && RMW.getType()->isFloatTy()) + RMW.setMetadata("amdgpu.ignore.denormal.mode", Empty); + } +} + bool AMDGPUTargetCodeGenInfo::shouldEmitStaticExternCAliases() const { return false; } diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index e6b63b6fe093f..4d61f51379346 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -412,13 +412,16 @@ ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const { } ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const { + // Handle transparent union types. + Ty = useFirstFieldIfTransparentUnion(Ty); + // Handle the generic C++ ABI. if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); // Integers and enums are extended to full register width. if (isPromotableIntegerTypeForABI(Ty)) - return ABIArgInfo::getExtend(Ty); + return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)); // Handle vector types and vector-like structure types. Note that // as opposed to float-like structure types, we do not allow any diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index d1ce53539e8a7..c116aa6f589f0 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -24,22 +24,9 @@ bool IsX86_MMXType(llvm::Type *IRType) { IRType->getScalarSizeInBits() != 64; } -static llvm::Type* X86AdjustInlineAsmType(CodeGen::CodeGenFunction &CGF, +static llvm::Type *X86AdjustInlineAsmType(CodeGen::CodeGenFunction &CGF, StringRef Constraint, - llvm::Type* Ty) { - bool IsMMXCons = llvm::StringSwitch(Constraint) - .Cases("y", "&y", "^Ym", true) - .Default(false); - if (IsMMXCons && Ty->isVectorTy()) { - if (cast(Ty)->getPrimitiveSizeInBits().getFixedValue() != - 64) { - // Invalid MMX constraint - return nullptr; - } - - return llvm::Type::getX86_MMXTy(CGF.getLLVMContext()); - } - + llvm::Type *Ty) { if (Constraint == "k") { llvm::Type *Int1Ty = llvm::Type::getInt1Ty(CGF.getLLVMContext()); return llvm::FixedVectorType::get(Int1Ty, Ty->getScalarSizeInBits()); @@ -808,6 +795,10 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State, if (!IsWin32StructABI && isEmptyRecord(getContext(), Ty, true)) return ABIArgInfo::getIgnore(); + // Ignore 0 sized structs. + if (TI.Width == 0) + return ABIArgInfo::getIgnore(); + llvm::LLVMContext &LLVMContext = getVMContext(); llvm::IntegerType *Int32 = llvm::Type::getInt32Ty(LLVMContext); bool NeedsPadding = false; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index f8f2ff94e2a2c..fc94b470dbd5d 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -2607,7 +2607,7 @@ void Driver::HandleAutocompletions(StringRef PassedFlags) const { llvm::outs() << llvm::join(SuggestedCompletions, "\n") << '\n'; } -bool Driver::HandleImmediateArgs(const Compilation &C) { +bool Driver::HandleImmediateArgs(Compilation &C) { // The order these options are handled in gcc is all over the place, but we // don't expect inconsistencies w.r.t. that to matter in practice. @@ -2755,6 +2755,14 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { if (C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) { ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(C.getArgs()); const llvm::Triple Triple(TC.ComputeEffectiveClangTriple(C.getArgs())); + // The 'Darwin' toolchain is initialized only when its arguments are + // computed. Get the default arguments for OFK_None to ensure that + // initialization is performed before trying to access properties of + // the toolchain in the functions below. + // FIXME: Remove when darwin's toolchain is initialized during construction. + // FIXME: For some more esoteric targets the default toolchain is not the + // correct one. + C.getArgsForToolChain(&TC, Triple.getArchName(), Action::OFK_None); RegisterEffectiveTriple TripleRAII(TC, Triple); switch (RLT) { case ToolChain::RLT_CompilerRT: diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 9d64f0d1eb754..33b493ebe4828 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1109,11 +1109,12 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, } case llvm::Triple::aarch64: { llvm::Triple Triple = getTriple(); + tools::aarch64::setPAuthABIInTriple(getDriver(), Args, Triple); if (!Triple.isOSBinFormatMachO()) - return getTripleString(); + return Triple.getTriple(); if (Triple.isArm64e()) - return getTripleString(); + return Triple.getTriple(); // FIXME: older versions of ld64 expect the "arm64" component in the actual // triple string and query it to determine whether an LTO file can be diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp index b04502a57a9f7..aa51c1a8df58c 100644 --- a/clang/lib/Driver/ToolChains/AIX.cpp +++ b/clang/lib/Driver/ToolChains/AIX.cpp @@ -548,6 +548,9 @@ void AIX::addClangTargetOptions( options::OPT_mtocdata)) addTocDataOptions(Args, CC1Args, getDriver()); + if (Args.hasArg(options::OPT_msave_reg_params)) + CC1Args.push_back("-msave-reg-params"); + if (Args.hasFlag(options::OPT_fxl_pragma_pack, options::OPT_fno_xl_pragma_pack, true)) CC1Args.push_back("-fxl-pragma-pack"); @@ -557,6 +560,10 @@ void AIX::addClangTargetOptions( if (!Args.getLastArgNoClaim(options::OPT_fsized_deallocation, options::OPT_fno_sized_deallocation)) CC1Args.push_back("-fno-sized-deallocation"); + + if (!Args.hasFlag(options::OPT_ferr_pragma_mc_func_aix, + options::OPT_fno_err_pragma_mc_func_aix, true)) + CC1Args.push_back("-fno-err-pragma-mc-func-aix"); } void AIX::addProfileRTLibs(const llvm::opt::ArgList &Args, diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index e7e155b02d747..4384c10dbf3d1 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -620,19 +620,36 @@ void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA, const char *LinkingOutput) const { std::string Linker = getToolChain().GetLinkerPath(); ArgStringList CmdArgs; - CmdArgs.push_back("--no-undefined"); - CmdArgs.push_back("-shared"); + if (!Args.hasArg(options::OPT_r)) { + CmdArgs.push_back("--no-undefined"); + CmdArgs.push_back("-shared"); + } addLinkerCompressDebugSectionsOption(getToolChain(), Args, CmdArgs); Args.AddAllArgs(CmdArgs, options::OPT_L); getToolChain().AddFilePathLibArgs(Args, CmdArgs); AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); - if (C.getDriver().isUsingLTO()) + if (C.getDriver().isUsingLTO()) { addLTOOptions(getToolChain(), Args, CmdArgs, Output, Inputs[0], C.getDriver().getLTOMode() == LTOK_Thin); - else if (Args.hasArg(options::OPT_mcpu_EQ)) + } else if (Args.hasArg(options::OPT_mcpu_EQ)) { CmdArgs.push_back(Args.MakeArgString( - "-plugin-opt=mcpu=" + Args.getLastArgValue(options::OPT_mcpu_EQ))); + "-plugin-opt=mcpu=" + + getProcessorFromTargetID(getToolChain().getTriple(), + Args.getLastArgValue(options::OPT_mcpu_EQ)))); + } + + // Always pass the target-id features to the LTO job. + std::vector Features; + getAMDGPUTargetFeatures(C.getDriver(), getToolChain().getTriple(), Args, + Features); + if (!Features.empty()) { + CmdArgs.push_back( + Args.MakeArgString("-plugin-opt=-mattr=" + llvm::join(Features, ","))); + } + + addGPULibraries(getToolChain(), Args, CmdArgs); + CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); C.addCommand(std::make_unique( diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index 5fbf38cdda12b..f083e40df1314 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -449,3 +449,24 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, if (Args.getLastArg(options::OPT_mno_bti_at_return_twice)) Features.push_back("+no-bti-at-return-twice"); } + +void aarch64::setPAuthABIInTriple(const Driver &D, const ArgList &Args, + llvm::Triple &Triple) { + Arg *ABIArg = Args.getLastArg(options::OPT_mabi_EQ); + bool HasPAuthABI = + ABIArg ? (StringRef(ABIArg->getValue()) == "pauthtest") : false; + + switch (Triple.getEnvironment()) { + case llvm::Triple::UnknownEnvironment: + if (HasPAuthABI) + Triple.setEnvironment(llvm::Triple::PAuthTest); + break; + case llvm::Triple::PAuthTest: + break; + default: + if (HasPAuthABI) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << ABIArg->getAsString(Args) << Triple.getTriple(); + break; + } +} diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.h b/clang/lib/Driver/ToolChains/Arch/AArch64.h index d47c402d4a42d..6d071167bd392 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.h +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.h @@ -28,6 +28,9 @@ void getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple, std::string getAArch64TargetCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple, llvm::opt::Arg *&A); +void setPAuthABIInTriple(const Driver &D, const llvm::opt::ArgList &Args, + llvm::Triple &triple); + } // end namespace aarch64 } // end namespace target } // end namespace driver diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp index 4a2b9efc9ffad..1e8aac71dc9ba 100644 --- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp +++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp @@ -127,6 +127,11 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, const llvm::Triple &Triple, const ArgList &Args, std::vector &Features) { + // Enable the `lsx` feature on 64-bit LoongArch by default. + if (Triple.isLoongArch64() && + (!Args.hasArgNoClaim(clang::driver::options::OPT_march_EQ))) + Features.push_back("+lsx"); + std::string ArchName; if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) ArchName = A->getValue(); @@ -145,9 +150,11 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, } else if (A->getOption().matches(options::OPT_msingle_float)) { Features.push_back("+f"); Features.push_back("-d"); + Features.push_back("-lsx"); } else /*Soft-float*/ { Features.push_back("-f"); Features.push_back("-d"); + Features.push_back("-lsx"); } } else if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) { StringRef FPU = A->getValue(); @@ -157,9 +164,11 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, } else if (FPU == "32") { Features.push_back("+f"); Features.push_back("-d"); + Features.push_back("-lsx"); } else if (FPU == "0" || FPU == "none") { Features.push_back("-f"); Features.push_back("-d"); + Features.push_back("-lsx"); } else { D.Diag(diag::err_drv_loongarch_invalid_mfpu_EQ) << FPU; } @@ -174,6 +183,42 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, A->ignoreTargetSpecific(); if (Arg *A = Args.getLastArgNoClaim(options::OPT_mfpu_EQ)) A->ignoreTargetSpecific(); + if (Arg *A = Args.getLastArgNoClaim(options::OPT_msimd_EQ)) + A->ignoreTargetSpecific(); + + // Select lsx/lasx feature determined by -msimd=. + // Option -msimd= precedes -m[no-]lsx and -m[no-]lasx. + if (const Arg *A = Args.getLastArg(options::OPT_msimd_EQ)) { + StringRef MSIMD = A->getValue(); + if (MSIMD == "lsx") { + // Option -msimd=lsx depends on 64-bit FPU. + // -m*-float and -mfpu=none/0/32 conflict with -msimd=lsx. + if (llvm::find(Features, "-d") != Features.end()) + D.Diag(diag::err_drv_loongarch_wrong_fpu_width) << /*LSX*/ 0; + else + Features.push_back("+lsx"); + } else if (MSIMD == "lasx") { + // Option -msimd=lasx depends on 64-bit FPU and LSX. + // -m*-float, -mfpu=none/0/32 and -mno-lsx conflict with -msimd=lasx. + if (llvm::find(Features, "-d") != Features.end()) + D.Diag(diag::err_drv_loongarch_wrong_fpu_width) << /*LASX*/ 1; + else if (llvm::find(Features, "-lsx") != Features.end()) + D.Diag(diag::err_drv_loongarch_invalid_simd_option_combination); + + // The command options do not contain -mno-lasx. + if (!Args.getLastArg(options::OPT_mno_lasx)) { + Features.push_back("+lsx"); + Features.push_back("+lasx"); + } + } else if (MSIMD == "none") { + if (llvm::find(Features, "+lsx") != Features.end()) + Features.push_back("-lsx"); + if (llvm::find(Features, "+lasx") != Features.end()) + Features.push_back("-lasx"); + } else { + D.Diag(diag::err_drv_loongarch_invalid_msimd_EQ) << MSIMD; + } + } // Select lsx feature determined by -m[no-]lsx. if (const Arg *A = Args.getLastArg(options::OPT_mlsx, options::OPT_mno_lsx)) { @@ -197,8 +242,6 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, if (A->getOption().matches(options::OPT_mlasx)) { if (llvm::find(Features, "-d") != Features.end()) D.Diag(diag::err_drv_loongarch_wrong_fpu_width) << /*LASX*/ 1; - else if (llvm::find(Features, "-lsx") != Features.end()) - D.Diag(diag::err_drv_loongarch_invalid_simd_option_combination); else { /*-mlasx*/ Features.push_back("+lsx"); Features.push_back("+lasx"); @@ -206,35 +249,6 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, } else /*-mno-lasx*/ Features.push_back("-lasx"); } - - // Select lsx/lasx feature determined by -msimd=. - // Option -msimd= has lower priority than -m[no-]lsx and -m[no-]lasx. - if (const Arg *A = Args.getLastArg(options::OPT_msimd_EQ)) { - StringRef MSIMD = A->getValue(); - if (MSIMD == "lsx") { - // Option -msimd=lsx depends on 64-bit FPU. - // -m*-float and -mfpu=none/0/32 conflict with -mlsx. - if (llvm::find(Features, "-d") != Features.end()) - D.Diag(diag::err_drv_loongarch_wrong_fpu_width) << /*LSX*/ 0; - // The previous option does not contain feature -lsx. - else if (llvm::find(Features, "-lsx") == Features.end()) - Features.push_back("+lsx"); - } else if (MSIMD == "lasx") { - // Option -msimd=lasx depends on 64-bit FPU and LSX. - // -m*-float and -mfpu=none/0/32 conflict with -mlsx. - if (llvm::find(Features, "-d") != Features.end()) - D.Diag(diag::err_drv_loongarch_wrong_fpu_width) << /*LASX*/ 1; - else if (llvm::find(Features, "-lsx") != Features.end()) - D.Diag(diag::err_drv_loongarch_invalid_simd_option_combination); - // The previous option does not contain feature -lasx. - else if (llvm::find(Features, "-lasx") == Features.end()) { - Features.push_back("+lsx"); - Features.push_back("+lasx"); - } - } else if (MSIMD != "none") { - D.Diag(diag::err_drv_loongarch_invalid_msimd_EQ) << MSIMD; - } - } } std::string loongarch::postProcessTargetCPUString(const std::string &CPU, @@ -253,8 +267,14 @@ std::string loongarch::postProcessTargetCPUString(const std::string &CPU, std::string loongarch::getLoongArchTargetCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple) { std::string CPU; + std::string Arch; // If we have -march, use that. - if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) - CPU = A->getValue(); + if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { + Arch = A->getValue(); + if (Arch == "la64v1.0" || Arch == "la64v1.1") + CPU = llvm::LoongArch::getDefaultArch(Triple.isLoongArch64()); + else + CPU = Arch; + } return postProcessTargetCPUString(CPU, Triple); } diff --git a/clang/lib/Driver/ToolChains/Arch/PPC.cpp b/clang/lib/Driver/ToolChains/Arch/PPC.cpp index 634c096523319..57baa186a9eb7 100644 --- a/clang/lib/Driver/ToolChains/Arch/PPC.cpp +++ b/clang/lib/Driver/ToolChains/Arch/PPC.cpp @@ -20,78 +20,6 @@ using namespace clang::driver::tools; using namespace clang; using namespace llvm::opt; -static std::string getPPCGenericTargetCPU(const llvm::Triple &T) { - // LLVM may default to generating code for the native CPU, - // but, like gcc, we default to a more generic option for - // each architecture. (except on AIX) - if (T.isOSAIX()) - return "pwr7"; - else if (T.getArch() == llvm::Triple::ppc64le) - return "ppc64le"; - else if (T.getArch() == llvm::Triple::ppc64) - return "ppc64"; - else - return "ppc"; -} - -static std::string normalizeCPUName(StringRef CPUName, const llvm::Triple &T) { - // Clang/LLVM does not actually support code generation - // for the 405 CPU. However, there are uses of this CPU ID - // in projects that previously used GCC and rely on Clang - // accepting it. Clang has always ignored it and passed the - // generic CPU ID to the back end. - if (CPUName == "generic" || CPUName == "405") - return getPPCGenericTargetCPU(T); - - if (CPUName == "native") { - std::string CPU = std::string(llvm::sys::getHostCPUName()); - if (!CPU.empty() && CPU != "generic") - return CPU; - else - return getPPCGenericTargetCPU(T); - } - - return llvm::StringSwitch(CPUName) - .Case("common", "generic") - .Case("440fp", "440") - .Case("630", "pwr3") - .Case("G3", "g3") - .Case("G4", "g4") - .Case("G4+", "g4+") - .Case("8548", "e500") - .Case("G5", "g5") - .Case("power3", "pwr3") - .Case("power4", "pwr4") - .Case("power5", "pwr5") - .Case("power5x", "pwr5x") - .Case("power6", "pwr6") - .Case("power6x", "pwr6x") - .Case("power7", "pwr7") - .Case("power8", "pwr8") - .Case("power9", "pwr9") - .Case("power10", "pwr10") - .Case("future", "future") - .Case("powerpc", "ppc") - .Case("powerpc64", "ppc64") - .Case("powerpc64le", "ppc64le") - .Default(CPUName.data()); -} - -/// Get the (LLVM) name of the PowerPC cpu we are tuning for. -std::string ppc::getPPCTuneCPU(const ArgList &Args, const llvm::Triple &T) { - if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)) - return normalizeCPUName(A->getValue(), T); - return getPPCGenericTargetCPU(T); -} - -/// Get the (LLVM) name of the PowerPC cpu we are targeting. -std::string ppc::getPPCTargetCPU(const Driver &D, const ArgList &Args, - const llvm::Triple &T) { - if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) - return normalizeCPUName(A->getValue(), T); - return getPPCGenericTargetCPU(T); -} - const char *ppc::getPPCAsmModeForCPU(StringRef Name) { return llvm::StringSwitch(Name) .Case("pwr7", "-mpower7") @@ -103,6 +31,8 @@ const char *ppc::getPPCAsmModeForCPU(StringRef Name) { .Case("power9", "-mpower9") .Case("pwr10", "-mpower10") .Case("power10", "-mpower10") + .Case("pwr11", "-mpower11") + .Case("power11", "-mpower11") .Default("-many"); } diff --git a/clang/lib/Driver/ToolChains/Arch/PPC.h b/clang/lib/Driver/ToolChains/Arch/PPC.h index ec5b3c8140b66..89b9af92e8ddb 100644 --- a/clang/lib/Driver/ToolChains/Arch/PPC.h +++ b/clang/lib/Driver/ToolChains/Arch/PPC.h @@ -35,10 +35,6 @@ enum class ReadGOTPtrMode { FloatABI getPPCFloatABI(const Driver &D, const llvm::opt::ArgList &Args); -std::string getPPCTargetCPU(const Driver &D, const llvm::opt::ArgList &Args, - const llvm::Triple &T); -std::string getPPCTuneCPU(const llvm::opt::ArgList &Args, - const llvm::Triple &T); const char *getPPCAsmModeForCPU(StringRef Name); ReadGOTPtrMode getPPCReadGOTPtrMode(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args); diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp index 2f63333b732f6..dc6c8695488bb 100644 --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -266,19 +266,29 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, } bool IsNegative = Name.starts_with("no-"); + + bool Not64Bit = ArchType != llvm::Triple::x86_64; + if (Not64Bit && Name == "uintr") + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getSpelling() << Triple.getTriple(); + if (A->getOption().matches(options::OPT_mapx_features_EQ) || A->getOption().matches(options::OPT_mno_apx_features_EQ)) { + if (Not64Bit && !IsNegative) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << StringRef(A->getSpelling().str() + "|-mapxf") + << Triple.getTriple(); + for (StringRef Value : A->getValues()) { - if (Value == "egpr" || Value == "push2pop2" || Value == "ppx" || - Value == "ndd" || Value == "ccmp" || Value == "nf" || - Value == "cf" || Value == "zu") { - Features.push_back( - Args.MakeArgString((IsNegative ? "-" : "+") + Value)); - continue; - } - D.Diag(clang::diag::err_drv_unsupported_option_argument) - << A->getSpelling() << Value; + if (Value != "egpr" && Value != "push2pop2" && Value != "ppx" && + Value != "ndd" && Value != "ccmp" && Value != "nf" && + Value != "cf" && Value != "zu") + D.Diag(clang::diag::err_drv_unsupported_option_argument) + << A->getSpelling() << Value; + + Features.push_back( + Args.MakeArgString((IsNegative ? "-" : "+") + Value)); } continue; } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 19aec9d2284f8..3779c8b884d41 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -64,6 +64,7 @@ #include "llvm/TargetParser/ARMTargetParserCommon.h" #include "llvm/TargetParser/Host.h" #include "llvm/TargetParser/LoongArchTargetParser.h" +#include "llvm/TargetParser/PPCTargetParser.h" #include "llvm/TargetParser/RISCVISAInfo.h" #include "llvm/TargetParser/RISCVTargetParser.h" #include @@ -833,10 +834,6 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C, Args.hasArg(options::OPT_coverage)) FProfileDir = Args.getLastArg(options::OPT_fprofile_dir); - // TODO: Don't claim -c/-S to warn about -fsyntax-only -c/-S, -E -c/-S, - // like we warn about -fsyntax-only -E. - (void)(Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S)); - // Put the .gcno and .gcda files (if needed) next to the primary output file, // or fall back to a file in the current directory for `clang -c --coverage // d/a.c` in the absence of -o. @@ -1170,33 +1167,6 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, } } - // If we are compiling for a GPU target we want to override the system headers - // with ones created by the 'libc' project if present. - if (!Args.hasArg(options::OPT_nostdinc) && - !Args.hasArg(options::OPT_nogpuinc) && - !Args.hasArg(options::OPT_nobuiltininc)) { - // Without an offloading language we will include these headers directly. - // Offloading languages will instead only use the declarations stored in - // the resource directory at clang/lib/Headers/llvm_libc_wrappers. - if ((getToolChain().getTriple().isNVPTX() || - getToolChain().getTriple().isAMDGCN()) && - C.getActiveOffloadKinds() == Action::OFK_None) { - SmallString<128> P(llvm::sys::path::parent_path(D.Dir)); - llvm::sys::path::append(P, "include"); - llvm::sys::path::append(P, getToolChain().getTripleString()); - CmdArgs.push_back("-internal-isystem"); - CmdArgs.push_back(Args.MakeArgString(P)); - } else if (C.getActiveOffloadKinds() == Action::OFK_OpenMP) { - // TODO: CUDA / HIP include their own headers for some common functions - // implemented here. We'll need to clean those up so they do not conflict. - SmallString<128> P(D.ResourceDir); - llvm::sys::path::append(P, "include"); - llvm::sys::path::append(P, "llvm_libc_wrappers"); - CmdArgs.push_back("-internal-isystem"); - CmdArgs.push_back(Args.MakeArgString(P)); - } - } - // If we are offloading to a target via OpenMP we need to include the // openmp_wrappers folder which contains alternative system headers. if (JA.isDeviceOffloading(Action::OFK_OpenMP) && @@ -1387,6 +1357,35 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, }); } + // If we are compiling for a GPU target we want to override the system headers + // with ones created by the 'libc' project if present. + // TODO: This should be moved to `AddClangSystemIncludeArgs` by passing the + // OffloadKind as an argument. + if (!Args.hasArg(options::OPT_nostdinc) && + !Args.hasArg(options::OPT_nogpuinc) && + !Args.hasArg(options::OPT_nobuiltininc)) { + // Without an offloading language we will include these headers directly. + // Offloading languages will instead only use the declarations stored in + // the resource directory at clang/lib/Headers/llvm_libc_wrappers. + if ((getToolChain().getTriple().isNVPTX() || + getToolChain().getTriple().isAMDGCN()) && + C.getActiveOffloadKinds() == Action::OFK_None) { + SmallString<128> P(llvm::sys::path::parent_path(D.Dir)); + llvm::sys::path::append(P, "include"); + llvm::sys::path::append(P, getToolChain().getTripleString()); + CmdArgs.push_back("-internal-isystem"); + CmdArgs.push_back(Args.MakeArgString(P)); + } else if (C.getActiveOffloadKinds() == Action::OFK_OpenMP) { + // TODO: CUDA / HIP include their own headers for some common functions + // implemented here. We'll need to clean those up so they do not conflict. + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "include"); + llvm::sys::path::append(P, "llvm_libc_wrappers"); + CmdArgs.push_back("-internal-isystem"); + CmdArgs.push_back(Args.MakeArgString(P)); + } + } + // Add system include arguments for all targets but IAMCU. if (!IsIAMCU) forAllAssociatedToolChains(C, JA, getToolChain(), @@ -1595,6 +1594,45 @@ void AddUnalignedAccessWarning(ArgStringList &CmdArgs) { } } +// Each combination of options here forms a signing schema, and in most cases +// each signing schema is its own incompatible ABI. The default values of the +// options represent the default signing schema. +static void handlePAuthABI(const ArgList &DriverArgs, ArgStringList &CC1Args) { + if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics, + options::OPT_fno_ptrauth_intrinsics)) + CC1Args.push_back("-fptrauth-intrinsics"); + + if (!DriverArgs.hasArg(options::OPT_fptrauth_calls, + options::OPT_fno_ptrauth_calls)) + CC1Args.push_back("-fptrauth-calls"); + + if (!DriverArgs.hasArg(options::OPT_fptrauth_returns, + options::OPT_fno_ptrauth_returns)) + CC1Args.push_back("-fptrauth-returns"); + + if (!DriverArgs.hasArg(options::OPT_fptrauth_auth_traps, + options::OPT_fno_ptrauth_auth_traps)) + CC1Args.push_back("-fptrauth-auth-traps"); + + if (!DriverArgs.hasArg( + options::OPT_fptrauth_vtable_pointer_address_discrimination, + options::OPT_fno_ptrauth_vtable_pointer_address_discrimination)) + CC1Args.push_back("-fptrauth-vtable-pointer-address-discrimination"); + + if (!DriverArgs.hasArg( + options::OPT_fptrauth_vtable_pointer_type_discrimination, + options::OPT_fno_ptrauth_vtable_pointer_type_discrimination)) + CC1Args.push_back("-fptrauth-vtable-pointer-type-discrimination"); + + if (!DriverArgs.hasArg(options::OPT_fptrauth_indirect_gotos, + options::OPT_fno_ptrauth_indirect_gotos)) + CC1Args.push_back("-fptrauth-indirect-gotos"); + + if (!DriverArgs.hasArg(options::OPT_fptrauth_init_fini, + options::OPT_fno_ptrauth_init_fini)) + CC1Args.push_back("-fptrauth-init-fini"); +} + static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs, bool isAArch64) { const Arg *A = isAArch64 @@ -1657,16 +1695,30 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, CmdArgs.push_back( Args.MakeArgString(Twine("-msign-return-address=") + Scope)); - if (Scope != "none") + if (Scope != "none") { + if (Triple.getEnvironment() == llvm::Triple::PAuthTest) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getAsString(Args) << Triple.getTriple(); CmdArgs.push_back( Args.MakeArgString(Twine("-msign-return-address-key=") + Key)); - if (BranchProtectionPAuthLR) + } + if (BranchProtectionPAuthLR) { + if (Triple.getEnvironment() == llvm::Triple::PAuthTest) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getAsString(Args) << Triple.getTriple(); CmdArgs.push_back( Args.MakeArgString(Twine("-mbranch-protection-pauth-lr"))); + } if (IndirectBranches) CmdArgs.push_back("-mbranch-target-enforce"); - if (GuardedControlStack) + // GCS is currently untested with PAuthABI, but enabling this could be allowed + // in future after testing with a suitable system. + if (GuardedControlStack) { + if (Triple.getEnvironment() == llvm::Triple::PAuthTest) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getAsString(Args) << Triple.getTriple(); CmdArgs.push_back("-mguarded-control-stack"); + } } void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args, @@ -1810,6 +1862,8 @@ void RenderAArch64ABI(const llvm::Triple &Triple, const ArgList &Args, ABIName = A->getValue(); else if (Triple.isOSDarwin()) ABIName = "darwinpcs"; + else if (Triple.getEnvironment() == llvm::Triple::PAuthTest) + ABIName = "pauthtest"; else ABIName = "aapcs"; @@ -1846,6 +1900,9 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, // Enable/disable return address signing and indirect branch targets. CollectARMPACBTIOptions(getToolChain(), Args, CmdArgs, true /*isAArch64*/); + if (Triple.getEnvironment() == llvm::Triple::PAuthTest) + handlePAuthABI(Args, CmdArgs); + // Handle -msve_vector_bits= if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) { StringRef Val = A->getValue(); @@ -1898,11 +1955,17 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, Args.addOptInFlag( CmdArgs, options::OPT_fptrauth_vtable_pointer_type_discrimination, options::OPT_fno_ptrauth_vtable_pointer_type_discrimination); + Args.addOptInFlag( + CmdArgs, options::OPT_fptrauth_type_info_vtable_pointer_discrimination, + options::OPT_fno_ptrauth_type_info_vtable_pointer_discrimination); Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_init_fini, options::OPT_fno_ptrauth_init_fini); Args.addOptInFlag( CmdArgs, options::OPT_fptrauth_function_pointer_type_discrimination, options::OPT_fno_ptrauth_function_pointer_type_discrimination); + + Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_indirect_gotos, + options::OPT_fno_ptrauth_indirect_gotos); } void Clang::AddLoongArchTargetArgs(const ArgList &Args, @@ -2075,10 +2138,10 @@ void Clang::AddPPCTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { const Driver &D = getToolChain().getDriver(); const llvm::Triple &T = getToolChain().getTriple(); - if (Args.getLastArg(options::OPT_mtune_EQ)) { + if (Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) { CmdArgs.push_back("-tune-cpu"); - std::string CPU = ppc::getPPCTuneCPU(Args, T); - CmdArgs.push_back(Args.MakeArgString(CPU)); + StringRef CPU = llvm::PPC::getNormalizedPPCTuneCPU(T, A->getValue()); + CmdArgs.push_back(Args.MakeArgString(CPU.str())); } // Select the ABI to use. @@ -2923,6 +2986,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, // If one wasn't given by the user, don't pass it here. StringRef FPContract; StringRef LastSeenFfpContractOption; + StringRef LastFpContractOverrideOption; bool SeenUnsafeMathModeOption = false; if (!JA.isDeviceOffloading(Action::OFK_Cuda) && !JA.isOffloading(Action::OFK_HIP)) @@ -2965,6 +3029,27 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, SeenUnsafeMathModeOption = true; }; + // Lambda to consolidate common handling for fp-contract + auto restoreFPContractState = [&]() { + // CUDA and HIP don't rely on the frontend to pass an ffp-contract option. + // For other targets, if the state has been changed by one of the + // unsafe-math umbrella options a subsequent -fno-fast-math or + // -fno-unsafe-math-optimizations option reverts to the last value seen for + // the -ffp-contract option or "on" if we have not seen the -ffp-contract + // option. If we have not seen an unsafe-math option or -ffp-contract, + // we leave the FPContract state unchanged. + if (!JA.isDeviceOffloading(Action::OFK_Cuda) && + !JA.isOffloading(Action::OFK_HIP)) { + if (LastSeenFfpContractOption != "") + FPContract = LastSeenFfpContractOption; + else if (SeenUnsafeMathModeOption) + FPContract = "on"; + } + // In this case, we're reverting to the last explicit fp-contract option + // or the platform default + LastFpContractOverrideOption = ""; + }; + if (const Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) { CmdArgs.push_back("-mlimit-float-precision"); CmdArgs.push_back(A->getValue()); @@ -3073,7 +3158,6 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, AssociativeMath = false; ReciprocalMath = false; SignedZeros = true; - FPContract = "on"; StringRef Val = A->getValue(); if (OFastEnabled && Val != "fast") { @@ -3090,14 +3174,18 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, if (Val == "fast") { FPModel = Val; applyFastMath(); + // applyFastMath sets fp-contract="fast" + LastFpContractOverrideOption = "-ffp-model=fast"; } else if (Val == "precise") { FPModel = Val; FPContract = "on"; + LastFpContractOverrideOption = "-ffp-model=precise"; } else if (Val == "strict") { StrictFPModel = true; FPExceptionBehavior = "strict"; FPModel = Val; FPContract = "off"; + LastFpContractOverrideOption = "-ffp-model=strict"; TrappingMath = true; RoundingFPMath = true; } else @@ -3181,8 +3269,15 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, StringRef Val = A->getValue(); if (Val == "fast" || Val == "on" || Val == "off" || Val == "fast-honor-pragmas") { + if (Val != FPContract && LastFpContractOverrideOption != "") { + D.Diag(clang::diag::warn_drv_overriding_option) + << LastFpContractOverrideOption + << Args.MakeArgString("-ffp-contract=" + Val); + } + FPContract = Val; LastSeenFfpContractOption = Val; + LastFpContractOverrideOption = ""; } else D.Diag(diag::err_drv_unsupported_option_argument) << A->getSpelling() << Val; @@ -3261,6 +3356,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, TrappingMath = false; FPExceptionBehavior = ""; FPContract = "fast"; + LastFpContractOverrideOption = "-funsafe-math-optimizations"; SeenUnsafeMathModeOption = true; break; case options::OPT_fno_unsafe_math_optimizations: @@ -3268,14 +3364,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, ReciprocalMath = false; SignedZeros = true; ApproxFunc = false; - - if (!JA.isDeviceOffloading(Action::OFK_Cuda) && - !JA.isOffloading(Action::OFK_HIP)) { - if (LastSeenFfpContractOption != "") { - FPContract = LastSeenFfpContractOption; - } else if (SeenUnsafeMathModeOption) - FPContract = "on"; - } + restoreFPContractState(); break; case options::OPT_Ofast: @@ -3283,10 +3372,13 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, if (!OFastEnabled) continue; [[fallthrough]]; - case options::OPT_ffast_math: { + case options::OPT_ffast_math: applyFastMath(); + if (A->getOption().getID() == options::OPT_Ofast) + LastFpContractOverrideOption = "-Ofast"; + else + LastFpContractOverrideOption = "-ffast-math"; break; - } case options::OPT_fno_fast_math: HonorINFs = true; HonorNaNs = true; @@ -3299,16 +3391,11 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, ReciprocalMath = false; ApproxFunc = false; SignedZeros = true; - // -fno_fast_math restores default fpcontract handling - if (!JA.isDeviceOffloading(Action::OFK_Cuda) && - !JA.isOffloading(Action::OFK_HIP)) { - if (LastSeenFfpContractOption != "") { - FPContract = LastSeenFfpContractOption; - } else if (SeenUnsafeMathModeOption) - FPContract = "on"; - } + restoreFPContractState(); + LastFpContractOverrideOption = ""; break; - } + } // End switch (A->getOption().getID()) + // The StrictFPModel local variable is needed to report warnings // in the way we intend. If -ffp-model=strict has been used, we // want to report a warning for the next option encountered that @@ -3326,12 +3413,17 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, else { StrictFPModel = false; FPModel = ""; + // The warning for -ffp-contract would have been reported by the + // OPT_ffp_contract_EQ handler above. A special check here is needed + // to avoid duplicating the warning. auto RHS = (A->getNumValues() == 0) ? A->getSpelling() : Args.MakeArgString(A->getSpelling() + A->getValue()); - if (RHS != "-ffp-model=strict") - D.Diag(clang::diag::warn_drv_overriding_option) - << "-ffp-model=strict" << RHS; + if (A->getSpelling() != "-ffp-contract=") { + if (RHS != "-ffp-model=strict") + D.Diag(clang::diag::warn_drv_overriding_option) + << "-ffp-model=strict" << RHS; + } } } @@ -3413,26 +3505,32 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, // individual features enabled by -ffast-math instead of the option itself as // that's consistent with gcc's behaviour. if (!HonorINFs && !HonorNaNs && !MathErrno && AssociativeMath && ApproxFunc && - ReciprocalMath && !SignedZeros && !TrappingMath && !RoundingFPMath) { + ReciprocalMath && !SignedZeros && !TrappingMath && !RoundingFPMath) CmdArgs.push_back("-ffast-math"); - if (FPModel == "fast") { - if (FPContract == "fast") - // All set, do nothing. - ; - else if (FPContract.empty()) - // Enable -ffp-contract=fast - CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast")); - else - D.Diag(clang::diag::warn_drv_overriding_option) - << "-ffp-model=fast" - << Args.MakeArgString("-ffp-contract=" + FPContract); - } - } // Handle __FINITE_MATH_ONLY__ similarly. - if (!HonorINFs && !HonorNaNs) + // The -ffinite-math-only is added to CmdArgs when !HonorINFs && !HonorNaNs. + // Otherwise process the Xclang arguments to determine if -menable-no-infs and + // -menable-no-nans are set by the user. + bool shouldAddFiniteMathOnly = false; + if (!HonorINFs && !HonorNaNs) { + shouldAddFiniteMathOnly = true; + } else { + bool InfValues = true; + bool NanValues = true; + for (const auto *Arg : Args.filtered(options::OPT_Xclang)) { + StringRef ArgValue = Arg->getValue(); + if (ArgValue == "-menable-no-nans") + NanValues = false; + else if (ArgValue == "-menable-no-infs") + InfValues = false; + } + if (!NanValues && !InfValues) + shouldAddFiniteMathOnly = true; + } + if (shouldAddFiniteMathOnly) { CmdArgs.push_back("-ffinite-math-only"); - + } if (const Arg *A = Args.getLastArg(options::OPT_mfpmath_EQ)) { CmdArgs.push_back("-mfpmath"); CmdArgs.push_back(A->getValue()); @@ -3801,6 +3899,11 @@ static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs, CmdArgs.push_back(Args.MakeArgString(CLExtStr)); } + if (Args.hasArg(options::OPT_cl_finite_math_only)) { + CmdArgs.push_back("-menable-no-infs"); + CmdArgs.push_back("-menable-no-nans"); + } + for (const auto &Arg : ForwardedArguments) if (const auto *A = Args.getLastArg(Arg)) CmdArgs.push_back(Args.MakeArgString(A->getOption().getPrefixedName())); @@ -4026,6 +4129,9 @@ static bool RenderModulesOptions(Compilation &C, const Driver &D, options::OPT_fno_modules_strict_decluse, false)) CmdArgs.push_back("-fmodules-strict-decluse"); + Args.addOptOutFlag(CmdArgs, options::OPT_fmodulemap_allow_subdirectory_search, + options::OPT_fno_modulemap_allow_subdirectory_search); + // -fno-implicit-modules turns off implicitly compiling modules on demand. bool ImplicitModules = false; if (!Args.hasFlag(options::OPT_fimplicit_modules, @@ -4789,11 +4895,8 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T, // -gdwarf-aranges turns on the emission of the aranges section in the // backend. - // Always enabled for SCE tuning. - bool NeedAranges = DebuggerTuning == llvm::DebuggerKind::SCE; - if (const Arg *A = Args.getLastArg(options::OPT_gdwarf_aranges)) - NeedAranges = checkDebugInfoOption(A, Args, D, TC) || NeedAranges; - if (NeedAranges) { + if (const Arg *A = Args.getLastArg(options::OPT_gdwarf_aranges); + A && checkDebugInfoOption(A, Args, D, TC)) { CmdArgs.push_back("-mllvm"); CmdArgs.push_back("-generate-arange-section"); } @@ -6453,6 +6556,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_zero_initialized_in_bss); bool OFastEnabled = isOptimizationLevelFast(Args); + if (OFastEnabled) + D.Diag(diag::warn_drv_deprecated_arg_ofast); // If -Ofast is the optimization level, then -fstrict-aliasing should be // enabled. This alias option is being used to simplify the hasFlag logic. OptSpecifier StrictAliasingAliasOption = @@ -6462,6 +6567,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption, options::OPT_fno_strict_aliasing, !IsWindowsMSVC)) CmdArgs.push_back("-relaxed-aliasing"); + if (Args.hasFlag(options::OPT_fpointer_tbaa, options::OPT_fno_pointer_tbaa, + false)) + CmdArgs.push_back("-pointer-tbaa"); if (!Args.hasFlag(options::OPT_fstruct_path_tbaa, options::OPT_fno_struct_path_tbaa, true)) CmdArgs.push_back("-no-struct-path-tbaa"); @@ -7451,7 +7559,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, StringRef S0 = A->getValue(), S = S0; unsigned Size, Offset = 0; if (!Triple.isAArch64() && !Triple.isLoongArch() && !Triple.isRISCV() && - !Triple.isX86()) + !Triple.isX86() && + !(!Triple.isOSAIX() && (Triple.getArch() == llvm::Triple::ppc || + Triple.getArch() == llvm::Triple::ppc64))) D.Diag(diag::err_drv_unsupported_opt_for_target) << A->getAsString(Args) << TripleStr; else if (S.consumeInteger(10, Size) || @@ -7544,6 +7654,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (const char *Name = C.getTimeTraceFile(&JA)) { CmdArgs.push_back(Args.MakeArgString("-ftime-trace=" + Twine(Name))); Args.AddLastArg(CmdArgs, options::OPT_ftime_trace_granularity_EQ); + Args.AddLastArg(CmdArgs, options::OPT_ftime_trace_verbose); } if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) { @@ -8479,17 +8590,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_mno_amdgpu_ieee); } - // For all the host OpenMP offloading compile jobs we need to pass the targets - // information using -fopenmp-targets= option. - if (JA.isHostOffloading(Action::OFK_OpenMP)) { - SmallString<128> Targets("-fopenmp-targets="); - - SmallVector Triples; - auto TCRange = C.getOffloadToolChains(); - std::transform(TCRange.first, TCRange.second, std::back_inserter(Triples), - [](auto TC) { return TC.second->getTripleString(); }); - CmdArgs.push_back(Args.MakeArgString(Targets + llvm::join(Triples, ","))); - } + addOpenMPHostOffloadingArgs(C, JA, Args, CmdArgs); // For all the host SYCL offloading compile jobs we need to pass the targets // information using -fsycl-targets= option. @@ -10515,8 +10616,7 @@ static void getTripleBasedSPIRVTransOpts(Compilation &C, ",+SPV_INTEL_tensor_float32_conversion" ",+SPV_INTEL_optnone" ",+SPV_KHR_non_semantic_info" - ",+SPV_KHR_cooperative_matrix" - ",+SPV_INTEL_memory_access_aliasing"; + ",+SPV_KHR_cooperative_matrix"; if (IsCPU) ExtArg += ",+SPV_INTEL_fp_max_error"; @@ -11320,6 +11420,11 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, A->claim(); } + // If we disable the GPU C library support it needs to be forwarded to the + // link job. + if (!Args.hasFlag(options::OPT_gpulibc, options::OPT_nogpulibc, true)) + CmdArgs.push_back("--device-compiler=-nolibc"); + // Add the linker arguments to be forwarded by the wrapper. CmdArgs.push_back(Args.MakeArgString(Twine("--linker-path=") + LinkCommand->getExecutable())); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 5ddec78442a94..c7555836a46c4 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -64,6 +64,7 @@ #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/YAMLParser.h" #include "llvm/TargetParser/Host.h" +#include "llvm/TargetParser/PPCTargetParser.h" #include "llvm/TargetParser/TargetParser.h" #include @@ -517,6 +518,22 @@ void tools::addLinkerCompressDebugSectionsOption( } } +void tools::addGPULibraries(const ToolChain &TC, const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) { + if (Args.hasArg(options::OPT_nostdlib, options::OPT_r, + options::OPT_nodefaultlibs, options::OPT_nolibc, + options::OPT_nogpulibc)) + return; + + // If the user's toolchain has the 'include//` path, we assume it + // supports the standard C libraries for the GPU and include them. + bool HasLibC = TC.getStdlibIncludePath().has_value(); + if (HasLibC) { + CmdArgs.push_back("-lc"); + CmdArgs.push_back("-lm"); + } +} + void tools::AddTargetFeature(const ArgList &Args, std::vector &Features, OptSpecifier OnOpt, OptSpecifier OffOpt, @@ -626,7 +643,10 @@ std::string tools::getCPUName(const Driver &D, const ArgList &Args, case llvm::Triple::ppcle: case llvm::Triple::ppc64: case llvm::Triple::ppc64le: - return ppc::getPPCTargetCPU(D, Args, T); + if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) + return std::string( + llvm::PPC::getNormalizedPPCTargetCPU(T, A->getValue())); + return std::string(llvm::PPC::getNormalizedPPCTargetCPU(T)); case llvm::Triple::csky: if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) @@ -1153,42 +1173,6 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args, } } -/// Adds the '-lcgpu' and '-lmgpu' libraries to the compilation to include the -/// LLVM C library for GPUs. -static void addOpenMPDeviceLibC(const Compilation &C, const ArgList &Args, - ArgStringList &CmdArgs) { - if (Args.hasArg(options::OPT_nogpulib) || Args.hasArg(options::OPT_nolibc)) - return; - - // Check the resource directory for the LLVM libc GPU declarations. If it's - // found we can assume that LLVM was built with support for the GPU libc. - SmallString<256> LibCDecls(C.getDriver().ResourceDir); - llvm::sys::path::append(LibCDecls, "include", "llvm_libc_wrappers", - "llvm-libc-decls"); - bool HasLibC = llvm::sys::fs::exists(LibCDecls) && - llvm::sys::fs::is_directory(LibCDecls); - if (!Args.hasFlag(options::OPT_gpulibc, options::OPT_nogpulibc, HasLibC)) - return; - - SmallVector ToolChains; - auto TCRange = C.getOffloadToolChains(Action::OFK_OpenMP); - for (auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI) - ToolChains.push_back(TI->second); - - if (llvm::any_of(ToolChains, [](const ToolChain *TC) { - return TC->getTriple().isAMDGPU(); - })) { - CmdArgs.push_back("-lcgpu-amdgpu"); - CmdArgs.push_back("-lmgpu-amdgpu"); - } - if (llvm::any_of(ToolChains, [](const ToolChain *TC) { - return TC->getTriple().isNVPTX(); - })) { - CmdArgs.push_back("-lcgpu-nvptx"); - CmdArgs.push_back("-lmgpu-nvptx"); - } -} - void tools::addOpenMPRuntimeLibraryPath(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { @@ -1259,15 +1243,32 @@ bool tools::addOpenMPRuntime(const Compilation &C, ArgStringList &CmdArgs, if (IsOffloadingHost && !Args.hasArg(options::OPT_nogpulib)) CmdArgs.push_back("-lomptarget.devicertl"); - if (IsOffloadingHost) - addOpenMPDeviceLibC(C, Args, CmdArgs); - addArchSpecificRPath(TC, Args, CmdArgs); + addOpenMPRuntimeLibraryPath(TC, Args, CmdArgs); return true; } +void tools::addOpenMPHostOffloadingArgs(const Compilation &C, + const JobAction &JA, + const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) { + if (!JA.isHostOffloading(Action::OFK_OpenMP)) + return; + + // For all the host OpenMP offloading compile jobs we need to pass the targets + // information using -fopenmp-targets= option. + constexpr llvm::StringLiteral Targets("-fopenmp-targets="); + + SmallVector Triples; + auto TCRange = C.getOffloadToolChains(); + std::transform(TCRange.first, TCRange.second, std::back_inserter(Triples), + [](auto TC) { return TC.second->getTripleString(); }); + CmdArgs.push_back( + Args.MakeArgString(Twine(Targets) + llvm::join(Triples, ","))); +} + /// Add Fortran runtime libs void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args, llvm::opt::ArgStringList &CmdArgs) { @@ -1989,8 +1990,8 @@ tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) { return std::make_tuple(RelocM, 0U, false); } -// `-falign-functions` indicates that the functions should be aligned to a -// 16-byte boundary. +// `-falign-functions` indicates that the functions should be aligned to the +// backend's preferred alignment. // // `-falign-functions=1` is the same as `-fno-align-functions`. // diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index ce97a7dbefc33..33c724692dee5 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -35,6 +35,9 @@ void addLinkerCompressDebugSectionsOption(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs); +void addGPULibraries(const ToolChain &TC, const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs); + void claimNoWarnArgs(const llvm::opt::ArgList &Args); bool addSanitizerRuntimes(const ToolChain &TC, const llvm::opt::ArgList &Args, @@ -121,6 +124,11 @@ bool addOpenMPRuntime(const Compilation &C, llvm::opt::ArgStringList &CmdArgs, bool ForceStaticHostRuntime = false, bool IsOffloadingHost = false, bool GompNeedsRT = false); +/// Adds offloading options for OpenMP host compilation to \p CmdArgs. +void addOpenMPHostOffloadingArgs(const Compilation &C, const JobAction &JA, + const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs); + /// Adds Fortran runtime libraries to \p CmdArgs. void addFortranRuntimeLibs(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs); diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index f3bddf04878b1..f5c182537d97c 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -465,13 +465,6 @@ void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("--output-file"); std::string OutputFileName = TC.getInputFilename(Output); - // If we are invoking `nvlink` internally we need to output a `.cubin` file. - // FIXME: This should hopefully be removed if NVIDIA updates their tooling. - if (!C.getInputArgs().getLastArg(options::OPT_c)) { - SmallString<256> Filename(Output.getFilename()); - llvm::sys::path::replace_extension(Filename, "cubin"); - OutputFileName = Filename.str(); - } if (Output.isFilename() && OutputFileName != Output.getFilename()) C.addTempFile(Args.MakeArgString(OutputFileName)); @@ -691,14 +684,24 @@ void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-v"); StringRef GPUArch = Args.getLastArgValue(options::OPT_march_EQ); - if (GPUArch.empty()) { + if (GPUArch.empty() && !C.getDriver().isUsingLTO()) { C.getDriver().Diag(diag::err_drv_offload_missing_gpu_arch) << getToolChain().getArchName() << getShortName(); return; } - CmdArgs.push_back("-arch"); - CmdArgs.push_back(Args.MakeArgString(GPUArch)); + if (!GPUArch.empty()) { + CmdArgs.push_back("-arch"); + CmdArgs.push_back(Args.MakeArgString(GPUArch)); + } + + if (Args.hasArg(options::OPT_ptxas_path_EQ)) + CmdArgs.push_back(Args.MakeArgString( + "--pxtas-path=" + Args.getLastArgValue(options::OPT_ptxas_path_EQ))); + + if (Args.hasArg(options::OPT_cuda_path_EQ)) + CmdArgs.push_back(Args.MakeArgString( + "--cuda-path=" + Args.getLastArgValue(options::OPT_cuda_path_EQ))); // Add paths specified in LIBRARY_PATH environment variable as -L options. addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH"); @@ -706,6 +709,20 @@ void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA, // Add standard library search paths passed on the command line. Args.AddAllArgs(CmdArgs, options::OPT_L); getToolChain().AddFilePathLibArgs(Args, CmdArgs); + AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); + + if (C.getDriver().isUsingLTO()) + addLTOOptions(getToolChain(), Args, CmdArgs, Output, Inputs[0], + C.getDriver().getLTOMode() == LTOK_Thin); + + // Forward the PTX features if the nvlink-wrapper needs it. + std::vector Features; + getNVPTXTargetFeatures(C.getDriver(), getToolChain().getTriple(), Args, + Features); + for (StringRef Feature : Features) + CmdArgs.append({"--feature", Args.MakeArgString(Feature)}); + + addGPULibraries(getToolChain(), Args, CmdArgs); // Add paths for the default clang library path. SmallString<256> DefaultLibPath = @@ -713,51 +730,12 @@ void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA, llvm::sys::path::append(DefaultLibPath, CLANG_INSTALL_LIBDIR_BASENAME); CmdArgs.push_back(Args.MakeArgString(Twine("-L") + DefaultLibPath)); - for (const auto &II : Inputs) { - if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR || - II.getType() == types::TY_LTO_BC || II.getType() == types::TY_LLVM_BC) { - C.getDriver().Diag(diag::err_drv_no_linker_llvm_support) - << getToolChain().getTripleString(); - continue; - } - - // The 'nvlink' application performs RDC-mode linking when given a '.o' - // file and device linking when given a '.cubin' file. We always want to - // perform device linking, so just rename any '.o' files. - // FIXME: This should hopefully be removed if NVIDIA updates their tooling. - if (II.isFilename()) { - auto InputFile = getToolChain().getInputFilename(II); - if (llvm::sys::path::extension(InputFile) != ".cubin") { - // If there are no actions above this one then this is direct input and - // we can copy it. Otherwise the input is internal so a `.cubin` file - // should exist. - if (II.getAction() && II.getAction()->getInputs().size() == 0) { - const char *CubinF = - Args.MakeArgString(getToolChain().getDriver().GetTemporaryPath( - llvm::sys::path::stem(InputFile), "cubin")); - if (llvm::sys::fs::copy_file(InputFile, C.addTempFile(CubinF))) - continue; - - CmdArgs.push_back(CubinF); - } else { - SmallString<256> Filename(InputFile); - llvm::sys::path::replace_extension(Filename, "cubin"); - CmdArgs.push_back(Args.MakeArgString(Filename)); - } - } else { - CmdArgs.push_back(Args.MakeArgString(InputFile)); - } - } else if (!II.isNothing()) { - II.getInputArg().renderAsInput(Args, CmdArgs); - } - } - C.addCommand(std::make_unique( JA, *this, ResponseFileSupport{ResponseFileSupport::RF_Full, llvm::sys::WEM_UTF8, "--options-file"}, - Args.MakeArgString(getToolChain().GetProgramPath("nvlink")), CmdArgs, - Inputs, Output)); + Args.MakeArgString(getToolChain().GetProgramPath("clang-nvlink-wrapper")), + CmdArgs, Inputs, Output)); } void NVPTX::getNVPTXTargetFeatures(const Driver &D, const llvm::Triple &Triple, @@ -1112,11 +1090,7 @@ std::string CudaToolChain::getInputFilename(const InputInfo &Input) const { if (Input.getType() != types::TY_Object || getDriver().offloadDeviceOnly()) return ToolChain::getInputFilename(Input); - // Replace extension for object files with cubin because nvlink relies on - // these particular file names. - SmallString<256> Filename(ToolChain::getInputFilename(Input)); - llvm::sys::path::replace_extension(Filename, "cubin"); - return std::string(Filename); + return ToolChain::getInputFilename(Input); } llvm::opt::DerivedArgList * diff --git a/clang/lib/Driver/ToolChains/Cuda.h b/clang/lib/Driver/ToolChains/Cuda.h index 70851d8356f25..9ea82bd379d54 100644 --- a/clang/lib/Driver/ToolChains/Cuda.h +++ b/clang/lib/Driver/ToolChains/Cuda.h @@ -182,6 +182,7 @@ class LLVM_LIBRARY_VISIBILITY NVPTXToolChain : public ToolChain { bool isPIEDefault(const llvm::opt::ArgList &Args) const override { return false; } + bool HasNativeLLVMSupport() const override { return true; } bool isPICDefaultForced() const override { return false; } bool SupportsProfiling() const override { return false; } @@ -220,6 +221,8 @@ class LLVM_LIBRARY_VISIBILITY CudaToolChain : public NVPTXToolChain { return &HostTC.getTriple(); } + bool HasNativeLLVMSupport() const override { return false; } + std::string getInputFilename(const InputInfo &Input) const override; llvm::opt::DerivedArgList * diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index f354b0974d5f2..17b6074160716 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -1272,23 +1272,8 @@ unsigned DarwinClang::GetDefaultDwarfVersion() const { void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs, StringRef Component, RuntimeLinkOptions Opts, bool IsShared) const { - SmallString<64> DarwinLibName = StringRef("libclang_rt."); - // On Darwin the builtins component is not in the library name. - if (Component != "builtins") { - DarwinLibName += Component; - if (!(Opts & RLO_IsEmbedded)) - DarwinLibName += "_"; - } - - DarwinLibName += getOSLibraryNameSuffix(); - DarwinLibName += IsShared ? "_dynamic.dylib" : ".a"; - SmallString<128> Dir(getDriver().ResourceDir); - llvm::sys::path::append(Dir, "lib", "darwin"); - if (Opts & RLO_IsEmbedded) - llvm::sys::path::append(Dir, "macho_embedded"); - - SmallString<128> P(Dir); - llvm::sys::path::append(P, DarwinLibName); + std::string P = getCompilerRT( + Args, Component, IsShared ? ToolChain::FT_Shared : ToolChain::FT_Static); // For now, allow missing resource libraries to support developers who may // not have compiler-rt checked out or integrated into their build (unless @@ -1303,20 +1288,58 @@ void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs, // rpaths. This is currently true from this place, but we need to be // careful if this function is ever called before user's rpaths are emitted. if (Opts & RLO_AddRPath) { - assert(DarwinLibName.ends_with(".dylib") && "must be a dynamic library"); + assert(StringRef(P).ends_with(".dylib") && "must be a dynamic library"); // Add @executable_path to rpath to support having the dylib copied with // the executable. CmdArgs.push_back("-rpath"); CmdArgs.push_back("@executable_path"); - // Add the path to the resource dir to rpath to support using the dylib - // from the default location without copying. + // Add the compiler-rt library's directory to rpath to support using the + // dylib from the default location without copying. CmdArgs.push_back("-rpath"); - CmdArgs.push_back(Args.MakeArgString(Dir)); + CmdArgs.push_back(Args.MakeArgString(llvm::sys::path::parent_path(P))); } } +std::string MachO::getCompilerRT(const ArgList &, StringRef Component, + FileType Type) const { + assert(Type != ToolChain::FT_Object && + "it doesn't make sense to ask for the compiler-rt library name as an " + "object file"); + SmallString<64> MachOLibName = StringRef("libclang_rt"); + // On MachO, the builtins component is not in the library name + if (Component != "builtins") { + MachOLibName += '.'; + MachOLibName += Component; + } + MachOLibName += Type == ToolChain::FT_Shared ? "_dynamic.dylib" : ".a"; + + SmallString<128> FullPath(getDriver().ResourceDir); + llvm::sys::path::append(FullPath, "lib", "darwin", "macho_embedded", + MachOLibName); + return std::string(FullPath); +} + +std::string Darwin::getCompilerRT(const ArgList &, StringRef Component, + FileType Type) const { + assert(Type != ToolChain::FT_Object && + "it doesn't make sense to ask for the compiler-rt library name as an " + "object file"); + SmallString<64> DarwinLibName = StringRef("libclang_rt."); + // On Darwin, the builtins component is not in the library name + if (Component != "builtins") { + DarwinLibName += Component; + DarwinLibName += '_'; + } + DarwinLibName += getOSLibraryNameSuffix(); + DarwinLibName += Type == ToolChain::FT_Shared ? "_dynamic.dylib" : ".a"; + + SmallString<128> FullPath(getDriver().ResourceDir); + llvm::sys::path::append(FullPath, "lib", "darwin", DarwinLibName); + return std::string(FullPath); +} + StringRef Darwin::getPlatformFamily() const { switch (TargetPlatform) { case DarwinPlatformKind::MacOS: @@ -3013,6 +3036,35 @@ void Darwin::addClangTargetOptions( if (!DriverArgs.hasArgNoClaim(options::OPT_fdefine_target_os_macros, options::OPT_fno_define_target_os_macros)) CC1Args.push_back("-fdefine-target-os-macros"); + + // Disable subdirectory modulemap search on sufficiently recent SDKs. + if (SDKInfo && + !DriverArgs.hasFlag(options::OPT_fmodulemap_allow_subdirectory_search, + options::OPT_fno_modulemap_allow_subdirectory_search, + false)) { + bool RequiresSubdirectorySearch; + VersionTuple SDKVersion = SDKInfo->getVersion(); + switch (TargetPlatform) { + default: + RequiresSubdirectorySearch = true; + break; + case MacOS: + RequiresSubdirectorySearch = SDKVersion < VersionTuple(15, 0); + break; + case IPhoneOS: + case TvOS: + RequiresSubdirectorySearch = SDKVersion < VersionTuple(18, 0); + break; + case WatchOS: + RequiresSubdirectorySearch = SDKVersion < VersionTuple(11, 0); + break; + case XROS: + RequiresSubdirectorySearch = SDKVersion < VersionTuple(2, 0); + break; + } + if (!RequiresSubdirectorySearch) + CC1Args.push_back("-fno-modulemap-allow-subdirectory-search"); + } } void Darwin::addClangCC1ASTargetOptions( diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h index b45279ecedeb2..2e55b49682a7e 100644 --- a/clang/lib/Driver/ToolChains/Darwin.h +++ b/clang/lib/Driver/ToolChains/Darwin.h @@ -223,6 +223,13 @@ class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain { // There aren't any profiling libs for embedded targets currently. } + // Return the full path of the compiler-rt library on a non-Darwin MachO + // system. Those are under + // /lib/darwin/macho_embedded/<...>(.dylib|.a). + std::string + getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, + FileType Type = ToolChain::FT_Static) const override; + /// } /// @name ToolChain Implementation /// { @@ -356,6 +363,12 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { void addProfileRTLibs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; + // Return the full path of the compiler-rt library on a Darwin MachO system. + // Those are under /lib/darwin/<...>(.dylib|.a). + std::string + getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, + FileType Type = ToolChain::FT_Static) const override; + protected: /// } /// @name Darwin specific Toolchain functions diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index c4f2375c64034..492d5a3021d9b 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -342,6 +342,9 @@ void Flang::AddAMDGPUTargetArgs(const ArgList &Args, StringRef Val = A->getValue(); CmdArgs.push_back(Args.MakeArgString("-mcode-object-version=" + Val)); } + + const ToolChain &TC = getToolChain(); + TC.addClangTargetOptions(Args, CmdArgs, Action::OffloadKind::OFK_OpenMP); } void Flang::addTargetOptions(const ArgList &Args, @@ -492,6 +495,8 @@ void Flang::addOffloadOptions(Compilation &C, const InputInfoList &Inputs, if (Args.hasArg(options::OPT_nogpulib)) CmdArgs.push_back("-nogpulib"); } + + addOpenMPHostOffloadingArgs(C, JA, Args, CmdArgs); } static void addFloatingPointOptions(const Driver &D, const ArgList &Args, diff --git a/clang/lib/Driver/ToolChains/Hexagon.cpp b/clang/lib/Driver/ToolChains/Hexagon.cpp index 12b3b99df7ca1..29781399cbab4 100644 --- a/clang/lib/Driver/ToolChains/Hexagon.cpp +++ b/clang/lib/Driver/ToolChains/Hexagon.cpp @@ -366,11 +366,14 @@ constructHexagonLinkArgs(Compilation &C, const JobAction &JA, options::OPT_t, options::OPT_u_Group}); AddLinkerInputs(HTC, Inputs, Args, CmdArgs, JA); + ToolChain::UnwindLibType UNW = HTC.GetUnwindLibType(Args); + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { if (NeedsSanitizerDeps) { linkSanitizerRuntimeDeps(HTC, Args, CmdArgs); - CmdArgs.push_back("-lunwind"); + if (UNW != ToolChain::UNW_None) + CmdArgs.push_back("-lunwind"); } if (NeedsXRayDeps) linkXRayRuntimeDeps(HTC, Args, CmdArgs); @@ -618,13 +621,24 @@ HexagonToolChain::~HexagonToolChain() {} void HexagonToolChain::AddCXXStdlibLibArgs(const ArgList &Args, ArgStringList &CmdArgs) const { CXXStdlibType Type = GetCXXStdlibType(Args); + ToolChain::UnwindLibType UNW = GetUnwindLibType(Args); + if (UNW != ToolChain::UNW_None && UNW != ToolChain::UNW_CompilerRT) { + const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ); + if (A) { + getDriver().Diag(diag::err_drv_unsupported_unwind_for_platform) + << A->getValue() << getTriple().normalize(); + return; + } + } + switch (Type) { 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"); - CmdArgs.push_back("-lunwind"); + if (UNW != ToolChain::UNW_None) + CmdArgs.push_back("-lunwind"); break; case ToolChain::CST_Libstdcxx: diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index 4fede7dec75e9..314101091835b 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -86,6 +86,9 @@ std::string Linux::getMultiarchTriple(const Driver &D, case llvm::Triple::aarch64: if (IsAndroid) return "aarch64-linux-android"; + if (hasEffectiveTriple() && + getEffectiveTriple().getEnvironment() == llvm::Triple::PAuthTest) + return "aarch64-linux-pauthtest"; return "aarch64-linux-gnu"; case llvm::Triple::aarch64_be: return "aarch64_be-linux-gnu"; diff --git a/clang/lib/Driver/ToolChains/PS4CPU.cpp b/clang/lib/Driver/ToolChains/PS4CPU.cpp index 974e486a0082b..a9e612c44da06 100644 --- a/clang/lib/Driver/ToolChains/PS4CPU.cpp +++ b/clang/lib/Driver/ToolChains/PS4CPU.cpp @@ -152,52 +152,38 @@ void tools::PS4cpu::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Output.getFilename()); } - const bool UseLTO = D.isUsingLTO(); const bool UseJMC = Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false); const char *LTOArgs = ""; - auto AddCodeGenFlag = [&](Twine Flag) { + auto AddLTOFlag = [&](Twine Flag) { LTOArgs = Args.MakeArgString(Twine(LTOArgs) + " " + Flag); }; - if (UseLTO) { - // We default to creating the arange section, but LTO does not. Enable it - // here. - AddCodeGenFlag("-generate-arange-section"); + // If the linker sees bitcode objects it will perform LTO. We can't tell + // whether or not that will be the case at this point. So, unconditionally + // pass LTO options to ensure proper codegen, metadata production, etc if + // LTO indeed occurs. + if (Args.hasFlag(options::OPT_funified_lto, options::OPT_fno_unified_lto, + true)) + CmdArgs.push_back(D.getLTOMode() == LTOK_Thin ? "--lto=thin" + : "--lto=full"); + if (UseJMC) + AddLTOFlag("-enable-jmc-instrument"); - // This tells LTO to perform JustMyCode instrumentation. - if (UseJMC) - AddCodeGenFlag("-enable-jmc-instrument"); + if (Arg *A = Args.getLastArg(options::OPT_fcrash_diagnostics_dir)) + AddLTOFlag(Twine("-crash-diagnostics-dir=") + A->getValue()); - if (Arg *A = Args.getLastArg(options::OPT_fcrash_diagnostics_dir)) - AddCodeGenFlag(Twine("-crash-diagnostics-dir=") + A->getValue()); + if (StringRef Threads = getLTOParallelism(Args, D); !Threads.empty()) + AddLTOFlag(Twine("-threads=") + Threads); - StringRef Parallelism = getLTOParallelism(Args, D); - if (!Parallelism.empty()) - AddCodeGenFlag(Twine("-threads=") + Parallelism); - - const char *Prefix = nullptr; - if (D.getLTOMode() == LTOK_Thin) - Prefix = "-lto-thin-debug-options="; - else if (D.getLTOMode() == LTOK_Full) - Prefix = "-lto-debug-options="; - else - llvm_unreachable("new LTO mode?"); - - CmdArgs.push_back(Args.MakeArgString(Twine(Prefix) + LTOArgs)); - } + if (*LTOArgs) + CmdArgs.push_back( + Args.MakeArgString(Twine("-lto-debug-options=") + LTOArgs)); if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) TC.addSanitizerArgs(Args, CmdArgs, "-l", ""); - if (D.isUsingLTO() && Args.hasArg(options::OPT_funified_lto)) { - if (D.getLTOMode() == LTOK_Thin) - CmdArgs.push_back("--lto=thin"); - else if (D.getLTOMode() == LTOK_Full) - CmdArgs.push_back("--lto=full"); - } - Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group, options::OPT_s, options::OPT_t}); @@ -263,41 +249,38 @@ void tools::PS5cpu::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Output.getFilename()); } - const bool UseLTO = D.isUsingLTO(); const bool UseJMC = Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false); - auto AddCodeGenFlag = [&](Twine Flag) { + auto AddLTOFlag = [&](Twine Flag) { CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=") + Flag)); }; - if (UseLTO) { - // We default to creating the arange section, but LTO does not. Enable it - // here. - AddCodeGenFlag("-generate-arange-section"); + // If the linker sees bitcode objects it will perform LTO. We can't tell + // whether or not that will be the case at this point. So, unconditionally + // pass LTO options to ensure proper codegen, metadata production, etc if + // LTO indeed occurs. + if (Args.hasFlag(options::OPT_funified_lto, options::OPT_fno_unified_lto, + true)) + CmdArgs.push_back(D.getLTOMode() == LTOK_Thin ? "--lto=thin" + : "--lto=full"); - // This tells LTO to perform JustMyCode instrumentation. - if (UseJMC) - AddCodeGenFlag("-enable-jmc-instrument"); + if (UseJMC) + AddLTOFlag("-enable-jmc-instrument"); - if (Arg *A = Args.getLastArg(options::OPT_fcrash_diagnostics_dir)) - AddCodeGenFlag(Twine("-crash-diagnostics-dir=") + A->getValue()); + if (Args.hasFlag(options::OPT_fstack_size_section, + options::OPT_fno_stack_size_section, false)) + AddLTOFlag("-stack-size-section"); - StringRef Parallelism = getLTOParallelism(Args, D); - if (!Parallelism.empty()) - CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=jobs=") + Parallelism)); - } + if (Arg *A = Args.getLastArg(options::OPT_fcrash_diagnostics_dir)) + AddLTOFlag(Twine("-crash-diagnostics-dir=") + A->getValue()); + + if (StringRef Jobs = getLTOParallelism(Args, D); !Jobs.empty()) + AddLTOFlag(Twine("jobs=") + Jobs); if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) TC.addSanitizerArgs(Args, CmdArgs, "-l", ""); - if (D.isUsingLTO() && Args.hasArg(options::OPT_funified_lto)) { - if (D.getLTOMode() == LTOK_Thin) - CmdArgs.push_back("--lto=thin"); - else if (D.getLTOMode() == LTOK_Full) - CmdArgs.push_back("--lto=full"); - } - Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group, options::OPT_s, options::OPT_t}); diff --git a/clang/lib/Driver/ToolChains/PS4CPU.h b/clang/lib/Driver/ToolChains/PS4CPU.h index 0be90183c637c..a33728bce5186 100644 --- a/clang/lib/Driver/ToolChains/PS4CPU.h +++ b/clang/lib/Driver/ToolChains/PS4CPU.h @@ -179,7 +179,7 @@ class LLVM_LIBRARY_VISIBILITY PS5CPU : public PS4PS5Base { llvm::opt::ArgStringList &CmdArgs, const char *Prefix, const char *Suffix) const override; const char *getProfileRTLibName() const override { - return "libclang_rt.profile-x86_64_nosubmission.a"; + return "libclang_rt.profile_nosubmission.a"; } protected: diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp index 60bd97e0ee987..9aacda5fd5702 100644 --- a/clang/lib/Driver/ToolChains/WebAssembly.cpp +++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp @@ -61,6 +61,13 @@ std::string wasm::Linker::getLinkerPath(const ArgList &Args) const { return ToolChain.GetProgramPath(ToolChain.getDefaultLinker()); } +static bool TargetBuildsComponents(const llvm::Triple &TargetTriple) { + // WASIp2 and above are all based on components, so test for WASI but exclude + // the original `wasi` target in addition to the `wasip1` name. + return TargetTriple.isOSWASI() && TargetTriple.getOSName() != "wasip1" && + TargetTriple.getOSName() != "wasi"; +} + void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -158,46 +165,52 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - if (Args.hasFlag(options::OPT_wasm_opt, options::OPT_no_wasm_opt, true)) { - // When optimizing, if wasm-opt is available, run it. - std::string WasmOptPath; - if (Args.getLastArg(options::OPT_O_Group)) { - WasmOptPath = ToolChain.GetProgramPath("wasm-opt"); - if (WasmOptPath == "wasm-opt") { - WasmOptPath = {}; - } + // Don't use wasm-opt by default on `wasip2` as it doesn't have support for + // components at this time. Retain the historical default otherwise, though, + // of running `wasm-opt` by default. + bool WasmOptDefault = !TargetBuildsComponents(ToolChain.getTriple()); + bool RunWasmOpt = Args.hasFlag(options::OPT_wasm_opt, + options::OPT_no_wasm_opt, WasmOptDefault); + + // If wasm-opt is enabled and optimizations are happening look for the + // `wasm-opt` program. If it's not found auto-disable it. + std::string WasmOptPath; + if (RunWasmOpt && Args.getLastArg(options::OPT_O_Group)) { + WasmOptPath = ToolChain.GetProgramPath("wasm-opt"); + if (WasmOptPath == "wasm-opt") { + WasmOptPath = {}; } + } - if (!WasmOptPath.empty()) { - CmdArgs.push_back("--keep-section=target_features"); - } + if (!WasmOptPath.empty()) { + CmdArgs.push_back("--keep-section=target_features"); + } - C.addCommand(std::make_unique(JA, *this, - ResponseFileSupport::AtFileCurCP(), - Linker, CmdArgs, Inputs, Output)); - - if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { - if (!WasmOptPath.empty()) { - StringRef OOpt = "s"; - if (A->getOption().matches(options::OPT_O4) || - A->getOption().matches(options::OPT_Ofast)) - OOpt = "4"; - else if (A->getOption().matches(options::OPT_O0)) - OOpt = "0"; - else if (A->getOption().matches(options::OPT_O)) - OOpt = A->getValue(); - - if (OOpt != "0") { - const char *WasmOpt = Args.MakeArgString(WasmOptPath); - ArgStringList OptArgs; - OptArgs.push_back(Output.getFilename()); - OptArgs.push_back(Args.MakeArgString(llvm::Twine("-O") + OOpt)); - OptArgs.push_back("-o"); - OptArgs.push_back(Output.getFilename()); - C.addCommand(std::make_unique( - JA, *this, ResponseFileSupport::AtFileCurCP(), WasmOpt, OptArgs, - Inputs, Output)); - } + C.addCommand(std::make_unique(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Linker, CmdArgs, Inputs, Output)); + + if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { + if (!WasmOptPath.empty()) { + StringRef OOpt = "s"; + if (A->getOption().matches(options::OPT_O4) || + A->getOption().matches(options::OPT_Ofast)) + OOpt = "4"; + else if (A->getOption().matches(options::OPT_O0)) + OOpt = "0"; + else if (A->getOption().matches(options::OPT_O)) + OOpt = A->getValue(); + + if (OOpt != "0") { + const char *WasmOpt = Args.MakeArgString(WasmOptPath); + ArgStringList OptArgs; + OptArgs.push_back(Output.getFilename()); + OptArgs.push_back(Args.MakeArgString(llvm::Twine("-O") + OOpt)); + OptArgs.push_back("-o"); + OptArgs.push_back(Output.getFilename()); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), WasmOpt, OptArgs, + Inputs, Output)); } } } @@ -241,7 +254,7 @@ WebAssembly::WebAssembly(const Driver &D, const llvm::Triple &Triple, } const char *WebAssembly::getDefaultLinker() const { - if (getOS() == "wasip2") + if (TargetBuildsComponents(getTriple())) return "wasm-component-ld"; return "wasm-ld"; } diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index b07360425ca6e..df86a774ba0f4 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -803,6 +803,37 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, tok::kw_switch); }; + auto IsFunctionCallParen = [](const FormatToken &Tok) { + return Tok.is(tok::l_paren) && Tok.ParameterCount > 0 && Tok.Previous && + Tok.Previous->is(tok::identifier); + }; + const auto IsInTemplateString = [this](const FormatToken &Tok) { + if (!Style.isJavaScript()) + return false; + for (const auto *Prev = &Tok; Prev; Prev = Prev->Previous) { + if (Prev->is(TT_TemplateString) && Prev->opensScope()) + return true; + if (Prev->is(TT_TemplateString) && Prev->closesScope()) + break; + } + return false; + }; + // Identifies simple (no expression) one-argument function calls. + const auto IsSimpleFunction = [&](const FormatToken &Tok) { + if (!Tok.FakeLParens.empty() && Tok.FakeLParens.back() > prec::Unknown) + return false; + const auto *Previous = Tok.Previous; + if (!Previous || (!Previous->isOneOf(TT_FunctionDeclarationLParen, + TT_LambdaDefinitionLParen) && + !IsFunctionCallParen(*Previous))) { + return true; + } + if (IsOpeningBracket(Tok) || IsInTemplateString(Tok)) + return true; + const auto *Next = Tok.Next; + return !Next || Next->isMemberAccess() || + Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*Next); + }; if ((Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak || Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) && IsOpeningBracket(Previous) && State.Column > getNewLineColumn(State) && @@ -813,10 +844,10 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, // caaaaaaaaaaaall( // caaaaaaaaaaaall( // caaaaaaaaaaaaaaaaaaaaaaall(aaaaaaaaaaaaaa, aaaaaaaaa)))); - Current.FakeLParens.size() > 0 && - Current.FakeLParens.back() > prec::Unknown) { + !IsSimpleFunction(Current)) { CurrentState.NoLineBreak = true; } + if (Previous.is(TT_TemplateString) && Previous.opensScope()) CurrentState.NoLineBreak = true; @@ -831,7 +862,8 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, Previous.isNot(TT_TableGenDAGArgOpenerToBreak) && !(Current.MacroParent && Previous.MacroParent) && (Current.isNot(TT_LineComment) || - Previous.isOneOf(BK_BracedInit, TT_VerilogMultiLineListLParen))) { + Previous.isOneOf(BK_BracedInit, TT_VerilogMultiLineListLParen)) && + !IsInTemplateString(Current)) { CurrentState.Indent = State.Column + Spaces; CurrentState.IsAligned = true; } diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index cc45d5a8c5c1e..abcedb66b57cc 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -102,6 +102,7 @@ namespace format { TYPE(JsTypeColon) \ TYPE(JsTypeOperator) \ TYPE(JsTypeOptionalQuestion) \ + TYPE(LambdaDefinitionLParen) \ TYPE(LambdaLBrace) \ TYPE(LambdaLSquare) \ TYPE(LeadingJavaAnnotation) \ diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index b6d6e52ccb8f8..8cd5cf2484160 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -62,6 +62,7 @@ static bool canBeObjCSelectorComponent(const FormatToken &Tok) { /// With `Left` being '(', check if we're at either `[...](` or /// `[...]<...>(`, where the [ opens a lambda capture list. +// FIXME: this doesn't cover attributes/constraints before the l_paren. static bool isLambdaParameterList(const FormatToken *Left) { // Skip <...> if present. if (Left->Previous && Left->Previous->is(tok::greater) && @@ -154,8 +155,8 @@ class AnnotatingParser { if (NonTemplateLess.count(CurrentToken->Previous) > 0) return false; - const FormatToken &Previous = *CurrentToken->Previous; // The '<'. - if (Previous.Previous) { + if (const auto &Previous = *CurrentToken->Previous; // The '<'. + Previous.Previous) { if (Previous.Previous->Tok.isLiteral()) return false; if (Previous.Previous->is(tok::r_brace)) @@ -175,11 +176,13 @@ class AnnotatingParser { FormatToken *Left = CurrentToken->Previous; Left->ParentBracket = Contexts.back().ContextKind; ScopedContextCreator ContextCreator(*this, tok::less, 12); - Contexts.back().IsExpression = false; + + const auto *BeforeLess = Left->Previous; + // If there's a template keyword before the opening angle bracket, this is a // template parameter, not an argument. - if (Left->Previous && Left->Previous->isNot(tok::kw_template)) + if (BeforeLess && BeforeLess->isNot(tok::kw_template)) Contexts.back().ContextType = Context::TemplateArgument; if (Style.Language == FormatStyle::LK_Java && @@ -187,19 +190,24 @@ class AnnotatingParser { next(); } - while (CurrentToken) { + for (bool SeenTernaryOperator = false; CurrentToken;) { + const bool InExpr = Contexts[Contexts.size() - 2].IsExpression; if (CurrentToken->is(tok::greater)) { + const auto *Next = CurrentToken->Next; // Try to do a better job at looking for ">>" within the condition of // a statement. Conservatively insert spaces between consecutive ">" // tokens to prevent splitting right bitshift operators and potentially // altering program semantics. This check is overly conservative and // will prevent spaces from being inserted in select nested template // parameter cases, but should not alter program semantics. - if (CurrentToken->Next && CurrentToken->Next->is(tok::greater) && + if (Next && Next->is(tok::greater) && Left->ParentBracket != tok::less && CurrentToken->getStartOfNonWhitespace() == - CurrentToken->Next->getStartOfNonWhitespace().getLocWithOffset( - -1)) { + Next->getStartOfNonWhitespace().getLocWithOffset(-1)) { + return false; + } + if (InExpr && SeenTernaryOperator && + (!Next || !Next->isOneOf(tok::l_paren, tok::l_brace))) { return false; } Left->MatchingParen = CurrentToken; @@ -210,14 +218,14 @@ class AnnotatingParser { // msg: < item: data > // In TT_TextProto, map does not occur. if (Style.Language == FormatStyle::LK_TextProto || - (Style.Language == FormatStyle::LK_Proto && Left->Previous && - Left->Previous->isOneOf(TT_SelectorName, TT_DictLiteral))) { + (Style.Language == FormatStyle::LK_Proto && BeforeLess && + BeforeLess->isOneOf(TT_SelectorName, TT_DictLiteral))) { CurrentToken->setType(TT_DictLiteral); } else { CurrentToken->setType(TT_TemplateCloser); CurrentToken->Tok.setLength(1); } - if (CurrentToken->Next && CurrentToken->Next->Tok.isLiteral()) + if (Next && Next->Tok.isLiteral()) return false; next(); return true; @@ -229,18 +237,21 @@ class AnnotatingParser { } if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace)) return false; + const auto &Prev = *CurrentToken->Previous; // If a && or || is found and interpreted as a binary operator, this set // of angles is likely part of something like "a < b && c > d". If the // angles are inside an expression, the ||/&& might also be a binary // operator that was misinterpreted because we are parsing template // parameters. // FIXME: This is getting out of hand, write a decent parser. - if (CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) && - CurrentToken->Previous->is(TT_BinaryOperator) && - Contexts[Contexts.size() - 2].IsExpression && - !Line.startsWith(tok::kw_template)) { - return false; + if (InExpr && !Line.startsWith(tok::kw_template) && + Prev.is(TT_BinaryOperator)) { + const auto Precedence = Prev.getPrecedence(); + if (Precedence > prec::Conditional && Precedence < prec::Relational) + return false; } + if (Prev.is(TT_ConditionalExpr)) + SeenTernaryOperator = true; updateParameterCount(Left, CurrentToken); if (Style.Language == FormatStyle::LK_Proto) { if (FormatToken *Previous = CurrentToken->getPreviousNonComment()) { @@ -365,6 +376,7 @@ class AnnotatingParser { Contexts.back().IsExpression = false; } else if (isLambdaParameterList(&OpeningParen)) { // This is a parameter list of a lambda expression. + OpeningParen.setType(TT_LambdaDefinitionLParen); Contexts.back().IsExpression = false; } else if (OpeningParen.is(TT_RequiresExpressionLParen)) { Contexts.back().IsExpression = false; @@ -2458,9 +2470,9 @@ class AnnotatingParser { Current.setType(TT_CastRParen); if (Current.MatchingParen && Current.Next && !Current.Next->isBinaryOperator() && - !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace, - tok::comma, tok::period, tok::arrow, - tok::coloncolon, tok::kw_noexcept)) { + !Current.Next->isOneOf( + tok::semi, tok::colon, tok::l_brace, tok::l_paren, tok::comma, + tok::period, tok::arrow, tok::coloncolon, tok::kw_noexcept)) { if (FormatToken *AfterParen = Current.MatchingParen->Next; AfterParen && AfterParen->isNot(tok::caret)) { // Make sure this isn't the return type of an Obj-C block declaration. @@ -2616,8 +2628,10 @@ class AnnotatingParser { return false; // int a or auto a. - if (PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto)) + if (PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto) && + PreviousNotConst->isNot(TT_StatementAttributeLikeMacro)) { return true; + } // *a or &a or &&a. if (PreviousNotConst->is(TT_PointerOrReference)) @@ -6194,6 +6208,12 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, 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/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index d406a531a5c0c..ed056b9dd5b75 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -2554,7 +2554,7 @@ bool UnwrappedLineParser::parseParens(TokenType AmpAmpTokenType) { const bool DoubleParens = Prev && Prev->is(tok::l_paren) && Next && Next->is(tok::r_paren); const auto *PrevPrev = Prev ? Prev->getPreviousNonComment() : nullptr; - const bool Blacklisted = + const bool Disallowed = PrevPrev && (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) || (SeenEqual && @@ -2566,7 +2566,7 @@ bool UnwrappedLineParser::parseParens(TokenType AmpAmpTokenType) { (!NestedLambdas.empty() && !NestedLambdas.back())) && Prev && Prev->isOneOf(tok::kw_return, tok::kw_co_return) && Next && Next->is(tok::semi); - if ((DoubleParens && !Blacklisted) || ReturnParens) { + if ((DoubleParens && !Disallowed) || ReturnParens) { LeftParen->Optional = true; FormatTok->Optional = true; } diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index d2e8f9b47c06f..da52cddf5bb06 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1495,20 +1495,30 @@ void CompilerInvocation::setDefaultPointerAuthOptions( Key::ASDA, LangOpts.PointerAuthVTPtrAddressDiscrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination ? Discrimination::Type : Discrimination::None); - Opts.CXXTypeInfoVTablePointer = - PointerAuthSchema(Key::ASDA, false, Discrimination::None); + + if (LangOpts.PointerAuthTypeInfoVTPtrDiscrimination) + Opts.CXXTypeInfoVTablePointer = + PointerAuthSchema(Key::ASDA, true, Discrimination::Constant, + StdTypeInfoVTablePointerConstantDiscrimination); + else + Opts.CXXTypeInfoVTablePointer = + PointerAuthSchema(Key::ASDA, false, Discrimination::None); + Opts.CXXVTTVTablePointers = PointerAuthSchema(Key::ASDA, false, Discrimination::None); Opts.CXXVirtualFunctionPointers = Opts.CXXVirtualVariadicFunctionPointers = PointerAuthSchema(Key::ASIA, true, Discrimination::Decl); + Opts.CXXMemberFunctionPointers = + PointerAuthSchema(Key::ASIA, false, Discrimination::Type); } + Opts.IndirectGotos = LangOpts.PointerAuthIndirectGotos; } static void parsePointerAuthOptions(PointerAuthOptions &Opts, const LangOptions &LangOpts, const llvm::Triple &Triple, DiagnosticsEngine &Diags) { - if (!LangOpts.PointerAuthCalls) + if (!LangOpts.PointerAuthCalls && !LangOpts.PointerAuthIndirectGotos) return; CompilerInvocation::setDefaultPointerAuthOptions(Opts, LangOpts, Triple); @@ -3421,12 +3431,17 @@ static void GeneratePointerAuthArgs(const LangOptions &Opts, GenerateArg(Consumer, OPT_fptrauth_calls); if (Opts.PointerAuthReturns) GenerateArg(Consumer, OPT_fptrauth_returns); + if (Opts.PointerAuthIndirectGotos) + GenerateArg(Consumer, OPT_fptrauth_indirect_gotos); if (Opts.PointerAuthAuthTraps) GenerateArg(Consumer, OPT_fptrauth_auth_traps); if (Opts.PointerAuthVTPtrAddressDiscrimination) GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_address_discrimination); if (Opts.PointerAuthVTPtrTypeDiscrimination) GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_type_discrimination); + if (Opts.PointerAuthTypeInfoVTPtrDiscrimination) + GenerateArg(Consumer, OPT_fptrauth_type_info_vtable_pointer_discrimination); + if (Opts.PointerAuthInitFini) GenerateArg(Consumer, OPT_fptrauth_init_fini); if (Opts.PointerAuthFunctionTypeDiscrimination) @@ -3438,11 +3453,15 @@ static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args, Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics); Opts.PointerAuthCalls = Args.hasArg(OPT_fptrauth_calls); Opts.PointerAuthReturns = Args.hasArg(OPT_fptrauth_returns); + Opts.PointerAuthIndirectGotos = Args.hasArg(OPT_fptrauth_indirect_gotos); Opts.PointerAuthAuthTraps = Args.hasArg(OPT_fptrauth_auth_traps); Opts.PointerAuthVTPtrAddressDiscrimination = Args.hasArg(OPT_fptrauth_vtable_pointer_address_discrimination); Opts.PointerAuthVTPtrTypeDiscrimination = Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination); + Opts.PointerAuthTypeInfoVTPtrDiscrimination = + Args.hasArg(OPT_fptrauth_type_info_vtable_pointer_discrimination); + Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini); Opts.PointerAuthFunctionTypeDiscrimination = Args.hasArg(OPT_fptrauth_function_pointer_type_discrimination); diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 96a96289c35ef..87170fa26e631 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -1346,7 +1346,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, if (!LangOpts.MathErrno) Builder.defineMacro("__NO_MATH_ERRNO__"); - if (LangOpts.FastMath || LangOpts.FiniteMathOnly) + if (LangOpts.FastMath || (LangOpts.NoHonorInfs && LangOpts.NoHonorNaNs)) Builder.defineMacro("__FINITE_MATH_ONLY__", "1"); else Builder.defineMacro("__FINITE_MATH_ONLY__", "0"); diff --git a/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/clang/lib/Frontend/PrintPreprocessedOutput.cpp index 00549416ae811..6d413cbd07c8f 100644 --- a/clang/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/clang/lib/Frontend/PrintPreprocessedOutput.cpp @@ -1016,7 +1016,6 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, *Callbacks->OS << static_cast(*Iter); PrintComma = true; } - IsStartOfLine = true; } else if (Tok.isAnnotation()) { // Ignore annotation tokens created by pragmas - the pragmas themselves // will be reproduced in the preprocessed output. diff --git a/clang/lib/Headers/emmintrin.h b/clang/lib/Headers/emmintrin.h index e85bfc47aa5cc..a3176570a468f 100644 --- a/clang/lib/Headers/emmintrin.h +++ b/clang/lib/Headers/emmintrin.h @@ -52,9 +52,12 @@ typedef __bf16 __m128bh __attribute__((__vector_size__(16), __aligned__(16))); #define __DEFAULT_FN_ATTRS \ __attribute__((__always_inline__, __nodebug__, \ __target__("sse2,no-evex512"), __min_vector_width__(128))) -#define __DEFAULT_FN_ATTRS_MMX \ - __attribute__((__always_inline__, __nodebug__, \ - __target__("mmx,sse2,no-evex512"), __min_vector_width__(64))) + +#define __trunc64(x) \ + (__m64) __builtin_shufflevector((__v2di)(x), __extension__(__v2di){}, 0) +#define __anyext128(x) \ + (__m128i) __builtin_shufflevector((__v2si)(x), __extension__(__v2si){}, 0, \ + 1, -1, -1) /// Adds lower double-precision values in both operands and returns the /// sum in the lower 64 bits of the result. The upper 64 bits of the result @@ -1486,8 +1489,8 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_cvttsd_si32(__m128d __a) { /// \param __a /// A 128-bit vector of [2 x double]. /// \returns A 64-bit vector of [2 x i32] containing the converted values. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX _mm_cvtpd_pi32(__m128d __a) { - return (__m64)__builtin_ia32_cvtpd2pi((__v2df)__a); +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_cvtpd_pi32(__m128d __a) { + return __trunc64(__builtin_ia32_cvtpd2dq((__v2df)__a)); } /// Converts the two double-precision floating-point elements of a @@ -1505,8 +1508,8 @@ static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX _mm_cvtpd_pi32(__m128d __a) { /// \param __a /// A 128-bit vector of [2 x double]. /// \returns A 64-bit vector of [2 x i32] containing the converted values. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX _mm_cvttpd_pi32(__m128d __a) { - return (__m64)__builtin_ia32_cvttpd2pi((__v2df)__a); +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_cvttpd_pi32(__m128d __a) { + return __trunc64(__builtin_ia32_cvttpd2dq((__v2df)__a)); } /// Converts the two signed 32-bit integer elements of a 64-bit vector of @@ -1520,8 +1523,8 @@ static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX _mm_cvttpd_pi32(__m128d __a) { /// \param __a /// A 64-bit vector of [2 x i32]. /// \returns A 128-bit vector of [2 x double] containing the converted values. -static __inline__ __m128d __DEFAULT_FN_ATTRS_MMX _mm_cvtpi32_pd(__m64 __a) { - return __builtin_ia32_cvtpi2pd((__v2si)__a); +static __inline__ __m128d __DEFAULT_FN_ATTRS _mm_cvtpi32_pd(__m64 __a) { + return (__m128d) __builtin_convertvector((__v2si)__a, __v2df); } /// Returns the low-order element of a 128-bit vector of [2 x double] as @@ -2108,9 +2111,8 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_add_epi32(__m128i __a, /// \param __b /// A 64-bit integer. /// \returns A 64-bit integer containing the sum of both parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX _mm_add_si64(__m64 __a, - __m64 __b) { - return (__m64)__builtin_ia32_paddq((__v1di)__a, (__v1di)__b); +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_add_si64(__m64 __a, __m64 __b) { + return (__m64)(((unsigned long long)__a) + ((unsigned long long)__b)); } /// Adds the corresponding elements of two 128-bit vectors of [2 x i64], @@ -2431,9 +2433,9 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_mullo_epi16(__m128i __a, /// \param __b /// A 64-bit integer containing one of the source operands. /// \returns A 64-bit integer vector containing the product of both operands. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX _mm_mul_su32(__m64 __a, - __m64 __b) { - return __builtin_ia32_pmuludq((__v2si)__a, (__v2si)__b); +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_mul_su32(__m64 __a, __m64 __b) { + return __trunc64(__builtin_ia32_pmuludq128((__v4si)__anyext128(__a), + (__v4si)__anyext128(__b))); } /// Multiplies 32-bit unsigned integer values contained in the lower @@ -2539,9 +2541,8 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_sub_epi32(__m128i __a, /// A 64-bit integer vector containing the subtrahend. /// \returns A 64-bit integer vector containing the difference of the values in /// the operands. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX _mm_sub_si64(__m64 __a, - __m64 __b) { - return (__m64)__builtin_ia32_psubq((__v1di)__a, (__v1di)__b); +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_sub_si64(__m64 __a, __m64 __b) { + return (__m64)((unsigned long long)__a - (unsigned long long)__b); } /// Subtracts the corresponding elements of two [2 x i64] vectors. @@ -4889,8 +4890,10 @@ void _mm_pause(void); #if defined(__cplusplus) } // extern "C" #endif + +#undef __anyext128 +#undef __trunc64 #undef __DEFAULT_FN_ATTRS -#undef __DEFAULT_FN_ATTRS_MMX #define _MM_SHUFFLE2(x, y) (((x) << 1) | (y)) diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 09f26a4588c14..6d86d278bc711 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -145,106 +145,106 @@ float4 acos(float4); #ifdef __HLSL_ENABLE_16_BIT _HLSL_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(int16_t); _HLSL_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(int16_t2); _HLSL_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(int16_t3); _HLSL_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(int16_t4); _HLSL_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(uint16_t); _HLSL_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(uint16_t2); _HLSL_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(uint16_t3); _HLSL_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(uint16_t4); #endif _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(half); _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(half2); _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(half3); _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(half4); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(bool); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(bool2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(bool3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(bool4); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(int); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(int2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(int3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(int4); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(uint); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(uint2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(uint3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(uint4); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(float); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(float2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(float3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(float4); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(int64_t); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(int64_t2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(int64_t3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(int64_t4); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(uint64_t); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(uint64_t2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(uint64_t3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(uint64_t4); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(double); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(double2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(double3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_all) bool all(double4); //===----------------------------------------------------------------------===// @@ -257,106 +257,106 @@ bool all(double4); #ifdef __HLSL_ENABLE_16_BIT _HLSL_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(int16_t); _HLSL_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(int16_t2); _HLSL_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(int16_t3); _HLSL_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(int16_t4); _HLSL_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(uint16_t); _HLSL_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(uint16_t2); _HLSL_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(uint16_t3); _HLSL_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(uint16_t4); #endif _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(half); _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(half2); _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(half3); _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(half4); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(bool); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(bool2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(bool3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(bool4); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(int); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(int2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(int3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(int4); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(uint); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(uint2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(uint3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(uint4); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(float); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(float2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(float3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(float4); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(int64_t); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(int64_t2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(int64_t3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(int64_t4); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(uint64_t); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(uint64_t2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(uint64_t3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(uint64_t4); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(double); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(double2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(double3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(double4); //===----------------------------------------------------------------------===// diff --git a/clang/lib/Headers/mmintrin.h b/clang/lib/Headers/mmintrin.h index 4e154e2d85935..9d1e135be63be 100644 --- a/clang/lib/Headers/mmintrin.h +++ b/clang/lib/Headers/mmintrin.h @@ -21,10 +21,33 @@ typedef int __v2si __attribute__((__vector_size__(8))); typedef short __v4hi __attribute__((__vector_size__(8))); typedef char __v8qi __attribute__((__vector_size__(8))); +/* Unsigned types */ +typedef unsigned long long __v1du __attribute__ ((__vector_size__ (8))); +typedef unsigned int __v2su __attribute__ ((__vector_size__ (8))); +typedef unsigned short __v4hu __attribute__((__vector_size__(8))); +typedef unsigned char __v8qu __attribute__((__vector_size__(8))); + +/* We need an explicitly signed variant for char. Note that this shouldn't + * appear in the interface though. */ +typedef signed char __v8qs __attribute__((__vector_size__(8))); + +/* SSE/SSE2 types */ +typedef long long __m128i __attribute__((__vector_size__(16), __aligned__(16))); +typedef long long __v2di __attribute__ ((__vector_size__ (16))); +typedef int __v4si __attribute__((__vector_size__(16))); +typedef short __v8hi __attribute__((__vector_size__(16))); +typedef char __v16qi __attribute__((__vector_size__(16))); + /* Define the default attributes for the functions in this file. */ -#define __DEFAULT_FN_ATTRS \ - __attribute__((__always_inline__, __nodebug__, __target__("mmx,no-evex512"), \ - __min_vector_width__(64))) +#define __DEFAULT_FN_ATTRS_SSE2 \ + __attribute__((__always_inline__, __nodebug__, \ + __target__("sse2,no-evex512"), __min_vector_width__(128))) + +#define __trunc64(x) \ + (__m64) __builtin_shufflevector((__v2di)(x), __extension__(__v2di){}, 0) +#define __anyext128(x) \ + (__m128i) __builtin_shufflevector((__v2si)(x), __extension__(__v2si){}, 0, \ + 1, -1, -1) /// Clears the MMX state by setting the state of the x87 stack registers /// to empty. @@ -50,10 +73,10 @@ _mm_empty(void) { /// A 32-bit integer value. /// \returns A 64-bit integer vector. The lower 32 bits contain the value of the /// parameter. The upper 32 bits are set to 0. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_cvtsi32_si64(int __i) { - return (__m64)__builtin_ia32_vec_init_v2si(__i, 0); + return __extension__ (__m64)(__v2si){__i, 0}; } /// Returns the lower 32 bits of a 64-bit integer vector as a 32-bit @@ -67,10 +90,10 @@ _mm_cvtsi32_si64(int __i) /// A 64-bit integer vector. /// \returns A 32-bit signed integer value containing the lower 32 bits of the /// parameter. -static __inline__ int __DEFAULT_FN_ATTRS +static __inline__ int __DEFAULT_FN_ATTRS_SSE2 _mm_cvtsi64_si32(__m64 __m) { - return __builtin_ia32_vec_ext_v2si((__v2si)__m, 0); + return ((__v2si)__m)[0]; } /// Casts a 64-bit signed integer value into a 64-bit integer vector. @@ -83,7 +106,7 @@ _mm_cvtsi64_si32(__m64 __m) /// A 64-bit signed integer. /// \returns A 64-bit integer vector containing the same bitwise pattern as the /// parameter. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_cvtsi64_m64(long long __i) { return (__m64)__i; @@ -99,7 +122,7 @@ _mm_cvtsi64_m64(long long __i) /// A 64-bit integer vector. /// \returns A 64-bit signed integer containing the same bitwise pattern as the /// parameter. -static __inline__ long long __DEFAULT_FN_ATTRS +static __inline__ long long __DEFAULT_FN_ATTRS_SSE2 _mm_cvtm64_si64(__m64 __m) { return (long long)__m; @@ -124,10 +147,11 @@ _mm_cvtm64_si64(__m64 __m) /// written to the upper 32 bits of the result. /// \returns A 64-bit integer vector of [8 x i8] containing the converted /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_packs_pi16(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_packsswb((__v4hi)__m1, (__v4hi)__m2); + return __trunc64(__builtin_ia32_packsswb128( + (__v8hi)__builtin_shufflevector(__m1, __m2, 0, 1), (__v8hi){})); } /// Converts, with saturation, 32-bit signed integers from both 64-bit integer @@ -149,10 +173,11 @@ _mm_packs_pi16(__m64 __m1, __m64 __m2) /// written to the upper 32 bits of the result. /// \returns A 64-bit integer vector of [4 x i16] containing the converted /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_packs_pi32(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_packssdw((__v2si)__m1, (__v2si)__m2); + return __trunc64(__builtin_ia32_packssdw128( + (__v4si)__builtin_shufflevector(__m1, __m2, 0, 1), (__v4si){})); } /// Converts, with saturation, 16-bit signed integers from both 64-bit integer @@ -174,10 +199,11 @@ _mm_packs_pi32(__m64 __m1, __m64 __m2) /// written to the upper 32 bits of the result. /// \returns A 64-bit integer vector of [8 x i8] containing the converted /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_packs_pu16(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_packuswb((__v4hi)__m1, (__v4hi)__m2); + return __trunc64(__builtin_ia32_packuswb128( + (__v8hi)__builtin_shufflevector(__m1, __m2, 0, 1), (__v8hi){})); } /// Unpacks the upper 32 bits from two 64-bit integer vectors of [8 x i8] @@ -201,10 +227,11 @@ _mm_packs_pu16(__m64 __m1, __m64 __m2) /// Bits [63:56] are written to bits [63:56] of the result. /// \returns A 64-bit integer vector of [8 x i8] containing the interleaved /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_unpackhi_pi8(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_punpckhbw((__v8qi)__m1, (__v8qi)__m2); + return (__m64)__builtin_shufflevector((__v8qi)__m1, (__v8qi)__m2, + 4, 12, 5, 13, 6, 14, 7, 15); } /// Unpacks the upper 32 bits from two 64-bit integer vectors of @@ -224,10 +251,11 @@ _mm_unpackhi_pi8(__m64 __m1, __m64 __m2) /// Bits [63:48] are written to bits [63:48] of the result. /// \returns A 64-bit integer vector of [4 x i16] containing the interleaved /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_unpackhi_pi16(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_punpckhwd((__v4hi)__m1, (__v4hi)__m2); + return (__m64)__builtin_shufflevector((__v4hi)__m1, (__v4hi)__m2, + 2, 6, 3, 7); } /// Unpacks the upper 32 bits from two 64-bit integer vectors of @@ -245,10 +273,10 @@ _mm_unpackhi_pi16(__m64 __m1, __m64 __m2) /// the upper 32 bits of the result. /// \returns A 64-bit integer vector of [2 x i32] containing the interleaved /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_unpackhi_pi32(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_punpckhdq((__v2si)__m1, (__v2si)__m2); + return (__m64)__builtin_shufflevector((__v2si)__m1, (__v2si)__m2, 1, 3); } /// Unpacks the lower 32 bits from two 64-bit integer vectors of [8 x i8] @@ -272,10 +300,11 @@ _mm_unpackhi_pi32(__m64 __m1, __m64 __m2) /// Bits [31:24] are written to bits [63:56] of the result. /// \returns A 64-bit integer vector of [8 x i8] containing the interleaved /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_unpacklo_pi8(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_punpcklbw((__v8qi)__m1, (__v8qi)__m2); + return (__m64)__builtin_shufflevector((__v8qi)__m1, (__v8qi)__m2, + 0, 8, 1, 9, 2, 10, 3, 11); } /// Unpacks the lower 32 bits from two 64-bit integer vectors of @@ -295,10 +324,11 @@ _mm_unpacklo_pi8(__m64 __m1, __m64 __m2) /// Bits [31:16] are written to bits [63:48] of the result. /// \returns A 64-bit integer vector of [4 x i16] containing the interleaved /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_unpacklo_pi16(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_punpcklwd((__v4hi)__m1, (__v4hi)__m2); + return (__m64)__builtin_shufflevector((__v4hi)__m1, (__v4hi)__m2, + 0, 4, 1, 5); } /// Unpacks the lower 32 bits from two 64-bit integer vectors of @@ -316,10 +346,10 @@ _mm_unpacklo_pi16(__m64 __m1, __m64 __m2) /// the upper 32 bits of the result. /// \returns A 64-bit integer vector of [2 x i32] containing the interleaved /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_unpacklo_pi32(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_punpckldq((__v2si)__m1, (__v2si)__m2); + return (__m64)__builtin_shufflevector((__v2si)__m1, (__v2si)__m2, 0, 2); } /// Adds each 8-bit integer element of the first 64-bit integer vector @@ -337,10 +367,10 @@ _mm_unpacklo_pi32(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [8 x i8]. /// \returns A 64-bit integer vector of [8 x i8] containing the sums of both /// parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_add_pi8(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_paddb((__v8qi)__m1, (__v8qi)__m2); + return (__m64)(((__v8qu)__m1) + ((__v8qu)__m2)); } /// Adds each 16-bit integer element of the first 64-bit integer vector @@ -358,10 +388,10 @@ _mm_add_pi8(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [4 x i16]. /// \returns A 64-bit integer vector of [4 x i16] containing the sums of both /// parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_add_pi16(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_paddw((__v4hi)__m1, (__v4hi)__m2); + return (__m64)(((__v4hu)__m1) + ((__v4hu)__m2)); } /// Adds each 32-bit integer element of the first 64-bit integer vector @@ -379,10 +409,10 @@ _mm_add_pi16(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [2 x i32]. /// \returns A 64-bit integer vector of [2 x i32] containing the sums of both /// parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_add_pi32(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_paddd((__v2si)__m1, (__v2si)__m2); + return (__m64)(((__v2su)__m1) + ((__v2su)__m2)); } /// Adds, with saturation, each 8-bit signed integer element of the first @@ -403,10 +433,10 @@ _mm_add_pi32(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [8 x i8]. /// \returns A 64-bit integer vector of [8 x i8] containing the saturated sums /// of both parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_adds_pi8(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_paddsb((__v8qi)__m1, (__v8qi)__m2); + return (__m64)__builtin_elementwise_add_sat((__v8qs)__m1, (__v8qs)__m2); } /// Adds, with saturation, each 16-bit signed integer element of the first @@ -427,10 +457,10 @@ _mm_adds_pi8(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [4 x i16]. /// \returns A 64-bit integer vector of [4 x i16] containing the saturated sums /// of both parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_adds_pi16(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_paddsw((__v4hi)__m1, (__v4hi)__m2); + return (__m64)__builtin_elementwise_add_sat((__v4hi)__m1, (__v4hi)__m2); } /// Adds, with saturation, each 8-bit unsigned integer element of the first @@ -450,10 +480,10 @@ _mm_adds_pi16(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [8 x i8]. /// \returns A 64-bit integer vector of [8 x i8] containing the saturated /// unsigned sums of both parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_adds_pu8(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_paddusb((__v8qi)__m1, (__v8qi)__m2); + return (__m64)__builtin_elementwise_add_sat((__v8qu)__m1, (__v8qu)__m2); } /// Adds, with saturation, each 16-bit unsigned integer element of the first @@ -473,10 +503,10 @@ _mm_adds_pu8(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [4 x i16]. /// \returns A 64-bit integer vector of [4 x i16] containing the saturated /// unsigned sums of both parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_adds_pu16(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_paddusw((__v4hi)__m1, (__v4hi)__m2); + return (__m64)__builtin_elementwise_add_sat((__v4hu)__m1, (__v4hu)__m2); } /// Subtracts each 8-bit integer element of the second 64-bit integer @@ -494,10 +524,10 @@ _mm_adds_pu16(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [8 x i8] containing the subtrahends. /// \returns A 64-bit integer vector of [8 x i8] containing the differences of /// both parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_sub_pi8(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_psubb((__v8qi)__m1, (__v8qi)__m2); + return (__m64)(((__v8qu)__m1) - ((__v8qu)__m2)); } /// Subtracts each 16-bit integer element of the second 64-bit integer @@ -515,10 +545,10 @@ _mm_sub_pi8(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [4 x i16] containing the subtrahends. /// \returns A 64-bit integer vector of [4 x i16] containing the differences of /// both parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_sub_pi16(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_psubw((__v4hi)__m1, (__v4hi)__m2); + return (__m64)(((__v4hu)__m1) - ((__v4hu)__m2)); } /// Subtracts each 32-bit integer element of the second 64-bit integer @@ -536,10 +566,10 @@ _mm_sub_pi16(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [2 x i32] containing the subtrahends. /// \returns A 64-bit integer vector of [2 x i32] containing the differences of /// both parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_sub_pi32(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_psubd((__v2si)__m1, (__v2si)__m2); + return (__m64)(((__v2su)__m1) - ((__v2su)__m2)); } /// Subtracts, with saturation, each 8-bit signed integer element of the second @@ -560,10 +590,10 @@ _mm_sub_pi32(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [8 x i8] containing the subtrahends. /// \returns A 64-bit integer vector of [8 x i8] containing the saturated /// differences of both parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_subs_pi8(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_psubsb((__v8qi)__m1, (__v8qi)__m2); + return (__m64)__builtin_elementwise_sub_sat((__v8qs)__m1, (__v8qs)__m2); } /// Subtracts, with saturation, each 16-bit signed integer element of the @@ -584,10 +614,10 @@ _mm_subs_pi8(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [4 x i16] containing the subtrahends. /// \returns A 64-bit integer vector of [4 x i16] containing the saturated /// differences of both parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_subs_pi16(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_psubsw((__v4hi)__m1, (__v4hi)__m2); + return (__m64)__builtin_elementwise_sub_sat((__v4hi)__m1, (__v4hi)__m2); } /// Subtracts each 8-bit unsigned integer element of the second 64-bit @@ -608,10 +638,10 @@ _mm_subs_pi16(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [8 x i8] containing the subtrahends. /// \returns A 64-bit integer vector of [8 x i8] containing the saturated /// differences of both parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_subs_pu8(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_psubusb((__v8qi)__m1, (__v8qi)__m2); + return (__m64)__builtin_elementwise_sub_sat((__v8qu)__m1, (__v8qu)__m2); } /// Subtracts each 16-bit unsigned integer element of the second 64-bit @@ -632,10 +662,10 @@ _mm_subs_pu8(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [4 x i16] containing the subtrahends. /// \returns A 64-bit integer vector of [4 x i16] containing the saturated /// differences of both parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_subs_pu16(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_psubusw((__v4hi)__m1, (__v4hi)__m2); + return (__m64)__builtin_elementwise_sub_sat((__v4hu)__m1, (__v4hu)__m2); } /// Multiplies each 16-bit signed integer element of the first 64-bit @@ -659,10 +689,11 @@ _mm_subs_pu16(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [4 x i16]. /// \returns A 64-bit integer vector of [2 x i32] containing the sums of /// products of both parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_madd_pi16(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_pmaddwd((__v4hi)__m1, (__v4hi)__m2); + return __trunc64(__builtin_ia32_pmaddwd128((__v8hi)__anyext128(__m1), + (__v8hi)__anyext128(__m2))); } /// Multiplies each 16-bit signed integer element of the first 64-bit @@ -680,10 +711,11 @@ _mm_madd_pi16(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [4 x i16]. /// \returns A 64-bit integer vector of [4 x i16] containing the upper 16 bits /// of the products of both parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_mulhi_pi16(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_pmulhw((__v4hi)__m1, (__v4hi)__m2); + return __trunc64(__builtin_ia32_pmulhw128((__v8hi)__anyext128(__m1), + (__v8hi)__anyext128(__m2))); } /// Multiplies each 16-bit signed integer element of the first 64-bit @@ -701,10 +733,10 @@ _mm_mulhi_pi16(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [4 x i16]. /// \returns A 64-bit integer vector of [4 x i16] containing the lower 16 bits /// of the products of both parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_mullo_pi16(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_pmullw((__v4hi)__m1, (__v4hi)__m2); + return (__m64)(((__v4hu)__m1) * ((__v4hu)__m2)); } /// Left-shifts each 16-bit signed integer element of the first @@ -724,10 +756,11 @@ _mm_mullo_pi16(__m64 __m1, __m64 __m2) /// \returns A 64-bit integer vector of [4 x i16] containing the left-shifted /// values. If \a __count is greater or equal to 16, the result is set to all /// 0. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_sll_pi16(__m64 __m, __m64 __count) { - return (__m64)__builtin_ia32_psllw((__v4hi)__m, __count); + return __trunc64(__builtin_ia32_psllw128((__v8hi)__anyext128(__m), + (__v8hi)__anyext128(__count))); } /// Left-shifts each 16-bit signed integer element of a 64-bit integer @@ -746,10 +779,11 @@ _mm_sll_pi16(__m64 __m, __m64 __count) /// \returns A 64-bit integer vector of [4 x i16] containing the left-shifted /// values. If \a __count is greater or equal to 16, the result is set to all /// 0. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_slli_pi16(__m64 __m, int __count) { - return (__m64)__builtin_ia32_psllwi((__v4hi)__m, __count); + return __trunc64(__builtin_ia32_psllwi128((__v8hi)__anyext128(__m), + __count)); } /// Left-shifts each 32-bit signed integer element of the first @@ -769,10 +803,11 @@ _mm_slli_pi16(__m64 __m, int __count) /// \returns A 64-bit integer vector of [2 x i32] containing the left-shifted /// values. If \a __count is greater or equal to 32, the result is set to all /// 0. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_sll_pi32(__m64 __m, __m64 __count) { - return (__m64)__builtin_ia32_pslld((__v2si)__m, __count); + return __trunc64(__builtin_ia32_pslld128((__v4si)__anyext128(__m), + (__v4si)__anyext128(__count))); } /// Left-shifts each 32-bit signed integer element of a 64-bit integer @@ -791,10 +826,11 @@ _mm_sll_pi32(__m64 __m, __m64 __count) /// \returns A 64-bit integer vector of [2 x i32] containing the left-shifted /// values. If \a __count is greater or equal to 32, the result is set to all /// 0. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_slli_pi32(__m64 __m, int __count) { - return (__m64)__builtin_ia32_pslldi((__v2si)__m, __count); + return __trunc64(__builtin_ia32_pslldi128((__v4si)__anyext128(__m), + __count)); } /// Left-shifts the first 64-bit integer parameter by the number of bits @@ -811,10 +847,11 @@ _mm_slli_pi32(__m64 __m, int __count) /// A 64-bit integer vector interpreted as a single 64-bit integer. /// \returns A 64-bit integer vector containing the left-shifted value. If /// \a __count is greater or equal to 64, the result is set to 0. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_sll_si64(__m64 __m, __m64 __count) { - return (__m64)__builtin_ia32_psllq((__v1di)__m, __count); + return __trunc64(__builtin_ia32_psllq128((__v2di)__anyext128(__m), + (__v2di)__anyext128(__count))); } /// Left-shifts the first parameter, which is a 64-bit integer, by the @@ -831,10 +868,11 @@ _mm_sll_si64(__m64 __m, __m64 __count) /// A 32-bit integer value. /// \returns A 64-bit integer vector containing the left-shifted value. If /// \a __count is greater or equal to 64, the result is set to 0. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_slli_si64(__m64 __m, int __count) { - return (__m64)__builtin_ia32_psllqi((__v1di)__m, __count); + return __trunc64(__builtin_ia32_psllqi128((__v2di)__anyext128(__m), + __count)); } /// Right-shifts each 16-bit integer element of the first parameter, @@ -855,10 +893,11 @@ _mm_slli_si64(__m64 __m, int __count) /// A 64-bit integer vector interpreted as a single 64-bit integer. /// \returns A 64-bit integer vector of [4 x i16] containing the right-shifted /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_sra_pi16(__m64 __m, __m64 __count) { - return (__m64)__builtin_ia32_psraw((__v4hi)__m, __count); + return __trunc64(__builtin_ia32_psraw128((__v8hi)__anyext128(__m), + (__v8hi)__anyext128(__count))); } /// Right-shifts each 16-bit integer element of a 64-bit integer vector @@ -878,10 +917,11 @@ _mm_sra_pi16(__m64 __m, __m64 __count) /// A 32-bit integer value. /// \returns A 64-bit integer vector of [4 x i16] containing the right-shifted /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_srai_pi16(__m64 __m, int __count) { - return (__m64)__builtin_ia32_psrawi((__v4hi)__m, __count); + return __trunc64(__builtin_ia32_psrawi128((__v8hi)__anyext128(__m), + __count)); } /// Right-shifts each 32-bit integer element of the first parameter, @@ -902,10 +942,11 @@ _mm_srai_pi16(__m64 __m, int __count) /// A 64-bit integer vector interpreted as a single 64-bit integer. /// \returns A 64-bit integer vector of [2 x i32] containing the right-shifted /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_sra_pi32(__m64 __m, __m64 __count) { - return (__m64)__builtin_ia32_psrad((__v2si)__m, __count); + return __trunc64(__builtin_ia32_psrad128((__v4si)__anyext128(__m), + (__v4si)__anyext128(__count))); } /// Right-shifts each 32-bit integer element of a 64-bit integer vector @@ -925,10 +966,11 @@ _mm_sra_pi32(__m64 __m, __m64 __count) /// A 32-bit integer value. /// \returns A 64-bit integer vector of [2 x i32] containing the right-shifted /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_srai_pi32(__m64 __m, int __count) { - return (__m64)__builtin_ia32_psradi((__v2si)__m, __count); + return __trunc64(__builtin_ia32_psradi128((__v4si)__anyext128(__m), + __count)); } /// Right-shifts each 16-bit integer element of the first parameter, @@ -948,10 +990,11 @@ _mm_srai_pi32(__m64 __m, int __count) /// A 64-bit integer vector interpreted as a single 64-bit integer. /// \returns A 64-bit integer vector of [4 x i16] containing the right-shifted /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_srl_pi16(__m64 __m, __m64 __count) { - return (__m64)__builtin_ia32_psrlw((__v4hi)__m, __count); + return __trunc64(__builtin_ia32_psrlw128((__v8hi)__anyext128(__m), + (__v8hi)__anyext128(__count))); } /// Right-shifts each 16-bit integer element of a 64-bit integer vector @@ -970,10 +1013,11 @@ _mm_srl_pi16(__m64 __m, __m64 __count) /// A 32-bit integer value. /// \returns A 64-bit integer vector of [4 x i16] containing the right-shifted /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_srli_pi16(__m64 __m, int __count) { - return (__m64)__builtin_ia32_psrlwi((__v4hi)__m, __count); + return __trunc64(__builtin_ia32_psrlwi128((__v8hi)__anyext128(__m), + __count)); } /// Right-shifts each 32-bit integer element of the first parameter, @@ -993,10 +1037,11 @@ _mm_srli_pi16(__m64 __m, int __count) /// A 64-bit integer vector interpreted as a single 64-bit integer. /// \returns A 64-bit integer vector of [2 x i32] containing the right-shifted /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_srl_pi32(__m64 __m, __m64 __count) { - return (__m64)__builtin_ia32_psrld((__v2si)__m, __count); + return __trunc64(__builtin_ia32_psrld128((__v4si)__anyext128(__m), + (__v4si)__anyext128(__count))); } /// Right-shifts each 32-bit integer element of a 64-bit integer vector @@ -1015,10 +1060,11 @@ _mm_srl_pi32(__m64 __m, __m64 __count) /// A 32-bit integer value. /// \returns A 64-bit integer vector of [2 x i32] containing the right-shifted /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_srli_pi32(__m64 __m, int __count) { - return (__m64)__builtin_ia32_psrldi((__v2si)__m, __count); + return __trunc64(__builtin_ia32_psrldi128((__v4si)__anyext128(__m), + __count)); } /// Right-shifts the first 64-bit integer parameter by the number of bits @@ -1035,10 +1081,11 @@ _mm_srli_pi32(__m64 __m, int __count) /// \param __count /// A 64-bit integer vector interpreted as a single 64-bit integer. /// \returns A 64-bit integer vector containing the right-shifted value. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_srl_si64(__m64 __m, __m64 __count) { - return (__m64)__builtin_ia32_psrlq((__v1di)__m, __count); + return __trunc64(__builtin_ia32_psrlq128((__v2di)__anyext128(__m), + (__v2di)__anyext128(__count))); } /// Right-shifts the first parameter, which is a 64-bit integer, by the @@ -1056,10 +1103,11 @@ _mm_srl_si64(__m64 __m, __m64 __count) /// \param __count /// A 32-bit integer value. /// \returns A 64-bit integer vector containing the right-shifted value. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_srli_si64(__m64 __m, int __count) { - return (__m64)__builtin_ia32_psrlqi((__v1di)__m, __count); + return __trunc64(__builtin_ia32_psrlqi128((__v2di)__anyext128(__m), + __count)); } /// Performs a bitwise AND of two 64-bit integer vectors. @@ -1074,10 +1122,10 @@ _mm_srli_si64(__m64 __m, int __count) /// A 64-bit integer vector. /// \returns A 64-bit integer vector containing the bitwise AND of both /// parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_and_si64(__m64 __m1, __m64 __m2) { - return __builtin_ia32_pand((__v1di)__m1, (__v1di)__m2); + return (__m64)(((__v1du)__m1) & ((__v1du)__m2)); } /// Performs a bitwise NOT of the first 64-bit integer vector, and then @@ -1095,10 +1143,10 @@ _mm_and_si64(__m64 __m1, __m64 __m2) /// A 64-bit integer vector. /// \returns A 64-bit integer vector containing the bitwise AND of the second /// parameter and the one's complement of the first parameter. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_andnot_si64(__m64 __m1, __m64 __m2) { - return __builtin_ia32_pandn((__v1di)__m1, (__v1di)__m2); + return (__m64)(~((__v1du)__m1) & ((__v1du)__m2)); } /// Performs a bitwise OR of two 64-bit integer vectors. @@ -1113,10 +1161,10 @@ _mm_andnot_si64(__m64 __m1, __m64 __m2) /// A 64-bit integer vector. /// \returns A 64-bit integer vector containing the bitwise OR of both /// parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_or_si64(__m64 __m1, __m64 __m2) { - return __builtin_ia32_por((__v1di)__m1, (__v1di)__m2); + return (__m64)(((__v1du)__m1) | ((__v1du)__m2)); } /// Performs a bitwise exclusive OR of two 64-bit integer vectors. @@ -1131,10 +1179,10 @@ _mm_or_si64(__m64 __m1, __m64 __m2) /// A 64-bit integer vector. /// \returns A 64-bit integer vector containing the bitwise exclusive OR of both /// parameters. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_xor_si64(__m64 __m1, __m64 __m2) { - return __builtin_ia32_pxor((__v1di)__m1, (__v1di)__m2); + return (__m64)(((__v1du)__m1) ^ ((__v1du)__m2)); } /// Compares the 8-bit integer elements of two 64-bit integer vectors of @@ -1153,10 +1201,10 @@ _mm_xor_si64(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [8 x i8]. /// \returns A 64-bit integer vector of [8 x i8] containing the comparison /// results. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_cmpeq_pi8(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_pcmpeqb((__v8qi)__m1, (__v8qi)__m2); + return (__m64)(((__v8qi)__m1) == ((__v8qi)__m2)); } /// Compares the 16-bit integer elements of two 64-bit integer vectors of @@ -1175,10 +1223,10 @@ _mm_cmpeq_pi8(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [4 x i16]. /// \returns A 64-bit integer vector of [4 x i16] containing the comparison /// results. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_cmpeq_pi16(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_pcmpeqw((__v4hi)__m1, (__v4hi)__m2); + return (__m64)(((__v4hi)__m1) == ((__v4hi)__m2)); } /// Compares the 32-bit integer elements of two 64-bit integer vectors of @@ -1197,10 +1245,10 @@ _mm_cmpeq_pi16(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [2 x i32]. /// \returns A 64-bit integer vector of [2 x i32] containing the comparison /// results. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_cmpeq_pi32(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_pcmpeqd((__v2si)__m1, (__v2si)__m2); + return (__m64)(((__v2si)__m1) == ((__v2si)__m2)); } /// Compares the 8-bit integer elements of two 64-bit integer vectors of @@ -1219,10 +1267,12 @@ _mm_cmpeq_pi32(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [8 x i8]. /// \returns A 64-bit integer vector of [8 x i8] containing the comparison /// results. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_cmpgt_pi8(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_pcmpgtb((__v8qi)__m1, (__v8qi)__m2); + /* This function always performs a signed comparison, but __v8qi is a char + which may be signed or unsigned, so use __v8qs. */ + return (__m64)((__v8qs)__m1 > (__v8qs)__m2); } /// Compares the 16-bit integer elements of two 64-bit integer vectors of @@ -1241,10 +1291,10 @@ _mm_cmpgt_pi8(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [4 x i16]. /// \returns A 64-bit integer vector of [4 x i16] containing the comparison /// results. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_cmpgt_pi16(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_pcmpgtw((__v4hi)__m1, (__v4hi)__m2); + return (__m64)((__v4hi)__m1 > (__v4hi)__m2); } /// Compares the 32-bit integer elements of two 64-bit integer vectors of @@ -1263,10 +1313,10 @@ _mm_cmpgt_pi16(__m64 __m1, __m64 __m2) /// A 64-bit integer vector of [2 x i32]. /// \returns A 64-bit integer vector of [2 x i32] containing the comparison /// results. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_cmpgt_pi32(__m64 __m1, __m64 __m2) { - return (__m64)__builtin_ia32_pcmpgtd((__v2si)__m1, (__v2si)__m2); + return (__m64)((__v2si)__m1 > (__v2si)__m2); } /// Constructs a 64-bit integer vector initialized to zero. @@ -1276,7 +1326,7 @@ _mm_cmpgt_pi32(__m64 __m1, __m64 __m2) /// This intrinsic corresponds to the PXOR instruction. /// /// \returns An initialized 64-bit integer vector with all elements set to zero. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_setzero_si64(void) { return __extension__ (__m64){ 0LL }; @@ -1297,10 +1347,10 @@ _mm_setzero_si64(void) /// A 32-bit integer value used to initialize the lower 32 bits of the /// result. /// \returns An initialized 64-bit integer vector. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_set_pi32(int __i1, int __i0) { - return (__m64)__builtin_ia32_vec_init_v2si(__i0, __i1); + return __extension__ (__m64)(__v2si){__i0, __i1}; } /// Constructs a 64-bit integer vector initialized with the specified @@ -1320,10 +1370,10 @@ _mm_set_pi32(int __i1, int __i0) /// \param __s0 /// A 16-bit integer value used to initialize bits [15:0] of the result. /// \returns An initialized 64-bit integer vector. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_set_pi16(short __s3, short __s2, short __s1, short __s0) { - return (__m64)__builtin_ia32_vec_init_v4hi(__s0, __s1, __s2, __s3); + return __extension__ (__m64)(__v4hi){__s0, __s1, __s2, __s3}; } /// Constructs a 64-bit integer vector initialized with the specified @@ -1351,12 +1401,12 @@ _mm_set_pi16(short __s3, short __s2, short __s1, short __s0) /// \param __b0 /// An 8-bit integer value used to initialize bits [7:0] of the result. /// \returns An initialized 64-bit integer vector. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_set_pi8(char __b7, char __b6, char __b5, char __b4, char __b3, char __b2, char __b1, char __b0) { - return (__m64)__builtin_ia32_vec_init_v8qi(__b0, __b1, __b2, __b3, - __b4, __b5, __b6, __b7); + return __extension__ (__m64)(__v8qi){__b0, __b1, __b2, __b3, + __b4, __b5, __b6, __b7}; } /// Constructs a 64-bit integer vector of [2 x i32], with each of the @@ -1372,7 +1422,7 @@ _mm_set_pi8(char __b7, char __b6, char __b5, char __b4, char __b3, char __b2, /// A 32-bit integer value used to initialize each vector element of the /// result. /// \returns An initialized 64-bit integer vector of [2 x i32]. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_set1_pi32(int __i) { return _mm_set_pi32(__i, __i); @@ -1391,7 +1441,7 @@ _mm_set1_pi32(int __i) /// A 16-bit integer value used to initialize each vector element of the /// result. /// \returns An initialized 64-bit integer vector of [4 x i16]. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_set1_pi16(short __w) { return _mm_set_pi16(__w, __w, __w, __w); @@ -1409,7 +1459,7 @@ _mm_set1_pi16(short __w) /// An 8-bit integer value used to initialize each vector element of the /// result. /// \returns An initialized 64-bit integer vector of [8 x i8]. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_set1_pi8(char __b) { return _mm_set_pi8(__b, __b, __b, __b, __b, __b, __b, __b); @@ -1430,7 +1480,7 @@ _mm_set1_pi8(char __b) /// A 32-bit integer value used to initialize the upper 32 bits of the /// result. /// \returns An initialized 64-bit integer vector. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_setr_pi32(int __i0, int __i1) { return _mm_set_pi32(__i1, __i0); @@ -1453,7 +1503,7 @@ _mm_setr_pi32(int __i0, int __i1) /// \param __w3 /// A 16-bit integer value used to initialize bits [63:48] of the result. /// \returns An initialized 64-bit integer vector. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_setr_pi16(short __w0, short __w1, short __w2, short __w3) { return _mm_set_pi16(__w3, __w2, __w1, __w0); @@ -1484,14 +1534,16 @@ _mm_setr_pi16(short __w0, short __w1, short __w2, short __w3) /// \param __b7 /// An 8-bit integer value used to initialize bits [63:56] of the result. /// \returns An initialized 64-bit integer vector. -static __inline__ __m64 __DEFAULT_FN_ATTRS +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_setr_pi8(char __b0, char __b1, char __b2, char __b3, char __b4, char __b5, char __b6, char __b7) { return _mm_set_pi8(__b7, __b6, __b5, __b4, __b3, __b2, __b1, __b0); } -#undef __DEFAULT_FN_ATTRS +#undef __anyext128 +#undef __trunc64 +#undef __DEFAULT_FN_ATTRS_SSE2 /* Aliases for compatibility. */ #define _m_empty _mm_empty diff --git a/clang/lib/Headers/prfchwintrin.h b/clang/lib/Headers/prfchwintrin.h index 8a13784543c5f..eaea5f3cf8feb 100644 --- a/clang/lib/Headers/prfchwintrin.h +++ b/clang/lib/Headers/prfchwintrin.h @@ -8,7 +8,7 @@ */ #if !defined(__X86INTRIN_H) && !defined(_MM3DNOW_H_INCLUDED) -#error "Never use directly; include or instead." +#error "Never use directly; include instead." #endif #ifndef __PRFCHWINTRIN_H diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h index 40ac6dcac2ab8..4724155b0dc79 100644 --- a/clang/lib/Headers/ptrauth.h +++ b/clang/lib/Headers/ptrauth.h @@ -58,6 +58,21 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; /* Authenticating a pointer that was not signed with the given key and extra-data value will (likely) fail by trapping. */ +/* The null function pointer is always the all-zero bit pattern. + Signing an all-zero bit pattern will embed a (likely) non-zero + signature in the result, and so the result will not seem to be + a null function pointer. Authenticating this value will yield + a null function pointer back. However, authenticating an + all-zero bit pattern will probably fail, because the + authentication will expect a (likely) non-zero signature to + embedded in the value. + + Because of this, if a pointer may validly be null, you should + check for null before attempting to authenticate it with one + of these intrinsics. This is not necessary when using the + __ptrauth qualifier; the compiler will perform this check + automatically. */ + #if __has_feature(ptrauth_intrinsics) /* Strip the signature from a value without authenticating it. @@ -187,6 +202,23 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; #define ptrauth_string_discriminator(__string) \ __builtin_ptrauth_string_discriminator(__string) +/* Compute a constant discriminator from the given type. + + The result can be used as the second argument to + ptrauth_blend_discriminator or the third argument to the + __ptrauth qualifier. It has type size_t. + + If the type is a C++ member function pointer type, the result is + the discriminator used to signed member function pointers of that + type. If the type is a function, function pointer, or function + reference type, the result is the discriminator used to sign + functions of that type. It is ill-formed to use this macro with any + other type. + + A call to this function is an integer constant expression. */ +#define ptrauth_type_discriminator(__type) \ + __builtin_ptrauth_type_discriminator(__type) + /* Compute a signature for the given pair of pointer-sized values. The order of the arguments is significant. @@ -274,6 +306,8 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; ((ptrauth_extra_data_t)0); \ }) +#define ptrauth_type_discriminator(__type) ((ptrauth_extra_data_t)0) + #define ptrauth_sign_generic_data(__value, __data) \ ({ \ (void)__value; \ diff --git a/clang/lib/Headers/stdarg.h b/clang/lib/Headers/stdarg.h index 8292ab907becf..6203d7a600a23 100644 --- a/clang/lib/Headers/stdarg.h +++ b/clang/lib/Headers/stdarg.h @@ -20,19 +20,18 @@ * modules. */ #if defined(__MVS__) && __has_include_next() -#include <__stdarg_header_macro.h> #undef __need___va_list #undef __need_va_list #undef __need_va_arg #undef __need___va_copy #undef __need_va_copy +#include <__stdarg_header_macro.h> #include_next #else #if !defined(__need___va_list) && !defined(__need_va_list) && \ !defined(__need_va_arg) && !defined(__need___va_copy) && \ !defined(__need_va_copy) -#include <__stdarg_header_macro.h> #define __need___va_list #define __need_va_list #define __need_va_arg @@ -45,6 +44,7 @@ !defined(__STRICT_ANSI__) #define __need_va_copy #endif +#include <__stdarg_header_macro.h> #endif #ifdef __need___va_list diff --git a/clang/lib/Headers/stdatomic.h b/clang/lib/Headers/stdatomic.h index 2027055f38796..1991351f9e9ef 100644 --- a/clang/lib/Headers/stdatomic.h +++ b/clang/lib/Headers/stdatomic.h @@ -172,7 +172,11 @@ typedef _Atomic(uintmax_t) atomic_uintmax_t; typedef struct atomic_flag { atomic_bool _Value; } atomic_flag; +#ifdef __cplusplus +#define ATOMIC_FLAG_INIT {false} +#else #define ATOMIC_FLAG_INIT { 0 } +#endif /* These should be provided by the libc implementation. */ #ifdef __cplusplus diff --git a/clang/lib/Headers/stddef.h b/clang/lib/Headers/stddef.h index 8985c526e8fc5..99b275aebf5aa 100644 --- a/clang/lib/Headers/stddef.h +++ b/clang/lib/Headers/stddef.h @@ -20,7 +20,6 @@ * modules. */ #if defined(__MVS__) && __has_include_next() -#include <__stddef_header_macro.h> #undef __need_ptrdiff_t #undef __need_size_t #undef __need_rsize_t @@ -31,6 +30,7 @@ #undef __need_max_align_t #undef __need_offsetof #undef __need_wint_t +#include <__stddef_header_macro.h> #include_next #else @@ -40,7 +40,6 @@ !defined(__need_NULL) && !defined(__need_nullptr_t) && \ !defined(__need_unreachable) && !defined(__need_max_align_t) && \ !defined(__need_offsetof) && !defined(__need_wint_t) -#include <__stddef_header_macro.h> #define __need_ptrdiff_t #define __need_size_t /* ISO9899:2011 7.20 (C11 Annex K): Define rsize_t if __STDC_WANT_LIB_EXT1__ is @@ -49,7 +48,24 @@ #define __need_rsize_t #endif #define __need_wchar_t +#if !defined(__STDDEF_H) || __has_feature(modules) +/* + * __stddef_null.h is special when building without modules: if __need_NULL is + * set, then it will unconditionally redefine NULL. To avoid stepping on client + * definitions of NULL, __need_NULL should only be set the first time this + * header is included, that is when __STDDEF_H is not defined. However, when + * building with modules, this header is a textual header and needs to + * unconditionally include __stdef_null.h to support multiple submodules + * exporting _Builtin_stddef.null. Take module SM with submodules A and B, whose + * headers both include stddef.h When SM.A builds, __STDDEF_H will be defined. + * When SM.B builds, the definition from SM.A will leak when building without + * local submodule visibility. stddef.h wouldn't include __stddef_null.h, and + * SM.B wouldn't import _Builtin_stddef.null, and SM.B's `export *` wouldn't + * export NULL as expected. When building with modules, always include + * __stddef_null.h so that everything works as expected. + */ #define __need_NULL +#endif #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) || \ defined(__cplusplus) #define __need_nullptr_t @@ -65,6 +81,7 @@ /* wint_t is provided by and not . It's here * for compatibility, but must be explicitly requested. Therefore * __need_wint_t is intentionally not defined here. */ +#include <__stddef_header_macro.h> #endif #if defined(__need_ptrdiff_t) diff --git a/clang/lib/Headers/tmmintrin.h b/clang/lib/Headers/tmmintrin.h index bf8327b692d1c..bd832ce8dddfd 100644 --- a/clang/lib/Headers/tmmintrin.h +++ b/clang/lib/Headers/tmmintrin.h @@ -19,11 +19,13 @@ /* Define the default attributes for the functions in this file. */ #define __DEFAULT_FN_ATTRS \ __attribute__((__always_inline__, __nodebug__, \ - __target__("ssse3,no-evex512"), __min_vector_width__(64))) -#define __DEFAULT_FN_ATTRS_MMX \ - __attribute__((__always_inline__, __nodebug__, \ - __target__("mmx,ssse3,no-evex512"), \ - __min_vector_width__(64))) + __target__("ssse3,no-evex512"), __min_vector_width__(128))) + +#define __trunc64(x) \ + (__m64) __builtin_shufflevector((__v2di)(x), __extension__(__v2di){}, 0) +#define __anyext128(x) \ + (__m128i) __builtin_shufflevector((__v2si)(x), __extension__(__v2si){}, 0, \ + 1, -1, -1) /// Computes the absolute value of each of the packed 8-bit signed /// integers in the source operand and stores the 8-bit unsigned integer @@ -37,10 +39,10 @@ /// A 64-bit vector of [8 x i8]. /// \returns A 64-bit integer vector containing the absolute values of the /// elements in the operand. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_abs_pi8(__m64 __a) { - return (__m64)__builtin_ia32_pabsb((__v8qi)__a); + return (__m64)__builtin_elementwise_abs((__v8qs)__a); } /// Computes the absolute value of each of the packed 8-bit signed @@ -73,10 +75,10 @@ _mm_abs_epi8(__m128i __a) /// A 64-bit vector of [4 x i16]. /// \returns A 64-bit integer vector containing the absolute values of the /// elements in the operand. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_abs_pi16(__m64 __a) { - return (__m64)__builtin_ia32_pabsw((__v4hi)__a); + return (__m64)__builtin_elementwise_abs((__v4hi)__a); } /// Computes the absolute value of each of the packed 16-bit signed @@ -109,10 +111,10 @@ _mm_abs_epi16(__m128i __a) /// A 64-bit vector of [2 x i32]. /// \returns A 64-bit integer vector containing the absolute values of the /// elements in the operand. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_abs_pi32(__m64 __a) { - return (__m64)__builtin_ia32_pabsd((__v2si)__a); + return (__m64)__builtin_elementwise_abs((__v2si)__a); } /// Computes the absolute value of each of the packed 32-bit signed @@ -177,7 +179,10 @@ _mm_abs_epi32(__m128i __a) /// \returns A 64-bit integer vector containing the concatenated right-shifted /// value. #define _mm_alignr_pi8(a, b, n) \ - ((__m64)__builtin_ia32_palignr((__v8qi)(__m64)(a), (__v8qi)(__m64)(b), (n))) + ((__m64)__builtin_shufflevector( \ + __builtin_ia32_psrldqi128_byteshift( \ + __builtin_shufflevector((__v1di)(a), (__v1di)(b), 1, 0), \ + (n)), __extension__ (__v2di){}, 0)) /// Horizontally adds the adjacent pairs of values contained in 2 packed /// 128-bit vectors of [8 x i16]. @@ -242,10 +247,11 @@ _mm_hadd_epi32(__m128i __a, __m128i __b) /// destination. /// \returns A 64-bit vector of [4 x i16] containing the horizontal sums of both /// operands. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_hadd_pi16(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_phaddw((__v4hi)__a, (__v4hi)__b); + return __trunc64(__builtin_ia32_phaddw128( + (__v8hi)__builtin_shufflevector(__a, __b, 0, 1), (__v8hi){})); } /// Horizontally adds the adjacent pairs of values contained in 2 packed @@ -265,10 +271,11 @@ _mm_hadd_pi16(__m64 __a, __m64 __b) /// destination. /// \returns A 64-bit vector of [2 x i32] containing the horizontal sums of both /// operands. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_hadd_pi32(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_phaddd((__v2si)__a, (__v2si)__b); + return __trunc64(__builtin_ia32_phaddd128( + (__v4si)__builtin_shufflevector(__a, __b, 0, 1), (__v4si){})); } /// Horizontally adds, with saturation, the adjacent pairs of values contained @@ -317,10 +324,11 @@ _mm_hadds_epi16(__m128i __a, __m128i __b) /// destination. /// \returns A 64-bit vector of [4 x i16] containing the horizontal saturated /// sums of both operands. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_hadds_pi16(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_phaddsw((__v4hi)__a, (__v4hi)__b); + return __trunc64(__builtin_ia32_phaddsw128( + (__v8hi)__builtin_shufflevector(__a, __b, 0, 1), (__v8hi){})); } /// Horizontally subtracts the adjacent pairs of values contained in 2 @@ -386,10 +394,11 @@ _mm_hsub_epi32(__m128i __a, __m128i __b) /// the destination. /// \returns A 64-bit vector of [4 x i16] containing the horizontal differences /// of both operands. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_hsub_pi16(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_phsubw((__v4hi)__a, (__v4hi)__b); + return __trunc64(__builtin_ia32_phsubw128( + (__v8hi)__builtin_shufflevector(__a, __b, 0, 1), (__v8hi){})); } /// Horizontally subtracts the adjacent pairs of values contained in 2 @@ -409,10 +418,11 @@ _mm_hsub_pi16(__m64 __a, __m64 __b) /// the destination. /// \returns A 64-bit vector of [2 x i32] containing the horizontal differences /// of both operands. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_hsub_pi32(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_phsubd((__v2si)__a, (__v2si)__b); + return __trunc64(__builtin_ia32_phsubd128( + (__v4si)__builtin_shufflevector(__a, __b, 0, 1), (__v4si){})); } /// Horizontally subtracts, with saturation, the adjacent pairs of values @@ -461,10 +471,11 @@ _mm_hsubs_epi16(__m128i __a, __m128i __b) /// the destination. /// \returns A 64-bit vector of [4 x i16] containing the horizontal saturated /// differences of both operands. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_hsubs_pi16(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_phsubsw((__v4hi)__a, (__v4hi)__b); + return __trunc64(__builtin_ia32_phsubsw128( + (__v8hi)__builtin_shufflevector(__a, __b, 0, 1), (__v8hi){})); } /// Multiplies corresponding pairs of packed 8-bit unsigned integer @@ -525,10 +536,11 @@ _mm_maddubs_epi16(__m128i __a, __m128i __b) /// \a R1 := (\a __a2 * \a __b2) + (\a __a3 * \a __b3) \n /// \a R2 := (\a __a4 * \a __b4) + (\a __a5 * \a __b5) \n /// \a R3 := (\a __a6 * \a __b6) + (\a __a7 * \a __b7) -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_maddubs_pi16(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_pmaddubsw((__v8qi)__a, (__v8qi)__b); + return __trunc64(__builtin_ia32_pmaddubsw128((__v16qi)__anyext128(__a), + (__v16qi)__anyext128(__b))); } /// Multiplies packed 16-bit signed integer values, truncates the 32-bit @@ -565,10 +577,11 @@ _mm_mulhrs_epi16(__m128i __a, __m128i __b) /// A 64-bit vector of [4 x i16] containing one of the source operands. /// \returns A 64-bit vector of [4 x i16] containing the rounded and scaled /// products of both operands. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_mulhrs_pi16(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_pmulhrsw((__v4hi)__a, (__v4hi)__b); + return __trunc64(__builtin_ia32_pmulhrsw128((__v8hi)__anyext128(__a), + (__v8hi)__anyext128(__b))); } /// Copies the 8-bit integers from a 128-bit integer vector to the @@ -614,12 +627,15 @@ _mm_shuffle_epi8(__m128i __a, __m128i __b) /// 1: Clear the corresponding byte in the destination. \n /// 0: Copy the selected source byte to the corresponding byte in the /// destination. \n -/// Bits [3:0] select the source byte to be copied. +/// Bits [2:0] select the source byte to be copied. /// \returns A 64-bit integer vector containing the copied or cleared values. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_shuffle_pi8(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_pshufb((__v8qi)__a, (__v8qi)__b); + return __trunc64(__builtin_ia32_pshufb128( + (__v16qi)__builtin_shufflevector( + (__v2si)(__a), __extension__ (__v2si){}, 0, 1, 0, 1), + (__v16qi)__anyext128(__b))); } /// For each 8-bit integer in the first source operand, perform one of @@ -720,10 +736,11 @@ _mm_sign_epi32(__m128i __a, __m128i __b) /// A 64-bit integer vector containing control bytes corresponding to /// positions in the destination. /// \returns A 64-bit integer vector containing the resultant values. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_sign_pi8(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_psignb((__v8qi)__a, (__v8qi)__b); + return __trunc64(__builtin_ia32_psignb128((__v16qi)__anyext128(__a), + (__v16qi)__anyext128(__b))); } /// For each 16-bit integer in the first source operand, perform one of @@ -746,10 +763,11 @@ _mm_sign_pi8(__m64 __a, __m64 __b) /// A 64-bit integer vector containing control words corresponding to /// positions in the destination. /// \returns A 64-bit integer vector containing the resultant values. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_sign_pi16(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_psignw((__v4hi)__a, (__v4hi)__b); + return __trunc64(__builtin_ia32_psignw128((__v8hi)__anyext128(__a), + (__v8hi)__anyext128(__b))); } /// For each 32-bit integer in the first source operand, perform one of @@ -772,13 +790,15 @@ _mm_sign_pi16(__m64 __a, __m64 __b) /// A 64-bit integer vector containing two control doublewords corresponding /// to positions in the destination. /// \returns A 64-bit integer vector containing the resultant values. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_sign_pi32(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_psignd((__v2si)__a, (__v2si)__b); + return __trunc64(__builtin_ia32_psignd128((__v4si)__anyext128(__a), + (__v4si)__anyext128(__b))); } +#undef __anyext128 +#undef __trunc64 #undef __DEFAULT_FN_ATTRS -#undef __DEFAULT_FN_ATTRS_MMX #endif /* __TMMINTRIN_H */ diff --git a/clang/lib/Headers/xmmintrin.h b/clang/lib/Headers/xmmintrin.h index 1ef89de9c9f56..5b9e90e8f061c 100644 --- a/clang/lib/Headers/xmmintrin.h +++ b/clang/lib/Headers/xmmintrin.h @@ -35,9 +35,21 @@ typedef unsigned int __v4su __attribute__((__vector_size__(16))); #define __DEFAULT_FN_ATTRS \ __attribute__((__always_inline__, __nodebug__, __target__("sse,no-evex512"), \ __min_vector_width__(128))) -#define __DEFAULT_FN_ATTRS_MMX \ +#define __DEFAULT_FN_ATTRS_SSE2 \ __attribute__((__always_inline__, __nodebug__, \ - __target__("mmx,sse,no-evex512"), __min_vector_width__(64))) + __target__("sse2,no-evex512"), __min_vector_width__(128))) + +#define __trunc64(x) \ + (__m64) __builtin_shufflevector((__v2di)(x), __extension__(__v2di){}, 0) +#define __zext128(x) \ + (__m128i) __builtin_shufflevector((__v2si)(x), __extension__(__v2si){}, 0, \ + 1, 2, 3) +#define __anyext128(x) \ + (__m128i) __builtin_shufflevector((__v2si)(x), __extension__(__v2si){}, 0, \ + 1, -1, -1) +#define __zeroupper64(x) \ + (__m128i) __builtin_shufflevector((__v4si)(x), __extension__(__v4si){}, 0, \ + 1, 4, 5) /// Adds the 32-bit float values in the low-order bits of the operands. /// @@ -1448,10 +1460,10 @@ _mm_cvtss_si64(__m128 __a) /// \param __a /// A 128-bit vector of [4 x float]. /// \returns A 64-bit integer vector containing the converted values. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_cvtps_pi32(__m128 __a) { - return (__m64)__builtin_ia32_cvtps2pi((__v4sf)__a); + return __trunc64(__builtin_ia32_cvtps2dq((__v4sf)__zeroupper64(__a))); } /// Converts two low-order float values in a 128-bit vector of @@ -1468,7 +1480,7 @@ _mm_cvtps_pi32(__m128 __a) /// \param __a /// A 128-bit vector of [4 x float]. /// \returns A 64-bit integer vector containing the converted values. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_cvt_ps2pi(__m128 __a) { return _mm_cvtps_pi32(__a); @@ -1558,10 +1570,10 @@ _mm_cvttss_si64(__m128 __a) /// \param __a /// A 128-bit vector of [4 x float]. /// \returns A 64-bit integer vector containing the converted values. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_cvttps_pi32(__m128 __a) { - return (__m64)__builtin_ia32_cvttps2pi((__v4sf)__a); + return __trunc64(__builtin_ia32_cvttps2dq((__v4sf)__zeroupper64(__a))); } /// Converts the lower (first) two elements of a 128-bit vector of [4 x float] @@ -1579,7 +1591,7 @@ _mm_cvttps_pi32(__m128 __a) /// \param __a /// A 128-bit vector of [4 x float]. /// \returns A 64-bit integer vector containing the converted values. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_cvtt_ps2pi(__m128 __a) { return _mm_cvttps_pi32(__a); @@ -1674,10 +1686,13 @@ _mm_cvtsi64_ss(__m128 __a, long long __b) /// \returns A 128-bit vector of [4 x float] whose lower 64 bits contain the /// converted value of the second operand. The upper 64 bits are copied from /// the upper 64 bits of the first operand. -static __inline__ __m128 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m128 __DEFAULT_FN_ATTRS_SSE2 _mm_cvtpi32_ps(__m128 __a, __m64 __b) { - return __builtin_ia32_cvtpi2ps((__v4sf)__a, (__v2si)__b); + return (__m128)__builtin_shufflevector( + (__v4sf)__a, + __builtin_convertvector((__v4si)__zext128(__b), __v4sf), + 4, 5, 2, 3); } /// Converts two elements of a 64-bit vector of [2 x i32] into two @@ -1697,7 +1712,7 @@ _mm_cvtpi32_ps(__m128 __a, __m64 __b) /// \returns A 128-bit vector of [4 x float] whose lower 64 bits contain the /// converted value from the second operand. The upper 64 bits are copied /// from the upper 64 bits of the first operand. -static __inline__ __m128 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m128 __DEFAULT_FN_ATTRS_SSE2 _mm_cvt_pi2ps(__m128 __a, __m64 __b) { return _mm_cvtpi32_ps(__a, __b); @@ -2231,10 +2246,10 @@ _mm_storer_ps(float *__p, __m128 __a) /// A pointer to an aligned memory location used to store the register value. /// \param __a /// A 64-bit integer containing the value to be stored. -static __inline__ void __DEFAULT_FN_ATTRS_MMX +static __inline__ void __DEFAULT_FN_ATTRS _mm_stream_pi(void *__p, __m64 __a) { - __builtin_ia32_movntq((__m64 *)__p, __a); + __builtin_nontemporal_store(__a, (__m64 *)__p); } /// Moves packed float values from a 128-bit vector of [4 x float] to a @@ -2296,7 +2311,7 @@ void _mm_sfence(void); /// 3: Bits [63:48] are copied to the destination. /// \returns A 16-bit integer containing the extracted 16 bits of packed data. #define _mm_extract_pi16(a, n) \ - ((int)__builtin_ia32_vec_ext_v4hi((__v4hi)a, (int)n)) + ((int)(unsigned short)__builtin_ia32_vec_ext_v4hi((__v4hi)a, (int)n)) /// Copies data from the 64-bit vector of [4 x i16] to the destination, /// and inserts the lower 16-bits of an integer operand at the 16-bit offset @@ -2342,10 +2357,10 @@ void _mm_sfence(void); /// \param __b /// A 64-bit integer vector containing one of the source operands. /// \returns A 64-bit integer vector containing the comparison results. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_max_pi16(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_pmaxsw((__v4hi)__a, (__v4hi)__b); + return (__m64)__builtin_elementwise_max((__v4hi)__a, (__v4hi)__b); } /// Compares each of the corresponding packed 8-bit unsigned integer @@ -2361,10 +2376,10 @@ _mm_max_pi16(__m64 __a, __m64 __b) /// \param __b /// A 64-bit integer vector containing one of the source operands. /// \returns A 64-bit integer vector containing the comparison results. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_max_pu8(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_pmaxub((__v8qi)__a, (__v8qi)__b); + return (__m64)__builtin_elementwise_max((__v8qu)__a, (__v8qu)__b); } /// Compares each of the corresponding packed 16-bit integer values of @@ -2380,10 +2395,10 @@ _mm_max_pu8(__m64 __a, __m64 __b) /// \param __b /// A 64-bit integer vector containing one of the source operands. /// \returns A 64-bit integer vector containing the comparison results. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_min_pi16(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_pminsw((__v4hi)__a, (__v4hi)__b); + return (__m64)__builtin_elementwise_min((__v4hi)__a, (__v4hi)__b); } /// Compares each of the corresponding packed 8-bit unsigned integer @@ -2399,10 +2414,10 @@ _mm_min_pi16(__m64 __a, __m64 __b) /// \param __b /// A 64-bit integer vector containing one of the source operands. /// \returns A 64-bit integer vector containing the comparison results. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_min_pu8(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_pminub((__v8qi)__a, (__v8qi)__b); + return (__m64)__builtin_elementwise_min((__v8qu)__a, (__v8qu)__b); } /// Takes the most significant bit from each 8-bit element in a 64-bit @@ -2417,10 +2432,10 @@ _mm_min_pu8(__m64 __a, __m64 __b) /// A 64-bit integer vector containing the values with bits to be extracted. /// \returns The most significant bit from each 8-bit element in \a __a, /// written to bits [7:0]. -static __inline__ int __DEFAULT_FN_ATTRS_MMX +static __inline__ int __DEFAULT_FN_ATTRS_SSE2 _mm_movemask_pi8(__m64 __a) { - return __builtin_ia32_pmovmskb((__v8qi)__a); + return __builtin_ia32_pmovmskb128((__v16qi)__zext128(__a)); } /// Multiplies packed 16-bit unsigned integer values and writes the @@ -2436,10 +2451,11 @@ _mm_movemask_pi8(__m64 __a) /// \param __b /// A 64-bit integer vector containing one of the source operands. /// \returns A 64-bit integer vector containing the products of both operands. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_mulhi_pu16(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_pmulhuw((__v4hi)__a, (__v4hi)__b); + return __trunc64(__builtin_ia32_pmulhuw128((__v8hi)__anyext128(__a), + (__v8hi)__anyext128(__b))); } /// Shuffles the 4 16-bit integers from a 64-bit integer vector to the @@ -2476,8 +2492,10 @@ _mm_mulhi_pu16(__m64 __a, __m64 __b) /// _MM_SHUFFLE(b6, b4, b2, b0) can create an 8-bit mask of the form /// [b6, b4, b2, b0]. /// \returns A 64-bit integer vector containing the shuffled values. -#define _mm_shuffle_pi16(a, n) \ - ((__m64)__builtin_ia32_pshufw((__v4hi)(__m64)(a), (n))) +#define _mm_shuffle_pi16(a, n) \ + ((__m64)__builtin_shufflevector((__v4hi)(__m64)(a), __extension__(__v4hi){}, \ + (n) & 0x3, ((n) >> 2) & 0x3, \ + ((n) >> 4) & 0x3, ((n) >> 6) & 0x3)) /// Conditionally copies the values from each 8-bit element in the first /// 64-bit integer vector operand to the specified memory location, as @@ -2502,10 +2520,25 @@ _mm_mulhi_pu16(__m64 __a, __m64 __b) /// A pointer to a 64-bit memory location that will receive the conditionally /// copied integer values. The address of the memory location does not have /// to be aligned. -static __inline__ void __DEFAULT_FN_ATTRS_MMX +static __inline__ void __DEFAULT_FN_ATTRS_SSE2 _mm_maskmove_si64(__m64 __d, __m64 __n, char *__p) { - __builtin_ia32_maskmovq((__v8qi)__d, (__v8qi)__n, __p); + // This is complex, because we need to support the case where __p is pointing + // within the last 15 to 8 bytes of a page. In that case, using a 128-bit + // write might cause a trap where a 64-bit maskmovq would not. (Memory + // locations not selected by the mask bits might still cause traps.) + __m128i __d128 = __anyext128(__d); + __m128i __n128 = __zext128(__n); + if (((__SIZE_TYPE__)__p & 0xfff) >= 4096-15 && + ((__SIZE_TYPE__)__p & 0xfff) <= 4096-8) { + // If there's a risk of spurious trap due to a 128-bit write, back up the + // pointer by 8 bytes and shift values in registers to match. + __p -= 8; + __d128 = __builtin_ia32_pslldqi128_byteshift((__v2di)__d128, 8); + __n128 = __builtin_ia32_pslldqi128_byteshift((__v2di)__n128, 8); + } + + __builtin_ia32_maskmovdqu((__v16qi)__d128, (__v16qi)__n128, __p); } /// Computes the rounded averages of the packed unsigned 8-bit integer @@ -2521,10 +2554,11 @@ _mm_maskmove_si64(__m64 __d, __m64 __n, char *__p) /// \param __b /// A 64-bit integer vector containing one of the source operands. /// \returns A 64-bit integer vector containing the averages of both operands. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_avg_pu8(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_pavgb((__v8qi)__a, (__v8qi)__b); + return __trunc64(__builtin_ia32_pavgb128((__v16qi)__anyext128(__a), + (__v16qi)__anyext128(__b))); } /// Computes the rounded averages of the packed unsigned 16-bit integer @@ -2540,10 +2574,11 @@ _mm_avg_pu8(__m64 __a, __m64 __b) /// \param __b /// A 64-bit integer vector containing one of the source operands. /// \returns A 64-bit integer vector containing the averages of both operands. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_avg_pu16(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_pavgw((__v4hi)__a, (__v4hi)__b); + return __trunc64(__builtin_ia32_pavgw128((__v8hi)__anyext128(__a), + (__v8hi)__anyext128(__b))); } /// Subtracts the corresponding 8-bit unsigned integer values of the two @@ -2562,10 +2597,11 @@ _mm_avg_pu16(__m64 __a, __m64 __b) /// \returns A 64-bit integer vector whose lower 16 bits contain the sums of the /// sets of absolute differences between both operands. The upper bits are /// cleared. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_sad_pu8(__m64 __a, __m64 __b) { - return (__m64)__builtin_ia32_psadbw((__v8qi)__a, (__v8qi)__b); + return __trunc64(__builtin_ia32_psadbw128((__v16qi)__zext128(__a), + (__v16qi)__zext128(__b))); } #if defined(__cplusplus) @@ -2846,22 +2882,10 @@ _mm_movelh_ps(__m128 __a, __m128 __b) /// from the corresponding elements in this operand. /// \returns A 128-bit vector of [4 x float] containing the copied and converted /// values from the operand. -static __inline__ __m128 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m128 __DEFAULT_FN_ATTRS_SSE2 _mm_cvtpi16_ps(__m64 __a) { - __m64 __b, __c; - __m128 __r; - - __b = _mm_setzero_si64(); - __b = _mm_cmpgt_pi16(__b, __a); - __c = _mm_unpackhi_pi16(__a, __b); - __r = _mm_setzero_ps(); - __r = _mm_cvtpi32_ps(__r, __c); - __r = _mm_movelh_ps(__r, __r); - __c = _mm_unpacklo_pi16(__a, __b); - __r = _mm_cvtpi32_ps(__r, __c); - - return __r; + return __builtin_convertvector((__v4hi)__a, __v4sf); } /// Converts a 64-bit vector of 16-bit unsigned integer values into a @@ -2876,21 +2900,10 @@ _mm_cvtpi16_ps(__m64 __a) /// destination are copied from the corresponding elements in this operand. /// \returns A 128-bit vector of [4 x float] containing the copied and converted /// values from the operand. -static __inline__ __m128 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m128 __DEFAULT_FN_ATTRS_SSE2 _mm_cvtpu16_ps(__m64 __a) { - __m64 __b, __c; - __m128 __r; - - __b = _mm_setzero_si64(); - __c = _mm_unpackhi_pi16(__a, __b); - __r = _mm_setzero_ps(); - __r = _mm_cvtpi32_ps(__r, __c); - __r = _mm_movelh_ps(__r, __r); - __c = _mm_unpacklo_pi16(__a, __b); - __r = _mm_cvtpi32_ps(__r, __c); - - return __r; + return __builtin_convertvector((__v4hu)__a, __v4sf); } /// Converts the lower four 8-bit values from a 64-bit vector of [8 x i8] @@ -2905,16 +2918,12 @@ _mm_cvtpu16_ps(__m64 __a) /// from the corresponding lower 4 elements in this operand. /// \returns A 128-bit vector of [4 x float] containing the copied and converted /// values from the operand. -static __inline__ __m128 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m128 __DEFAULT_FN_ATTRS_SSE2 _mm_cvtpi8_ps(__m64 __a) { - __m64 __b; - - __b = _mm_setzero_si64(); - __b = _mm_cmpgt_pi8(__b, __a); - __b = _mm_unpacklo_pi8(__a, __b); - - return _mm_cvtpi16_ps(__b); + return __builtin_convertvector( + __builtin_shufflevector((__v8qs)__a, __extension__ (__v8qs){}, + 0, 1, 2, 3), __v4sf); } /// Converts the lower four unsigned 8-bit integer values from a 64-bit @@ -2930,15 +2939,12 @@ _mm_cvtpi8_ps(__m64 __a) /// operand. /// \returns A 128-bit vector of [4 x float] containing the copied and converted /// values from the source operand. -static __inline__ __m128 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m128 __DEFAULT_FN_ATTRS_SSE2 _mm_cvtpu8_ps(__m64 __a) { - __m64 __b; - - __b = _mm_setzero_si64(); - __b = _mm_unpacklo_pi8(__a, __b); - - return _mm_cvtpi16_ps(__b); + return __builtin_convertvector( + __builtin_shufflevector((__v8qu)__a, __extension__ (__v8qu){}, + 0, 1, 2, 3), __v4sf); } /// Converts the two 32-bit signed integer values from each 64-bit vector @@ -2957,16 +2963,12 @@ _mm_cvtpu8_ps(__m64 __a) /// \returns A 128-bit vector of [4 x float] whose lower 64 bits contain the /// copied and converted values from the first operand. The upper 64 bits /// contain the copied and converted values from the second operand. -static __inline__ __m128 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m128 __DEFAULT_FN_ATTRS_SSE2 _mm_cvtpi32x2_ps(__m64 __a, __m64 __b) { - __m128 __c; - - __c = _mm_setzero_ps(); - __c = _mm_cvtpi32_ps(__c, __b); - __c = _mm_movelh_ps(__c, __c); - - return _mm_cvtpi32_ps(__c, __a); + return __builtin_convertvector( + __builtin_shufflevector((__v2si)__a, (__v2si)__b, + 0, 1, 2, 3), __v4sf); } /// Converts each single-precision floating-point element of a 128-bit @@ -2986,16 +2988,11 @@ _mm_cvtpi32x2_ps(__m64 __a, __m64 __b) /// A 128-bit floating-point vector of [4 x float]. /// \returns A 64-bit integer vector of [4 x i16] containing the converted /// values. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_cvtps_pi16(__m128 __a) { - __m64 __b, __c; - - __b = _mm_cvtps_pi32(__a); - __a = _mm_movehl_ps(__a, __a); - __c = _mm_cvtps_pi32(__a); - - return _mm_packs_pi32(__b, __c); + return __trunc64(__builtin_ia32_packssdw128( + (__v4si)__builtin_ia32_cvtps2dq((__v4sf)__a), (__v4si)_mm_setzero_ps())); } /// Converts each single-precision floating-point element of a 128-bit @@ -3016,7 +3013,7 @@ _mm_cvtps_pi16(__m128 __a) /// 128-bit floating-point vector of [4 x float]. /// \returns A 64-bit integer vector of [8 x i8]. The lower 32 bits contain the /// converted values and the uppper 32 bits are set to zero. -static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX +static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2 _mm_cvtps_pi8(__m128 __a) { __m64 __b, __c; @@ -3196,8 +3193,12 @@ do { \ #define _m_psadbw _mm_sad_pu8 #define _m_ _mm_ +#undef __trunc64 +#undef __zext128 +#undef __anyext128 +#undef __zeroupper64 #undef __DEFAULT_FN_ATTRS -#undef __DEFAULT_FN_ATTRS_MMX +#undef __DEFAULT_FN_ATTRS_SSE2 /* Ugly hack for backwards-compatibility (compatible with gcc) */ #if defined(__SSE2__) && !__building_module(_Builtin_intrinsics) diff --git a/clang/lib/InstallAPI/DirectoryScanner.cpp b/clang/lib/InstallAPI/DirectoryScanner.cpp index 8984758e7b446..03a8208c7364e 100644 --- a/clang/lib/InstallAPI/DirectoryScanner.cpp +++ b/clang/lib/InstallAPI/DirectoryScanner.cpp @@ -130,7 +130,8 @@ Error DirectoryScanner::scanHeaders(StringRef Path, Library &Lib, if (ParentPath.empty()) ParentPath = Path; for (const StringRef Dir : SubDirectories) - return scanHeaders(Dir, Lib, Type, BasePath, ParentPath); + if (Error Err = scanHeaders(Dir, Lib, Type, BasePath, ParentPath)) + return Err; return Error::success(); } diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index b4882ab5d2236..7209a33272ef2 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -26,7 +26,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/CodeGen/CodeGenAction.h" #include "clang/CodeGen/ModuleBuilder.h" -#include "clang/CodeGen/ObjectFilePCHContainerOperations.h" +#include "clang/CodeGen/ObjectFilePCHContainerWriter.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Driver/Job.h" @@ -38,6 +38,7 @@ #include "clang/Interpreter/Value.h" #include "clang/Lex/PreprocessorOptions.h" #include "clang/Sema/Lookup.h" +#include "clang/Serialization/ObjectFilePCHContainerReader.h" #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/LLJIT.h" #include "llvm/IR/Module.h" diff --git a/clang/lib/Interpreter/InterpreterUtils.h b/clang/lib/Interpreter/InterpreterUtils.h index 8df158c17d491..c7b405b486d93 100644 --- a/clang/lib/Interpreter/InterpreterUtils.h +++ b/clang/lib/Interpreter/InterpreterUtils.h @@ -18,7 +18,6 @@ #include "clang/AST/TypeVisitor.h" #include "clang/Basic/TargetInfo.h" #include "clang/CodeGen/ModuleBuilder.h" -#include "clang/CodeGen/ObjectFilePCHContainerOperations.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Driver/Job.h" diff --git a/clang/lib/Lex/DependencyDirectivesScanner.cpp b/clang/lib/Lex/DependencyDirectivesScanner.cpp index 57652be8244b4..088d1cc96e3a2 100644 --- a/clang/lib/Lex/DependencyDirectivesScanner.cpp +++ b/clang/lib/Lex/DependencyDirectivesScanner.cpp @@ -88,8 +88,8 @@ struct Scanner { [[nodiscard]] dependency_directives_scan::Token & lexToken(const char *&First, const char *const End); - dependency_directives_scan::Token &lexIncludeFilename(const char *&First, - const char *const End); + [[nodiscard]] dependency_directives_scan::Token & + lexIncludeFilename(const char *&First, const char *const End); void skipLine(const char *&First, const char *const End); void skipDirective(StringRef Name, const char *&First, const char *const End); @@ -544,7 +544,7 @@ Scanner::lexIncludeFilename(const char *&First, const char *const End) { void Scanner::lexPPDirectiveBody(const char *&First, const char *const End) { while (true) { const dependency_directives_scan::Token &Tok = lexToken(First, End); - if (Tok.is(tok::eod)) + if (Tok.is(tok::eod) || Tok.is(tok::eof)) break; } } @@ -660,7 +660,18 @@ bool Scanner::lexModule(const char *&First, const char *const End) { // an import. switch (*First) { - case ':': + case ':': { + // `module :` is never the start of a valid module declaration. + if (Id == "module") { + skipLine(First, End); + return false; + } + // `import:(type)name` is a valid ObjC method decl, so check one more token. + (void)lexToken(First, End); + if (!tryLexIdentifierOrSkipLine(First, End)) + return false; + break; + } case '<': case '"': break; @@ -901,7 +912,10 @@ bool Scanner::lexPPLine(const char *&First, const char *const End) { case pp___include_macros: case pp_include_next: case pp_import: - lexIncludeFilename(First, End); + // Ignore missing filenames in include or import directives. + if (lexIncludeFilename(First, End).is(tok::eod)) { + return false; + } break; default: break; diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp index c3b3064cfbf28..d2210e7e18628 100644 --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -378,20 +378,22 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName, break; } - // If we've already performed the exhaustive search for module maps in this - // search directory, don't do it again. - if (Dir.haveSearchedAllModuleMaps()) - continue; + if (HSOpts->AllowModuleMapSubdirectorySearch) { + // If we've already performed the exhaustive search for module maps in + // this search directory, don't do it again. + if (Dir.haveSearchedAllModuleMaps()) + continue; - // Load all module maps in the immediate subdirectories of this search - // directory if ModuleName was from @import. - if (AllowExtraModuleMapSearch) - loadSubdirectoryModuleMaps(Dir); + // Load all module maps in the immediate subdirectories of this search + // directory if ModuleName was from @import. + if (AllowExtraModuleMapSearch) + loadSubdirectoryModuleMaps(Dir); - // Look again for the module. - Module = ModMap.findModule(ModuleName); - if (Module) - break; + // Look again for the module. + Module = ModMap.findModule(ModuleName); + if (Module) + break; + } } return Module; diff --git a/clang/lib/Lex/PPCaching.cpp b/clang/lib/Lex/PPCaching.cpp index f38ff62ebf437..cbacda9d31ae2 100644 --- a/clang/lib/Lex/PPCaching.cpp +++ b/clang/lib/Lex/PPCaching.cpp @@ -14,6 +14,15 @@ #include "clang/Lex/Preprocessor.h" using namespace clang; +std::pair +Preprocessor::LastBacktrackPos() { + assert(isBacktrackEnabled()); + auto BacktrackPos = BacktrackPositions.back(); + bool Unannotated = + static_cast(BacktrackPos) < 0; + return {Unannotated ? ~BacktrackPos : BacktrackPos, Unannotated}; +} + // EnableBacktrackAtThisPos - From the point that this method is called, and // until CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor // keeps track of the lexed tokens so that a subsequent Backtrack() call will @@ -22,26 +31,45 @@ using namespace clang; // Nested backtracks are allowed, meaning that EnableBacktrackAtThisPos can // be called multiple times and CommitBacktrackedTokens/Backtrack calls will // be combined with the EnableBacktrackAtThisPos calls in reverse order. -void Preprocessor::EnableBacktrackAtThisPos() { +void Preprocessor::EnableBacktrackAtThisPos(bool Unannotated) { assert(LexLevel == 0 && "cannot use lookahead while lexing"); - BacktrackPositions.push_back(CachedLexPos); + BacktrackPositions.push_back(Unannotated ? ~CachedLexPos : CachedLexPos); + if (Unannotated) + UnannotatedBacktrackTokens.emplace_back(CachedTokens, CachedTokens.size()); EnterCachingLexMode(); } +Preprocessor::CachedTokensTy Preprocessor::PopUnannotatedBacktrackTokens() { + assert(isUnannotatedBacktrackEnabled() && "missing unannotated tokens?"); + auto [UnannotatedTokens, NumCachedToks] = + std::move(UnannotatedBacktrackTokens.back()); + UnannotatedBacktrackTokens.pop_back(); + // If another unannotated backtrack is active, propagate any tokens that were + // lexed (not cached) since EnableBacktrackAtThisPos was last called. + if (isUnannotatedBacktrackEnabled()) + UnannotatedBacktrackTokens.back().first.append( + UnannotatedTokens.begin() + NumCachedToks, UnannotatedTokens.end()); + return std::move(UnannotatedTokens); +} + // Disable the last EnableBacktrackAtThisPos call. void Preprocessor::CommitBacktrackedTokens() { - assert(!BacktrackPositions.empty() - && "EnableBacktrackAtThisPos was not called!"); + assert(isBacktrackEnabled() && "EnableBacktrackAtThisPos was not called!"); + auto [BacktrackPos, Unannotated] = LastBacktrackPos(); BacktrackPositions.pop_back(); + if (Unannotated) + PopUnannotatedBacktrackTokens(); } // Make Preprocessor re-lex the tokens that were lexed since // EnableBacktrackAtThisPos() was previously called. void Preprocessor::Backtrack() { - assert(!BacktrackPositions.empty() - && "EnableBacktrackAtThisPos was not called!"); - CachedLexPos = BacktrackPositions.back(); + assert(isBacktrackEnabled() && "EnableBacktrackAtThisPos was not called!"); + auto [BacktrackPos, Unannotated] = LastBacktrackPos(); BacktrackPositions.pop_back(); + CachedLexPos = BacktrackPos; + if (Unannotated) + CachedTokens = PopUnannotatedBacktrackTokens(); recomputeCurLexerKind(); } @@ -67,6 +95,8 @@ void Preprocessor::CachingLex(Token &Result) { EnterCachingLexModeUnchecked(); CachedTokens.push_back(Result); ++CachedLexPos; + if (isUnannotatedBacktrackEnabled()) + UnannotatedBacktrackTokens.back().first.push_back(Result); return; } @@ -108,6 +138,8 @@ const Token &Preprocessor::PeekAhead(unsigned N) { for (size_t C = CachedLexPos + N - CachedTokens.size(); C > 0; --C) { CachedTokens.push_back(Token()); Lex(CachedTokens.back()); + if (isUnannotatedBacktrackEnabled()) + UnannotatedBacktrackTokens.back().first.push_back(CachedTokens.back()); } EnterCachingLexMode(); return CachedTokens.back(); @@ -124,7 +156,7 @@ void Preprocessor::AnnotatePreviousCachedTokens(const Token &Tok) { for (CachedTokensTy::size_type i = CachedLexPos; i != 0; --i) { CachedTokensTy::iterator AnnotBegin = CachedTokens.begin() + i-1; if (AnnotBegin->getLocation() == Tok.getLocation()) { - assert((BacktrackPositions.empty() || BacktrackPositions.back() <= i) && + assert((!isBacktrackEnabled() || LastBacktrackPos().first <= i) && "The backtrack pos points inside the annotated tokens!"); // Replace the cached tokens with the single annotation token. if (i < CachedLexPos) diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index a53540b12dee6..4e77df9ec444c 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -1137,7 +1137,9 @@ Preprocessor::LookupEmbedFile(StringRef Filename, bool isAngled, bool OpenFile, SeparateComponents(LookupPath, Entry, Filename, false); llvm::Expected ShouldBeEntry = FM.getFileRef(LookupPath, OpenFile); - return llvm::expectedToOptional(std::move(ShouldBeEntry)); + if (ShouldBeEntry) + return llvm::expectedToOptional(std::move(ShouldBeEntry)); + llvm::consumeError(ShouldBeEntry.takeError()); } return std::nullopt; } @@ -3624,12 +3626,10 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) { LexEmbedParametersResult Result{}; SmallVector ParameterTokens; tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod; - Result.ParamRange = {CurTok.getLocation(), CurTok.getLocation()}; auto DiagMismatchedBracesAndSkipToEOD = [&](tok::TokenKind Expected, std::pair Matches) { - Result.ParamRange.setEnd(CurTok.getEndLoc()); Diag(CurTok, diag::err_expected) << Expected; Diag(Matches.second, diag::note_matching) << Matches.first; if (CurTok.isNot(tok::eod)) @@ -3638,7 +3638,6 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) { auto ExpectOrDiagAndSkipToEOD = [&](tok::TokenKind Kind) { if (CurTok.isNot(Kind)) { - Result.ParamRange.setEnd(CurTok.getEndLoc()); Diag(CurTok, diag::err_expected) << Kind; if (CurTok.isNot(tok::eod)) DiscardUntilEndOfDirective(CurTok); @@ -3872,7 +3871,6 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) { } } } - Result.ParamRange.setEnd(CurTok.getLocation()); return Result; } diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 2ccd42d88b198..366212cb786fb 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -52,7 +52,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -1602,6 +1604,16 @@ static bool isTargetVariantEnvironment(const TargetInfo &TI, return false; } +#if defined(__sun__) && defined(__svr4__) +// GCC mangles std::tm as tm for binary compatibility on Solaris (Issue +// #33114). We need to match this to allow the std::put_time calls to link +// (PR #99075). +asm("_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_" + "RSt8ios_basecPKSt2tmPKcSB_ = " + "_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_" + "RSt8ios_basecPK2tmPKcSB_"); +#endif + /// ExpandBuiltinMacro - If an identifier token is read that is to be expanded /// as a builtin macro, handle it and return the next token as 'Tok'. void Preprocessor::ExpandBuiltinMacro(Token &Tok) { @@ -1721,11 +1733,13 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { Diag(Tok.getLocation(), diag::warn_pp_date_time); // MSVC, ICC, GCC, VisualAge C++ extension. The generated string should be // of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime. - const char *Result; + std::string Result; + std::stringstream TmpStream; + TmpStream.imbue(std::locale("C")); if (getPreprocessorOpts().SourceDateEpoch) { time_t TT = *getPreprocessorOpts().SourceDateEpoch; std::tm *TM = std::gmtime(&TT); - Result = asctime(TM); + TmpStream << std::put_time(TM, "%a %b %e %T %Y"); } else { // Get the file that we are lexing out of. If we're currently lexing from // a macro, dig into the include stack. @@ -1735,13 +1749,13 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { if (CurFile) { time_t TT = CurFile->getModificationTime(); struct tm *TM = localtime(&TT); - Result = asctime(TM); - } else { - Result = "??? ??? ?? ??:??:?? ????\n"; + TmpStream << std::put_time(TM, "%a %b %e %T %Y"); } } - // Surround the string with " and strip the trailing newline. - OS << '"' << StringRef(Result).drop_back() << '"'; + Result = TmpStream.str(); + if (Result.empty()) + Result = "??? ??? ?? ??:??:?? ????"; + OS << '"' << Result << '"'; Tok.setKind(tok::string_literal); } else if (II == Ident__FLT_EVAL_METHOD__) { // __FLT_EVAL_METHOD__ is set to the default value. diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index e04ff58ae8c9d..3a8bbb72591cd 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -170,7 +170,7 @@ Preprocessor::Preprocessor(std::shared_ptr PPOpts, } Preprocessor::~Preprocessor() { - assert(BacktrackPositions.empty() && "EnableBacktrack/Backtrack imbalance!"); + assert(!isBacktrackEnabled() && "EnableBacktrack/Backtrack imbalance!"); IncludeMacroStack.clear(); @@ -988,7 +988,7 @@ void Preprocessor::LexTokensUntilEOF(std::vector *Tokens) { } /// Lex a header-name token (including one formed from header-name-tokens if -/// \p AllowConcatenation is \c true). +/// \p AllowMacroExpansion is \c true). /// /// \param FilenameTok Filled in with the next token. On success, this will /// be either a header_name token. On failure, it will be whatever other diff --git a/clang/lib/Parse/ParseAST.cpp b/clang/lib/Parse/ParseAST.cpp index dc8df8e8f3f03..910bbac0c5920 100644 --- a/clang/lib/Parse/ParseAST.cpp +++ b/clang/lib/Parse/ParseAST.cpp @@ -153,7 +153,15 @@ void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) { bool HaveLexer = S.getPreprocessor().getCurrentLexer(); if (HaveLexer) { - llvm::TimeTraceScope TimeScope("Frontend"); + llvm::TimeTraceScope TimeScope("Frontend", [&]() { + llvm::TimeTraceMetadata M; + if (llvm::isTimeTraceVerbose()) { + const SourceManager &SM = S.getSourceManager(); + if (const auto *FE = SM.getFileEntryForID(SM.getMainFileID())) + M.File = FE->tryGetRealPathName(); + } + return M; + }); P.Initialize(); Parser::DeclGroupPtrTy ADecl; Sema::ModuleImportState ImportState; diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 9ccbbf9a7d5d0..b461743833c82 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -1205,41 +1205,6 @@ bool Parser::ConsumeAndStoreConditional(CachedTokens &Toks) { return true; } -/// A tentative parsing action that can also revert token annotations. -class Parser::UnannotatedTentativeParsingAction : public TentativeParsingAction { -public: - explicit UnannotatedTentativeParsingAction(Parser &Self, - tok::TokenKind EndKind) - : TentativeParsingAction(Self), Self(Self), EndKind(EndKind) { - // Stash away the old token stream, so we can restore it once the - // tentative parse is complete. - TentativeParsingAction Inner(Self); - Self.ConsumeAndStoreUntil(EndKind, Toks, true, /*ConsumeFinalToken*/false); - Inner.Revert(); - } - - void RevertAnnotations() { - Revert(); - - // Put back the original tokens. - Self.SkipUntil(EndKind, StopAtSemi | StopBeforeMatch); - if (Toks.size()) { - auto Buffer = std::make_unique(Toks.size()); - std::copy(Toks.begin() + 1, Toks.end(), Buffer.get()); - Buffer[Toks.size() - 1] = Self.Tok; - Self.PP.EnterTokenStream(std::move(Buffer), Toks.size(), true, - /*IsReinject*/ true); - - Self.Tok = Toks.front(); - } - } - -private: - Parser &Self; - CachedTokens Toks; - tok::TokenKind EndKind; -}; - /// ConsumeAndStoreInitializer - Consume and store the token at the passed token /// container until the end of the current initializer expression (either a /// default argument or an in-class initializer for a non-static data member). @@ -1277,9 +1242,7 @@ bool Parser::ConsumeAndStoreInitializer(CachedTokens &Toks, // syntactically-valid init-declarator-list, then this comma ends // the default initializer. { - UnannotatedTentativeParsingAction PA(*this, - CIK == CIK_DefaultInitializer - ? tok::semi : tok::r_paren); + TentativeParsingAction TPA(*this, /*Unannotated=*/true); Sema::TentativeAnalysisScope Scope(Actions); TPResult Result = TPResult::Error; @@ -1307,7 +1270,7 @@ bool Parser::ConsumeAndStoreInitializer(CachedTokens &Toks, // Put the token stream back and undo any annotations we performed // after the comma. They may reflect a different parse than the one // we will actually perform at the end of the class. - PA.RevertAnnotations(); + TPA.Revert(); // If what follows could be a declaration, it is a declaration. if (Result != TPResult::False && Result != TPResult::Error) diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 941009abebc43..e37c820d1b23c 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -314,64 +314,92 @@ void Parser::ParseGNUAttributes(ParsedAttributes &Attrs, } /// Determine whether the given attribute has an identifier argument. -static bool attributeHasIdentifierArg(const IdentifierInfo &II) { +static bool attributeHasIdentifierArg(const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_IDENTIFIER_ARG_LIST - return llvm::StringSwitch(normalizeAttrName(II.getName())) + return llvm::StringSwitch(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" - .Default(false); + .Default(false); #undef CLANG_ATTR_IDENTIFIER_ARG_LIST } /// Determine whether the given attribute has an identifier argument. static ParsedAttributeArgumentsProperties -attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II) { +attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_STRING_LITERAL_ARG_LIST - return llvm::StringSwitch(normalizeAttrName(II.getName())) + return llvm::StringSwitch(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" .Default(0); #undef CLANG_ATTR_STRING_LITERAL_ARG_LIST } /// Determine whether the given attribute has a variadic identifier argument. -static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II) { +static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST - return llvm::StringSwitch(normalizeAttrName(II.getName())) + return llvm::StringSwitch(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" - .Default(false); + .Default(false); #undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST } /// Determine whether the given attribute treats kw_this as an identifier. -static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II) { +static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST - return llvm::StringSwitch(normalizeAttrName(II.getName())) + return llvm::StringSwitch(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" - .Default(false); + .Default(false); #undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST } /// Determine if an attribute accepts parameter packs. -static bool attributeAcceptsExprPack(const IdentifierInfo &II) { +static bool attributeAcceptsExprPack(const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_ACCEPTS_EXPR_PACK - return llvm::StringSwitch(normalizeAttrName(II.getName())) + return llvm::StringSwitch(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" .Default(false); #undef CLANG_ATTR_ACCEPTS_EXPR_PACK } /// Determine whether the given attribute parses a type argument. -static bool attributeIsTypeArgAttr(const IdentifierInfo &II) { +static bool attributeIsTypeArgAttr(const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_TYPE_ARG_LIST - return llvm::StringSwitch(normalizeAttrName(II.getName())) + return llvm::StringSwitch(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" - .Default(false); + .Default(false); #undef CLANG_ATTR_TYPE_ARG_LIST } /// Determine whether the given attribute takes identifier arguments. -static bool attributeHasStrictIdentifierArgs(const IdentifierInfo &II) { +static bool attributeHasStrictIdentifierArgs(const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_STRICT_IDENTIFIER_ARG_AT_INDEX_LIST - return (llvm::StringSwitch(normalizeAttrName(II.getName())) + return (llvm::StringSwitch(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" .Default(0)) != 0; #undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_AT_INDEX_LIST @@ -380,9 +408,13 @@ static bool attributeHasStrictIdentifierArgs(const IdentifierInfo &II) { /// Determine whether the given attribute takes an identifier argument at a /// specific index static bool attributeHasStrictIdentifierArgAtIndex(const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName, size_t argIndex) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_STRICT_IDENTIFIER_ARG_AT_INDEX_LIST - return (llvm::StringSwitch(normalizeAttrName(II.getName())) + return (llvm::StringSwitch(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" .Default(0)) & (1ull << argIndex); @@ -391,11 +423,15 @@ static bool attributeHasStrictIdentifierArgAtIndex(const IdentifierInfo &II, /// Determine whether the given attribute requires parsing its arguments /// in an unevaluated context or not. -static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II) { +static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_ARG_CONTEXT_LIST - return llvm::StringSwitch(normalizeAttrName(II.getName())) + return llvm::StringSwitch(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" - .Default(false); + .Default(false); #undef CLANG_ATTR_ARG_CONTEXT_LIST } @@ -523,10 +559,12 @@ unsigned Parser::ParseAttributeArgsCommon( // Ignore the left paren location for now. ConsumeParen(); - bool ChangeKWThisToIdent = attributeTreatsKeywordThisAsIdentifier(*AttrName); - bool AttributeIsTypeArgAttr = attributeIsTypeArgAttr(*AttrName); + bool ChangeKWThisToIdent = attributeTreatsKeywordThisAsIdentifier( + *AttrName, Form.getSyntax(), ScopeName); + bool AttributeIsTypeArgAttr = + attributeIsTypeArgAttr(*AttrName, Form.getSyntax(), ScopeName); bool AttributeHasVariadicIdentifierArg = - attributeHasVariadicIdentifierArg(*AttrName); + attributeHasVariadicIdentifierArg(*AttrName, Form.getSyntax(), ScopeName); // Interpret "kw_this" as an identifier if the attributed requests it. if (ChangeKWThisToIdent && Tok.is(tok::kw_this)) @@ -535,8 +573,9 @@ unsigned Parser::ParseAttributeArgsCommon( ArgsVector ArgExprs; if (Tok.is(tok::identifier)) { // If this attribute wants an 'identifier' argument, make it so. - bool IsIdentifierArg = AttributeHasVariadicIdentifierArg || - attributeHasIdentifierArg(*AttrName); + bool IsIdentifierArg = + AttributeHasVariadicIdentifierArg || + attributeHasIdentifierArg(*AttrName, Form.getSyntax(), ScopeName); ParsedAttr::Kind AttrKind = ParsedAttr::getParsedKind(AttrName, ScopeName, Form.getSyntax()); @@ -568,7 +607,8 @@ unsigned Parser::ParseAttributeArgsCommon( if (T.isUsable()) TheParsedType = T.get(); } else if (AttributeHasVariadicIdentifierArg || - attributeHasStrictIdentifierArgs(*AttrName)) { + attributeHasStrictIdentifierArgs(*AttrName, Form.getSyntax(), + ScopeName)) { // Parse variadic identifier arg. This can either consume identifiers or // expressions. Variadic identifier args do not support parameter packs // because those are typically used for attributes with enumeration @@ -579,8 +619,9 @@ unsigned Parser::ParseAttributeArgsCommon( if (ChangeKWThisToIdent && Tok.is(tok::kw_this)) Tok.setKind(tok::identifier); - if (Tok.is(tok::identifier) && attributeHasStrictIdentifierArgAtIndex( - *AttrName, ArgExprs.size())) { + if (Tok.is(tok::identifier) && + attributeHasStrictIdentifierArgAtIndex( + *AttrName, Form.getSyntax(), ScopeName, ArgExprs.size())) { ArgExprs.push_back(ParseIdentifierLoc()); continue; } @@ -589,7 +630,8 @@ unsigned Parser::ParseAttributeArgsCommon( if (Tok.is(tok::identifier)) { ArgExprs.push_back(ParseIdentifierLoc()); } else { - bool Uneval = attributeParsedArgsUnevaluated(*AttrName); + bool Uneval = attributeParsedArgsUnevaluated( + *AttrName, Form.getSyntax(), ScopeName); EnterExpressionEvaluationContext Unevaluated( Actions, Uneval ? Sema::ExpressionEvaluationContext::Unevaluated @@ -610,7 +652,8 @@ unsigned Parser::ParseAttributeArgsCommon( } while (TryConsumeToken(tok::comma)); } else { // General case. Parse all available expressions. - bool Uneval = attributeParsedArgsUnevaluated(*AttrName); + bool Uneval = attributeParsedArgsUnevaluated(*AttrName, Form.getSyntax(), + ScopeName); EnterExpressionEvaluationContext Unevaluated( Actions, Uneval ? Sema::ExpressionEvaluationContext::Unevaluated @@ -621,7 +664,8 @@ unsigned Parser::ParseAttributeArgsCommon( ExprVector ParsedExprs; ParsedAttributeArgumentsProperties ArgProperties = - attributeStringLiteralListArg(getTargetInfo().getTriple(), *AttrName); + attributeStringLiteralListArg(getTargetInfo().getTriple(), *AttrName, + Form.getSyntax(), ScopeName); if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties)) { SkipUntil(tok::r_paren, StopAtSemi); return 0; @@ -632,7 +676,7 @@ unsigned Parser::ParseAttributeArgsCommon( if (!isa(ParsedExprs[I])) continue; - if (!attributeAcceptsExprPack(*AttrName)) { + if (!attributeAcceptsExprPack(*AttrName, Form.getSyntax(), ScopeName)) { Diag(Tok.getLocation(), diag::err_attribute_argument_parm_pack_not_supported) << AttrName; @@ -696,7 +740,7 @@ void Parser::ParseGNUAttributeArgs( ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, ScopeLoc, Form); return; - } else if (attributeIsTypeArgAttr(*AttrName)) { + } else if (attributeIsTypeArgAttr(*AttrName, Form.getSyntax(), ScopeName)) { ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc, Form); return; @@ -6651,48 +6695,66 @@ void Parser::ParseDeclaratorInternal(Declarator &D, (Tok.is(tok::identifier) && (NextToken().is(tok::coloncolon) || NextToken().is(tok::less))) || Tok.is(tok::annot_cxxscope))) { + TentativeParsingAction TPA(*this, /*Unannotated=*/true); bool EnteringContext = D.getContext() == DeclaratorContext::File || D.getContext() == DeclaratorContext::Member; CXXScopeSpec SS; SS.setTemplateParamLists(D.getTemplateParameterLists()); - ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHasErrors=*/false, EnteringContext); - if (SS.isNotEmpty()) { - if (Tok.isNot(tok::star)) { - // The scope spec really belongs to the direct-declarator. - if (D.mayHaveIdentifier()) - D.getCXXScopeSpec() = SS; - else - AnnotateScopeToken(SS, true); + if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, + /*ObjectHasErrors=*/false, + /*EnteringContext=*/false, + /*MayBePseudoDestructor=*/nullptr, + /*IsTypename=*/false, /*LastII=*/nullptr, + /*OnlyNamespace=*/false, + /*InUsingDeclaration=*/false, + /*Disambiguation=*/EnteringContext) || + + SS.isEmpty() || SS.isInvalid() || !EnteringContext || + Tok.is(tok::star)) { + TPA.Commit(); + if (SS.isNotEmpty() && Tok.is(tok::star)) { + if (SS.isValid()) { + checkCompoundToken(SS.getEndLoc(), tok::coloncolon, + CompoundToken::MemberPtr); + } - if (DirectDeclParser) - (this->*DirectDeclParser)(D); + SourceLocation StarLoc = ConsumeToken(); + D.SetRangeEnd(StarLoc); + DeclSpec DS(AttrFactory); + ParseTypeQualifierListOpt(DS); + D.ExtendWithDeclSpec(DS); + + // Recurse to parse whatever is left. + Actions.runWithSufficientStackSpace(D.getBeginLoc(), [&] { + ParseDeclaratorInternal(D, DirectDeclParser); + }); + + // Sema will have to catch (syntactically invalid) pointers into global + // scope. It has to catch pointers into namespace scope anyway. + D.AddTypeInfo(DeclaratorChunk::getMemberPointer( + SS, DS.getTypeQualifiers(), StarLoc, DS.getEndLoc()), + std::move(DS.getAttributes()), + /*EndLoc=*/SourceLocation()); return; } + } else { + TPA.Revert(); + SS.clear(); + ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, + /*ObjectHasErrors=*/false, + /*EnteringContext=*/true); + } - if (SS.isValid()) { - checkCompoundToken(SS.getEndLoc(), tok::coloncolon, - CompoundToken::MemberPtr); - } + if (SS.isNotEmpty()) { + // The scope spec really belongs to the direct-declarator. + if (D.mayHaveIdentifier()) + D.getCXXScopeSpec() = SS; + else + AnnotateScopeToken(SS, true); - SourceLocation StarLoc = ConsumeToken(); - D.SetRangeEnd(StarLoc); - DeclSpec DS(AttrFactory); - ParseTypeQualifierListOpt(DS); - D.ExtendWithDeclSpec(DS); - - // Recurse to parse whatever is left. - Actions.runWithSufficientStackSpace(D.getBeginLoc(), [&] { - ParseDeclaratorInternal(D, DirectDeclParser); - }); - - // Sema will have to catch (syntactically invalid) pointers into global - // scope. It has to catch pointers into namespace scope anyway. - D.AddTypeInfo(DeclaratorChunk::getMemberPointer( - SS, DS.getTypeQualifiers(), StarLoc, DS.getEndLoc()), - std::move(DS.getAttributes()), - /* Don't replace range end. */ SourceLocation()); + if (DirectDeclParser) + (this->*DirectDeclParser)(D); return; } } diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index ec8d5fd0feb95..7372a2e3b4084 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -763,6 +763,9 @@ class CastExpressionIdValidator final : public CorrectionCandidateCallback { bool Parser::isRevertibleTypeTrait(const IdentifierInfo *II, tok::TokenKind *Kind) { if (RevertibleTypeTraits.empty()) { +// Revertible type trait is a feature for backwards compatibility with older +// standard libraries that declare their own structs with the same name as +// the builtins listed below. New builtins should NOT be added to this list. #define RTT_JOIN(X, Y) X##Y #define REVERTIBLE_TYPE_TRAIT(Name) \ RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] = RTT_JOIN(tok::kw_, Name) @@ -790,7 +793,6 @@ bool Parser::isRevertibleTypeTrait(const IdentifierInfo *II, REVERTIBLE_TYPE_TRAIT(__is_fundamental); REVERTIBLE_TYPE_TRAIT(__is_integral); REVERTIBLE_TYPE_TRAIT(__is_interface_class); - REVERTIBLE_TYPE_TRAIT(__is_layout_compatible); REVERTIBLE_TYPE_TRAIT(__is_literal); REVERTIBLE_TYPE_TRAIT(__is_lvalue_expr); REVERTIBLE_TYPE_TRAIT(__is_lvalue_reference); @@ -841,6 +843,26 @@ bool Parser::isRevertibleTypeTrait(const IdentifierInfo *II, return false; } +ExprResult Parser::ParseBuiltinPtrauthTypeDiscriminator() { + SourceLocation Loc = ConsumeToken(); + + BalancedDelimiterTracker T(*this, tok::l_paren); + if (T.expectAndConsume()) + return ExprError(); + + TypeResult Ty = ParseTypeName(); + if (Ty.isInvalid()) { + SkipUntil(tok::r_paren, StopAtSemi); + return ExprError(); + } + + SourceLocation EndLoc = Tok.getLocation(); + T.consumeClose(); + return Actions.ActOnUnaryExprOrTypeTraitExpr( + Loc, UETT_PtrAuthTypeDiscriminator, + /*isType=*/true, Ty.get().getAsOpaquePtr(), SourceRange(Loc, EndLoc)); +} + /// Parse a cast-expression, or, if \pisUnaryExpression is true, parse /// a unary-expression. /// @@ -1818,6 +1840,9 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, Res = ParseArrayTypeTrait(); break; + case tok::kw___builtin_ptrauth_type_discriminator: + return ParseBuiltinPtrauthTypeDiscriminator(); + case tok::kw___is_lvalue_expr: case tok::kw___is_rvalue_expr: if (NotPrimaryExpression) @@ -2523,7 +2548,19 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, return ExprError(); } - Operand = ParseCastExpression(UnaryExprOnly); + // If we're parsing a chain that consists of keywords that could be + // followed by a non-parenthesized expression, BalancedDelimiterTracker + // is not going to help when the nesting is too deep. In this corner case + // we continue to parse with sufficient stack space to avoid crashing. + if (OpTok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof, + tok::kw_alignof, tok::kw__Alignof) && + Tok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof, + tok::kw_alignof, tok::kw__Alignof)) + Actions.runWithSufficientStackSpace(Tok.getLocation(), [&] { + Operand = ParseCastExpression(UnaryExprOnly); + }); + else + Operand = ParseCastExpression(UnaryExprOnly); } else { // If it starts with a '(', we know that it is either a parenthesized // type-name, or it is a unary-expression that starts with a compound @@ -3697,7 +3734,7 @@ void Parser::injectEmbedTokens() { I += 2; } PP.EnterTokenStream(std::move(Toks), /*DisableMacroExpansion=*/true, - /*IsReinject=*/false); + /*IsReinject=*/true); ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); } diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 1d364f77a8146..c0eae73927cdd 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -159,8 +159,8 @@ void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType, bool Parser::ParseOptionalCXXScopeSpecifier( CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool *MayBePseudoDestructor, bool IsTypename, - const IdentifierInfo **LastII, bool OnlyNamespace, - bool InUsingDeclaration) { + const IdentifierInfo **LastII, bool OnlyNamespace, bool InUsingDeclaration, + bool Disambiguation) { assert(getLangOpts().CPlusPlus && "Call sites of this function should be guarded by checking for C++"); @@ -528,13 +528,11 @@ bool Parser::ParseOptionalCXXScopeSpecifier( UnqualifiedId TemplateName; TemplateName.setIdentifier(&II, Tok.getLocation()); bool MemberOfUnknownSpecialization; - if (TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS, - /*hasTemplateKeyword=*/false, - TemplateName, - ObjectType, - EnteringContext, - Template, - MemberOfUnknownSpecialization)) { + if (TemplateNameKind TNK = Actions.isTemplateName( + getCurScope(), SS, + /*hasTemplateKeyword=*/false, TemplateName, ObjectType, + EnteringContext, Template, MemberOfUnknownSpecialization, + Disambiguation)) { // If lookup didn't find anything, we treat the name as a template-name // anyway. C++20 requires this, and in prior language modes it improves // error recovery. But before we commit to this, check that we actually @@ -557,7 +555,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier( continue; } - if (MemberOfUnknownSpecialization && (ObjectType || SS.isSet()) && + if (MemberOfUnknownSpecialization && !Disambiguation && + (ObjectType || SS.isSet()) && (IsTypename || isTemplateArgumentList(1) == TPResult::True)) { // If we had errors before, ObjectType can be dependent even without any // templates. Do not report missing template keyword in that case. diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 326cd22ff9005..e975e96c5c7e4 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -2885,6 +2885,8 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( } break; } + case OMPD_reverse: + case OMPD_interchange: case OMPD_declare_target: { SourceLocation DTLoc = ConsumeAnyToken(); bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end); @@ -3835,6 +3837,7 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind, // Get a defaultmap modifier unsigned Modifier = getOpenMPSimpleClauseType( Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts()); + // Set defaultmap modifier to unknown if it is either scalar, aggregate, or // pointer if (Modifier < OMPC_DEFAULTMAP_MODIFIER_unknown) diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index cc6f18b5b319f..aef4ddb758816 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -14,6 +14,7 @@ #include "clang/Basic/PragmaKinds.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Lex/PreprocessorOptions.h" #include "clang/Lex/Token.h" #include "clang/Parse/LoopHint.h" #include "clang/Parse/ParseDiagnostic.h" @@ -411,6 +412,19 @@ struct PragmaRISCVHandler : public PragmaHandler { Sema &Actions; }; +struct PragmaMCFuncHandler : public PragmaHandler { + PragmaMCFuncHandler(bool ReportError) + : PragmaHandler("mc_func"), ReportError(ReportError) {} + void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, + Token &Tok) override { + if (ReportError) + PP.Diag(Tok, diag::err_pragma_mc_func_not_supported); + } + +private: + bool ReportError = false; +}; + void markAsReinjectedForRelexing(llvm::MutableArrayRef Toks) { for (auto &T : Toks) T.setFlag(clang::Token::IsReinjected); @@ -568,6 +582,12 @@ void Parser::initializePragmaHandlers() { RISCVPragmaHandler = std::make_unique(Actions); PP.AddPragmaHandler("clang", RISCVPragmaHandler.get()); } + + if (getTargetInfo().getTriple().isOSAIX()) { + MCFuncPragmaHandler = std::make_unique( + PP.getPreprocessorOpts().ErrorOnPragmaMcfuncOnAIX); + PP.AddPragmaHandler(MCFuncPragmaHandler.get()); + } } void Parser::resetPragmaHandlers() { @@ -702,6 +722,11 @@ void Parser::resetPragmaHandlers() { PP.RemovePragmaHandler("clang", RISCVPragmaHandler.get()); RISCVPragmaHandler.reset(); } + + if (getTargetInfo().getTriple().isOSAIX()) { + PP.RemovePragmaHandler(MCFuncPragmaHandler.get()); + MCFuncPragmaHandler.reset(); + } } /// Handle the annotation token produced for #pragma unused(...) diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 22d38adc28ebe..bdb3fc051d0b3 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -299,6 +299,15 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes( goto Retry; } + case tok::kw_template: { + SourceLocation DeclEnd; + ParsedAttributes Attrs(AttrFactory); + ParseTemplateDeclarationOrSpecialization(DeclaratorContext::Block, DeclEnd, + Attrs, + getAccessSpecifierIfPresent()); + return StmtError(); + } + case tok::kw_case: // C99 6.8.1: labeled-statement return ParseCaseStatement(StmtCtx); case tok::kw_default: // C99 6.8.1: labeled-statement diff --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt index e6a2d132f9618..49d6be63bbfe8 100644 --- a/clang/lib/Sema/CMakeLists.txt +++ b/clang/lib/Sema/CMakeLists.txt @@ -45,6 +45,7 @@ add_clang_library(clangSema SemaAvailability.cpp SemaBPF.cpp SemaBase.cpp + SemaBoundsSafety.cpp SemaCXXScopeSpec.cpp SemaCast.cpp SemaChecking.cpp diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index 995e4cbadacfe..7389046eaddde 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "CheckExprLifetime.h" +#include "clang/AST/Decl.h" #include "clang/AST/Expr.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Sema/Initialization.h" @@ -191,7 +192,8 @@ struct IndirectLocalPathEntry { TemporaryCopy, LambdaCaptureInit, GslReferenceInit, - GslPointerInit + GslPointerInit, + GslPointerAssignment, } Kind; Expr *E; union { @@ -307,8 +309,7 @@ static bool shouldTrackFirstArgument(const FunctionDecl *FD) { const auto *RD = FD->getParamDecl(0)->getType()->getPointeeCXXRecordDecl(); if (!FD->isInStdNamespace() || !RD || !RD->isInStdNamespace()) return false; - if (!isRecordWithAttr(QualType(RD->getTypeForDecl(), 0)) && - !isRecordWithAttr(QualType(RD->getTypeForDecl(), 0))) + if (!RD->hasAttr() && !RD->hasAttr()) return false; if (FD->getReturnType()->isPointerType() || isRecordWithAttr(FD->getReturnType())) { @@ -337,7 +338,8 @@ static void handleGslAnnotatedTypes(IndirectLocalPath &Path, Expr *Call, for (const IndirectLocalPathEntry &PE : llvm::reverse(Path)) { if (PE.Kind == IndirectLocalPathEntry::GslReferenceInit) continue; - if (PE.Kind == IndirectLocalPathEntry::GslPointerInit) + if (PE.Kind == IndirectLocalPathEntry::GslPointerInit || + PE.Kind == IndirectLocalPathEntry::GslPointerAssignment) return; break; } @@ -547,6 +549,14 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path, EnableLifetimeWarnings); } + if (auto *M = dyn_cast(Init)) { + // Lifetime of a non-reference type field is same as base object. + if (auto *F = dyn_cast(M->getMemberDecl()); + F && !F->getType()->isReferenceType()) + visitLocalsRetainedByInitializer(Path, M->getBase(), Visit, true, + EnableLifetimeWarnings); + } + if (isa(Init)) { if (EnableLifetimeWarnings) handleGslAnnotatedTypes(Path, Init, Visit); @@ -815,7 +825,6 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, if (auto *CCE = dyn_cast(Init)) { if (CCE->getConstructor()->isCopyOrMoveConstructor()) { if (auto *MTE = dyn_cast(CCE->getArg(0))) { - // assert(false && "hit temporary copy path"); Expr *Arg = MTE->getSubExpr(); Path.push_back({IndirectLocalPathEntry::TemporaryCopy, Arg, CCE->getConstructor()}); @@ -937,6 +946,7 @@ static SourceRange nextPathEntryRange(const IndirectLocalPath &Path, unsigned I, case IndirectLocalPathEntry::TemporaryCopy: case IndirectLocalPathEntry::GslReferenceInit: case IndirectLocalPathEntry::GslPointerInit: + case IndirectLocalPathEntry::GslPointerAssignment: // These exist primarily to mark the path as not permitting or // supporting lifetime extension. break; @@ -957,16 +967,20 @@ static SourceRange nextPathEntryRange(const IndirectLocalPath &Path, unsigned I, return E->getSourceRange(); } -static bool pathOnlyInitializesGslPointer(IndirectLocalPath &Path) { +static bool pathOnlyHandlesGslPointer(IndirectLocalPath &Path) { for (const auto &It : llvm::reverse(Path)) { - if (It.Kind == IndirectLocalPathEntry::VarInit) - continue; - if (It.Kind == IndirectLocalPathEntry::AddressOf) - continue; - if (It.Kind == IndirectLocalPathEntry::LifetimeBoundCall) + switch (It.Kind) { + case IndirectLocalPathEntry::VarInit: + case IndirectLocalPathEntry::AddressOf: + case IndirectLocalPathEntry::LifetimeBoundCall: continue; - return It.Kind == IndirectLocalPathEntry::GslPointerInit || - It.Kind == IndirectLocalPathEntry::GslReferenceInit; + case IndirectLocalPathEntry::GslPointerInit: + case IndirectLocalPathEntry::GslReferenceInit: + case IndirectLocalPathEntry::GslPointerAssignment: + return true; + default: + return false; + } } return false; } @@ -975,7 +989,8 @@ static void checkExprLifetimeImpl(Sema &SemaRef, const InitializedEntity *InitEntity, const InitializedEntity *ExtendingEntity, LifetimeKind LK, - const AssignedEntity *AEntity, Expr *Init) { + const AssignedEntity *AEntity, Expr *Init, + bool EnableLifetimeWarnings) { assert((AEntity && LK == LK_Assignment) || (InitEntity && LK != LK_Assignment)); // If this entity doesn't have an interesting lifetime, don't bother looking @@ -992,9 +1007,9 @@ static void checkExprLifetimeImpl(Sema &SemaRef, auto *MTE = dyn_cast(L); - bool IsGslPtrInitWithGslTempOwner = false; + bool IsGslPtrValueFromGslTempOwner = false; bool IsLocalGslOwner = false; - if (pathOnlyInitializesGslPointer(Path)) { + 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: @@ -1005,13 +1020,13 @@ static void checkExprLifetimeImpl(Sema &SemaRef, if (pathContainsInit(Path) || !IsLocalGslOwner) return false; } else { - IsGslPtrInitWithGslTempOwner = + 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 (!IsGslPtrInitWithGslTempOwner) + if (!IsGslPtrValueFromGslTempOwner) return true; } } @@ -1030,7 +1045,7 @@ static void checkExprLifetimeImpl(Sema &SemaRef, return false; } - if (IsGslPtrInitWithGslTempOwner && DiagLoc.isValid()) { + if (IsGslPtrValueFromGslTempOwner && DiagLoc.isValid()) { SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer) << DiagRange; return false; @@ -1073,14 +1088,16 @@ static void checkExprLifetimeImpl(Sema &SemaRef, } case LK_Assignment: { - if (!MTE) + if (!MTE || pathContainsInit(Path)) return false; assert(shouldLifetimeExtendThroughPath(Path) == PathLifetimeKind::NoExtend && "No lifetime extension for assignments"); - if (!pathContainsInit(Path)) - SemaRef.Diag(DiagLoc, diag::warn_dangling_pointer_assignment) - << AEntity->LHS << DiagRange; + SemaRef.Diag(DiagLoc, + IsGslPtrValueFromGslTempOwner + ? diag::warn_dangling_lifetime_pointer_assignment + : diag::warn_dangling_pointer_assignment) + << AEntity->LHS << DiagRange; return false; } case LK_MemInitializer: { @@ -1090,7 +1107,7 @@ static void checkExprLifetimeImpl(Sema &SemaRef, // temporary, the program is ill-formed. if (auto *ExtendingDecl = ExtendingEntity ? ExtendingEntity->getDecl() : nullptr) { - if (IsGslPtrInitWithGslTempOwner) { + if (IsGslPtrValueFromGslTempOwner) { SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer_member) << ExtendingDecl << DiagRange; SemaRef.Diag(ExtendingDecl->getLocation(), @@ -1131,7 +1148,7 @@ static void checkExprLifetimeImpl(Sema &SemaRef, // Suppress false positives for code like the one below: // Ctor(unique_ptr up) : member(*up), member2(move(up)) {} - if (IsLocalGslOwner && pathOnlyInitializesGslPointer(Path)) + if (IsLocalGslOwner && pathOnlyHandlesGslPointer(Path)) return false; auto *DRE = dyn_cast(L); @@ -1159,7 +1176,7 @@ static void checkExprLifetimeImpl(Sema &SemaRef, case LK_New: if (isa(L)) { - if (IsGslPtrInitWithGslTempOwner) + if (IsGslPtrValueFromGslTempOwner) SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer) << DiagRange; else @@ -1226,6 +1243,7 @@ static void checkExprLifetimeImpl(Sema &SemaRef, case IndirectLocalPathEntry::TemporaryCopy: case IndirectLocalPathEntry::GslPointerInit: case IndirectLocalPathEntry::GslReferenceInit: + case IndirectLocalPathEntry::GslPointerAssignment: // FIXME: Consider adding a note for these. break; @@ -1265,9 +1283,11 @@ static void checkExprLifetimeImpl(Sema &SemaRef, return false; }; - bool EnableLifetimeWarnings = !SemaRef.getDiagnostics().isIgnored( - diag::warn_dangling_lifetime_pointer, SourceLocation()); llvm::SmallVector Path; + if (EnableLifetimeWarnings && LK == LK_Assignment && + isRecordWithAttr(AEntity->LHS->getType())) + Path.push_back({IndirectLocalPathEntry::GslPointerAssignment, Init}); + if (Init->isGLValue()) visitLocalsRetainedByReferenceBinding(Path, Init, RK_ReferenceBinding, TemporaryVisitor, @@ -1284,16 +1304,26 @@ void checkExprLifetime(Sema &SemaRef, const InitializedEntity &Entity, auto LTResult = getEntityLifetime(&Entity); LifetimeKind LK = LTResult.getInt(); const InitializedEntity *ExtendingEntity = LTResult.getPointer(); - checkExprLifetimeImpl(SemaRef, &Entity, ExtendingEntity, LK, nullptr, Init); + bool EnableLifetimeWarnings = !SemaRef.getDiagnostics().isIgnored( + diag::warn_dangling_lifetime_pointer, SourceLocation()); + checkExprLifetimeImpl(SemaRef, &Entity, ExtendingEntity, LK, + /*AEntity*/ nullptr, Init, EnableLifetimeWarnings); } void checkExprLifetime(Sema &SemaRef, const AssignedEntity &Entity, Expr *Init) { - if (!Entity.LHS->getType()->isPointerType()) // builtin pointer type + bool EnableLifetimeWarnings = !SemaRef.getDiagnostics().isIgnored( + diag::warn_dangling_lifetime_pointer, SourceLocation()); + bool RunAnalysis = Entity.LHS->getType()->isPointerType() || + (EnableLifetimeWarnings && + isRecordWithAttr(Entity.LHS->getType())); + + if (!RunAnalysis) return; + checkExprLifetimeImpl(SemaRef, /*InitEntity=*/nullptr, /*ExtendingEntity=*/nullptr, LK_Assignment, &Entity, - Init); + Init, EnableLifetimeWarnings); } } // namespace clang::sema diff --git a/clang/lib/Sema/ParsedAttr.cpp b/clang/lib/Sema/ParsedAttr.cpp index 5c2ebf51c03c0..23c7982f722b8 100644 --- a/clang/lib/Sema/ParsedAttr.cpp +++ b/clang/lib/Sema/ParsedAttr.cpp @@ -229,7 +229,7 @@ bool ParsedAttr::slidesFromDeclToDeclSpecLegacyBehavior() const { // atributes. return false; - assert(isStandardAttributeSyntax()); + assert(isStandardAttributeSyntax() || isAlignas()); // We have historically allowed some type attributes with standard attribute // syntax to slide to the decl-specifier-seq, so we have to keep supporting diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index bf7ce4b1ffc3d..8287db1afb302 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -496,7 +496,9 @@ void Sema::Initialize() { #include "clang/Basic/OpenCLExtensionTypes.def" } - if (Context.getTargetInfo().hasAArch64SVETypes()) { + if (Context.getTargetInfo().hasAArch64SVETypes() || + (Context.getAuxTargetInfo() && + Context.getAuxTargetInfo()->hasAArch64SVETypes())) { #define SVE_TYPE(Name, Id, SingletonId) \ addImplicitTypedef(Name, Context.SingletonId); #include "clang/Basic/AArch64SVEACLETypes.def" diff --git a/clang/lib/Sema/SemaAPINotes.cpp b/clang/lib/Sema/SemaAPINotes.cpp index 3482f3741fce6..2c49c1f64b2da 100644 --- a/clang/lib/Sema/SemaAPINotes.cpp +++ b/clang/lib/Sema/SemaAPINotes.cpp @@ -546,6 +546,13 @@ static void ProcessAPINotes(Sema &S, FunctionOrMethod AnyFunc, Metadata); } +/// Process API notes for a C++ method. +static void ProcessAPINotes(Sema &S, CXXMethodDecl *Method, + const api_notes::CXXMethodInfo &Info, + VersionedInfoMetadata Metadata) { + ProcessAPINotes(S, (FunctionOrMethod)Method, Info, Metadata); +} + /// Process API notes for a global function. static void ProcessAPINotes(Sema &S, FunctionDecl *D, const api_notes::GlobalFunctionInfo &Info, @@ -776,6 +783,64 @@ static void ProcessVersionedAPINotes( } } +static std::optional +UnwindNamespaceContext(DeclContext *DC, api_notes::APINotesManager &APINotes) { + if (auto NamespaceContext = dyn_cast(DC)) { + for (auto Reader : APINotes.findAPINotes(NamespaceContext->getLocation())) { + // Retrieve the context ID for the parent namespace of the decl. + std::stack NamespaceStack; + { + for (auto CurrentNamespace = NamespaceContext; CurrentNamespace; + CurrentNamespace = + dyn_cast(CurrentNamespace->getParent())) { + if (!CurrentNamespace->isInlineNamespace()) + NamespaceStack.push(CurrentNamespace); + } + } + std::optional NamespaceID; + while (!NamespaceStack.empty()) { + auto CurrentNamespace = NamespaceStack.top(); + NamespaceStack.pop(); + NamespaceID = + Reader->lookupNamespaceID(CurrentNamespace->getName(), NamespaceID); + if (!NamespaceID) + return std::nullopt; + } + if (NamespaceID) + return api_notes::Context(*NamespaceID, + api_notes::ContextKind::Namespace); + } + } + return std::nullopt; +} + +static std::optional +UnwindTagContext(TagDecl *DC, api_notes::APINotesManager &APINotes) { + assert(DC && "tag context must not be null"); + for (auto Reader : APINotes.findAPINotes(DC->getLocation())) { + // Retrieve the context ID for the parent tag of the decl. + std::stack TagStack; + { + for (auto CurrentTag = DC; CurrentTag; + CurrentTag = dyn_cast(CurrentTag->getParent())) + TagStack.push(CurrentTag); + } + assert(!TagStack.empty()); + std::optional Ctx = + UnwindNamespaceContext(TagStack.top()->getDeclContext(), APINotes); + while (!TagStack.empty()) { + auto CurrentTag = TagStack.top(); + TagStack.pop(); + auto CtxID = Reader->lookupTagID(CurrentTag->getName(), Ctx); + if (!CtxID) + return std::nullopt; + Ctx = api_notes::Context(*CtxID, api_notes::ContextKind::Tag); + } + return Ctx; + } + return std::nullopt; +} + /// Process API notes that are associated with this declaration, mapping them /// to attributes as appropriate. void Sema::ProcessAPINotes(Decl *D) { @@ -787,35 +852,8 @@ void Sema::ProcessAPINotes(Decl *D) { D->getDeclContext()->isNamespace() || D->getDeclContext()->isExternCContext() || D->getDeclContext()->isExternCXXContext()) { - std::optional APINotesContext; - if (auto NamespaceContext = dyn_cast(D->getDeclContext())) { - for (auto Reader : - APINotes.findAPINotes(NamespaceContext->getLocation())) { - // Retrieve the context ID for the parent namespace of the decl. - std::stack NamespaceStack; - { - for (auto CurrentNamespace = NamespaceContext; CurrentNamespace; - CurrentNamespace = - dyn_cast(CurrentNamespace->getParent())) { - if (!CurrentNamespace->isInlineNamespace()) - NamespaceStack.push(CurrentNamespace); - } - } - std::optional NamespaceID; - while (!NamespaceStack.empty()) { - auto CurrentNamespace = NamespaceStack.top(); - NamespaceStack.pop(); - NamespaceID = Reader->lookupNamespaceID(CurrentNamespace->getName(), - NamespaceID); - if (!NamespaceID) - break; - } - if (NamespaceID) - APINotesContext = api_notes::Context( - *NamespaceID, api_notes::ContextKind::Namespace); - } - } - + std::optional APINotesContext = + UnwindNamespaceContext(D->getDeclContext(), APINotes); // Global variables. if (auto VD = dyn_cast(D)) { for (auto Reader : APINotes.findAPINotes(D->getLocation())) { @@ -887,6 +925,8 @@ void Sema::ProcessAPINotes(Decl *D) { } for (auto Reader : APINotes.findAPINotes(D->getLocation())) { + if (auto ParentTag = dyn_cast(Tag->getDeclContext())) + APINotesContext = UnwindTagContext(ParentTag, APINotes); auto Info = Reader->lookupTag(LookupName, APINotesContext); ProcessVersionedAPINotes(*this, Tag, Info); } @@ -1001,4 +1041,30 @@ void Sema::ProcessAPINotes(Decl *D) { return; } } + + if (auto TagContext = dyn_cast(D->getDeclContext())) { + if (auto CXXMethod = dyn_cast(D)) { + if (!isa(CXXMethod) && + !isa(CXXMethod) && + !isa(CXXMethod) && + !CXXMethod->isOverloadedOperator()) { + for (auto Reader : APINotes.findAPINotes(D->getLocation())) { + if (auto Context = UnwindTagContext(TagContext, APINotes)) { + auto Info = + Reader->lookupCXXMethod(Context->id, CXXMethod->getName()); + ProcessVersionedAPINotes(*this, CXXMethod, Info); + } + } + } + } + + if (auto Tag = dyn_cast(D)) { + for (auto Reader : APINotes.findAPINotes(D->getLocation())) { + if (auto Context = UnwindTagContext(TagContext, APINotes)) { + auto Info = Reader->lookupTag(Tag->getName(), Context); + ProcessVersionedAPINotes(*this, Tag, Info); + } + } + } + } } diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index aaabd989c5c9f..b0c239678d0b0 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -117,7 +117,7 @@ void Sema::inferGslPointerAttribute(NamedDecl *ND, if (!Parent) return; - static llvm::StringSet<> Containers{ + static const llvm::StringSet<> Containers{ "array", "basic_string", "deque", @@ -137,9 +137,9 @@ void Sema::inferGslPointerAttribute(NamedDecl *ND, "unordered_multimap", }; - static llvm::StringSet<> Iterators{"iterator", "const_iterator", - "reverse_iterator", - "const_reverse_iterator"}; + static const llvm::StringSet<> Iterators{"iterator", "const_iterator", + "reverse_iterator", + "const_reverse_iterator"}; if (Parent->isInStdNamespace() && Iterators.count(ND->getName()) && Containers.count(Parent->getName())) @@ -165,7 +165,7 @@ void Sema::inferGslPointerAttribute(TypedefNameDecl *TD) { } void Sema::inferGslOwnerPointerAttribute(CXXRecordDecl *Record) { - static llvm::StringSet<> StdOwners{ + static const llvm::StringSet<> StdOwners{ "any", "array", "basic_regex", @@ -189,10 +189,11 @@ void Sema::inferGslOwnerPointerAttribute(CXXRecordDecl *Record) { "unordered_multimap", "variant", }; - static llvm::StringSet<> StdPointers{ + static const llvm::StringSet<> StdPointers{ "basic_string_view", "reference_wrapper", "regex_iterator", + "span", }; if (!Record->getIdentifier()) @@ -216,7 +217,7 @@ void Sema::inferGslOwnerPointerAttribute(CXXRecordDecl *Record) { } void Sema::inferNullableClassAttribute(CXXRecordDecl *CRD) { - static llvm::StringSet<> Nullable{ + static const llvm::StringSet<> Nullable{ "auto_ptr", "shared_ptr", "unique_ptr", "exception_ptr", "coroutine_handle", "function", "move_only_function", }; diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp index b677a1f170cd1..dd98ab1a7f3f9 100644 --- a/clang/lib/Sema/SemaAvailability.cpp +++ b/clang/lib/Sema/SemaAvailability.cpp @@ -107,6 +107,12 @@ ShouldDiagnoseAvailabilityOfDecl(Sema &S, const NamedDecl *D, break; } + // For alias templates, get the underlying declaration. + if (const auto *ADecl = dyn_cast(D)) { + D = ADecl->getTemplatedDecl(); + Result = D->getAvailability(Message); + } + // Forward class declarations get their attributes from their definition. if (const auto *IDecl = dyn_cast(D)) { if (IDecl->getDefinition()) { diff --git a/clang/lib/Sema/SemaBoundsSafety.cpp b/clang/lib/Sema/SemaBoundsSafety.cpp new file mode 100644 index 0000000000000..290c820938898 --- /dev/null +++ b/clang/lib/Sema/SemaBoundsSafety.cpp @@ -0,0 +1,193 @@ +//===-- SemaBoundsSafety.cpp - Bounds Safety specific routines-*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares semantic analysis functions specific to `-fbounds-safety` +/// (Bounds Safety) and also its attributes when used without `-fbounds-safety` +/// (e.g. `counted_by`) +/// +//===----------------------------------------------------------------------===// +#include "clang/Sema/Sema.h" + +namespace clang { + +static CountAttributedType::DynamicCountPointerKind +getCountAttrKind(bool CountInBytes, bool OrNull) { + if (CountInBytes) + return OrNull ? CountAttributedType::SizedByOrNull + : CountAttributedType::SizedBy; + return OrNull ? CountAttributedType::CountedByOrNull + : CountAttributedType::CountedBy; +} + +static const RecordDecl *GetEnclosingNamedOrTopAnonRecord(const FieldDecl *FD) { + const auto *RD = FD->getParent(); + // An unnamed struct is anonymous struct only if it's not instantiated. + // However, the struct may not be fully processed yet to determine + // whether it's anonymous or not. In that case, this function treats it as + // an anonymous struct and tries to find a named parent. + while (RD && (RD->isAnonymousStructOrUnion() || + (!RD->isCompleteDefinition() && RD->getName().empty()))) { + const auto *Parent = dyn_cast(RD->getParent()); + if (!Parent) + break; + RD = Parent; + } + return RD; +} + +enum class CountedByInvalidPointeeTypeKind { + INCOMPLETE, + SIZELESS, + FUNCTION, + FLEXIBLE_ARRAY_MEMBER, + VALID, +}; + +bool Sema::CheckCountedByAttrOnField( + FieldDecl *FD, Expr *E, + llvm::SmallVectorImpl &Decls, bool CountInBytes, + bool OrNull) { + // Check the context the attribute is used in + + unsigned Kind = getCountAttrKind(CountInBytes, OrNull); + + if (FD->getParent()->isUnion()) { + Diag(FD->getBeginLoc(), diag::err_count_attr_in_union) + << Kind << FD->getSourceRange(); + return true; + } + + const auto FieldTy = FD->getType(); + if (FieldTy->isArrayType() && (CountInBytes || OrNull)) { + Diag(FD->getBeginLoc(), + diag::err_count_attr_not_on_ptr_or_flexible_array_member) + << Kind << FD->getLocation() << /* suggest counted_by */ 1; + return true; + } + if (!FieldTy->isArrayType() && !FieldTy->isPointerType()) { + Diag(FD->getBeginLoc(), + diag::err_count_attr_not_on_ptr_or_flexible_array_member) + << Kind << FD->getLocation() << /* do not suggest counted_by */ 0; + return true; + } + + LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel = + LangOptions::StrictFlexArraysLevelKind::IncompleteOnly; + if (FieldTy->isArrayType() && + !Decl::isFlexibleArrayMemberLike(getASTContext(), FD, FieldTy, + StrictFlexArraysLevel, true)) { + Diag(FD->getBeginLoc(), + diag::err_counted_by_attr_on_array_not_flexible_array_member) + << Kind << FD->getLocation(); + return true; + } + + CountedByInvalidPointeeTypeKind InvalidTypeKind = + CountedByInvalidPointeeTypeKind::VALID; + QualType PointeeTy; + int SelectPtrOrArr = 0; + if (FieldTy->isPointerType()) { + PointeeTy = FieldTy->getPointeeType(); + SelectPtrOrArr = 0; + } else { + assert(FieldTy->isArrayType()); + const ArrayType *AT = getASTContext().getAsArrayType(FieldTy); + PointeeTy = AT->getElementType(); + SelectPtrOrArr = 1; + } + // Note: The `Decl::isFlexibleArrayMemberLike` check earlier on means + // only `PointeeTy->isStructureTypeWithFlexibleArrayMember()` is reachable + // when `FieldTy->isArrayType()`. + bool ShouldWarn = false; + if (PointeeTy->isIncompleteType() && !CountInBytes) { + InvalidTypeKind = CountedByInvalidPointeeTypeKind::INCOMPLETE; + } else if (PointeeTy->isSizelessType()) { + InvalidTypeKind = CountedByInvalidPointeeTypeKind::SIZELESS; + } else if (PointeeTy->isFunctionType()) { + InvalidTypeKind = CountedByInvalidPointeeTypeKind::FUNCTION; + } else if (PointeeTy->isStructureTypeWithFlexibleArrayMember()) { + if (FieldTy->isArrayType() && !getLangOpts().BoundsSafety) { + // This is a workaround for the Linux kernel that has already adopted + // `counted_by` on a FAM where the pointee is a struct with a FAM. This + // should be an error because computing the bounds of the array cannot be + // done correctly without manually traversing every struct object in the + // array at runtime. To allow the code to be built this error is + // downgraded to a warning. + ShouldWarn = true; + } + InvalidTypeKind = CountedByInvalidPointeeTypeKind::FLEXIBLE_ARRAY_MEMBER; + } + + if (InvalidTypeKind != CountedByInvalidPointeeTypeKind::VALID) { + unsigned DiagID = ShouldWarn + ? diag::warn_counted_by_attr_elt_type_unknown_size + : diag::err_counted_by_attr_pointee_unknown_size; + Diag(FD->getBeginLoc(), DiagID) + << SelectPtrOrArr << PointeeTy << (int)InvalidTypeKind + << (ShouldWarn ? 1 : 0) << Kind << FD->getSourceRange(); + return true; + } + + // Check the expression + + if (!E->getType()->isIntegerType() || E->getType()->isBooleanType()) { + Diag(E->getBeginLoc(), diag::err_count_attr_argument_not_integer) + << Kind << E->getSourceRange(); + return true; + } + + auto *DRE = dyn_cast(E); + if (!DRE) { + Diag(E->getBeginLoc(), + diag::err_count_attr_only_support_simple_decl_reference) + << Kind << E->getSourceRange(); + return true; + } + + auto *CountDecl = DRE->getDecl(); + FieldDecl *CountFD = dyn_cast(CountDecl); + if (auto *IFD = dyn_cast(CountDecl)) { + CountFD = IFD->getAnonField(); + } + if (!CountFD) { + Diag(E->getBeginLoc(), diag::err_count_attr_must_be_in_structure) + << CountDecl << Kind << E->getSourceRange(); + + Diag(CountDecl->getBeginLoc(), + diag::note_flexible_array_counted_by_attr_field) + << CountDecl << CountDecl->getSourceRange(); + return true; + } + + if (FD->getParent() != CountFD->getParent()) { + if (CountFD->getParent()->isUnion()) { + Diag(CountFD->getBeginLoc(), diag::err_count_attr_refer_to_union) + << Kind << CountFD->getSourceRange(); + return true; + } + // Whether CountRD is an anonymous struct is not determined at this + // point. Thus, an additional diagnostic in case it's not anonymous struct + // is done later in `Parser::ParseStructDeclaration`. + auto *RD = GetEnclosingNamedOrTopAnonRecord(FD); + auto *CountRD = GetEnclosingNamedOrTopAnonRecord(CountFD); + + if (RD != CountRD) { + Diag(E->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct) + << CountFD << Kind << FieldTy->isArrayType() << E->getSourceRange(); + Diag(CountFD->getBeginLoc(), + diag::note_flexible_array_counted_by_attr_field) + << CountFD << CountFD->getSourceRange(); + return true; + } + } + + Decls.push_back(TypeCoupledDeclRefInfo(CountFD, /*IsDref*/ false)); + return false; +} + +} // namespace clang diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index e4df5848ff132..a2842343be968 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1481,6 +1481,18 @@ static bool BuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, return false; } +// In OpenCL, __builtin_alloca_* should return a pointer to address space +// that corresponds to the stack address space i.e private address space. +static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall) { + QualType RT = TheCall->getType(); + assert((RT->isPointerType() && !(RT->getPointeeType().hasAddressSpace())) && + "__builtin_alloca has invalid address space"); + + RT = RT->getPointeeType(); + RT = S.Context.getAddrSpaceQualType(RT, LangAS::opencl_private); + TheCall->setType(S.Context.getPointerType(RT)); +} + namespace { enum PointerAuthOpKind { PAO_Strip, @@ -1493,14 +1505,18 @@ enum PointerAuthOpKind { }; } -static bool checkPointerAuthEnabled(Sema &S, Expr *E) { - if (S.getLangOpts().PointerAuthIntrinsics) +bool Sema::checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range) { + if (getLangOpts().PointerAuthIntrinsics) return false; - S.Diag(E->getExprLoc(), diag::err_ptrauth_disabled) << E->getSourceRange(); + Diag(Loc, diag::err_ptrauth_disabled) << Range; return true; } +static bool checkPointerAuthEnabled(Sema &S, Expr *E) { + return S.checkPointerAuthEnabled(E->getExprLoc(), E->getSourceRange()); +} + static bool checkPointerAuthKey(Sema &S, Expr *&Arg) { // Convert it to type 'int'. if (convertArgumentToType(S, Arg, S.Context.IntTy)) @@ -2214,6 +2230,9 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, case Builtin::BI__builtin_alloca_uninitialized: Diag(TheCall->getBeginLoc(), diag::warn_alloca) << TheCall->getDirectCallee(); + if (getLangOpts().OpenCL) { + builtinAllocaAddrSpace(*this, TheCall); + } break; case Builtin::BI__arithmetic_fence: if (BuiltinArithmeticFence(TheCall)) @@ -6400,7 +6419,7 @@ static const Expr *maybeConstEvalStringLiteral(ASTContext &Context, Sema::FormatStringType Sema::GetFormatStringType(const FormatAttr *Format) { return llvm::StringSwitch(Format->getType()->getName()) .Case("scanf", FST_Scanf) - .Cases("printf", "printf0", FST_Printf) + .Cases("printf", "printf0", "syslog", FST_Printf) .Cases("NSString", "CFString", FST_NSString) .Case("strftime", FST_Strftime) .Case("strfmon", FST_Strfmon) @@ -6494,6 +6513,7 @@ bool Sema::CheckFormatArguments(ArrayRef Args, case FST_Kprintf: case FST_FreeBSDKPrintf: case FST_Printf: + case FST_Syslog: Diag(FormatLoc, diag::note_format_security_fixit) << FixItHint::CreateInsertion(FormatLoc, "\"%s\", "); break; @@ -8230,7 +8250,7 @@ static void CheckFormatString( if (Type == Sema::FST_Printf || Type == Sema::FST_NSString || Type == Sema::FST_FreeBSDKPrintf || Type == Sema::FST_OSLog || - Type == Sema::FST_OSTrace) { + Type == Sema::FST_OSTrace || Type == Sema::FST_Syslog) { CheckPrintfHandler H( S, FExpr, OrigFormatExpr, Type, firstDataArg, numDataArgs, (Type == Sema::FST_NSString || Type == Sema::FST_OSTrace), Str, APK, @@ -8572,20 +8592,46 @@ static bool IsStdFunction(const FunctionDecl *FDecl, return true; } +enum class MathCheck { NaN, Inf }; +static bool IsInfOrNanFunction(StringRef calleeName, MathCheck Check) { + auto MatchesAny = [&](std::initializer_list names) { + return std::any_of(names.begin(), names.end(), [&](llvm::StringRef name) { + return calleeName == name; + }); + }; + + switch (Check) { + case MathCheck::NaN: + return MatchesAny({"__builtin_nan", "__builtin_nanf", "__builtin_nanl", + "__builtin_nanf16", "__builtin_nanf128"}); + case MathCheck::Inf: + return MatchesAny({"__builtin_inf", "__builtin_inff", "__builtin_infl", + "__builtin_inff16", "__builtin_inff128"}); + } + llvm_unreachable("unknown MathCheck"); +} + void Sema::CheckInfNaNFunction(const CallExpr *Call, const FunctionDecl *FDecl) { FPOptions FPO = Call->getFPFeaturesInEffect(getLangOpts()); - if ((IsStdFunction(FDecl, "isnan") || IsStdFunction(FDecl, "isunordered") || - (Call->getBuiltinCallee() == Builtin::BI__builtin_nanf)) && - FPO.getNoHonorNaNs()) + bool HasIdentifier = FDecl->getIdentifier() != nullptr; + bool IsNaNOrIsUnordered = + IsStdFunction(FDecl, "isnan") || IsStdFunction(FDecl, "isunordered"); + bool IsSpecialNaN = + HasIdentifier && IsInfOrNanFunction(FDecl->getName(), MathCheck::NaN); + if ((IsNaNOrIsUnordered || IsSpecialNaN) && FPO.getNoHonorNaNs()) { Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) << 1 << 0 << Call->getSourceRange(); - else if ((IsStdFunction(FDecl, "isinf") || - (IsStdFunction(FDecl, "isfinite") || - (FDecl->getIdentifier() && FDecl->getName() == "infinity"))) && - FPO.getNoHonorInfs()) - Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) - << 0 << 0 << Call->getSourceRange(); + } else { + bool IsInfOrIsFinite = + IsStdFunction(FDecl, "isinf") || IsStdFunction(FDecl, "isfinite"); + bool IsInfinityOrIsSpecialInf = + HasIdentifier && ((FDecl->getName() == "infinity") || + IsInfOrNanFunction(FDecl->getName(), MathCheck::Inf)); + if ((IsInfOrIsFinite || IsInfinityOrIsSpecialInf) && FPO.getNoHonorInfs()) + Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) + << 0 << 0 << Call->getSourceRange(); + } } void Sema::CheckAbsoluteValueFunction(const CallExpr *Call, @@ -14050,10 +14096,11 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, //===--- Layout compatibility ----------------------------------------------// -static bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2); +static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2); /// Check if two enumeration types are layout-compatible. -static bool isLayoutCompatible(ASTContext &C, EnumDecl *ED1, EnumDecl *ED2) { +static bool isLayoutCompatible(const ASTContext &C, const EnumDecl *ED1, + const EnumDecl *ED2) { // C++11 [dcl.enum] p8: // Two enumeration types are layout-compatible if they have the same // underlying type. @@ -14064,8 +14111,8 @@ static bool isLayoutCompatible(ASTContext &C, EnumDecl *ED1, EnumDecl *ED2) { /// Check if two fields are layout-compatible. /// Can be used on union members, which are exempt from alignment requirement /// of common initial sequence. -static bool isLayoutCompatible(ASTContext &C, FieldDecl *Field1, - FieldDecl *Field2, +static bool isLayoutCompatible(const ASTContext &C, const FieldDecl *Field1, + const FieldDecl *Field2, bool AreUnionMembers = false) { [[maybe_unused]] const Type *Field1Parent = Field1->getParent()->getTypeForDecl(); @@ -14108,60 +14155,33 @@ static bool isLayoutCompatible(ASTContext &C, FieldDecl *Field1, /// Check if two standard-layout structs are layout-compatible. /// (C++11 [class.mem] p17) -static bool isLayoutCompatibleStruct(ASTContext &C, RecordDecl *RD1, - RecordDecl *RD2) { - // If both records are C++ classes, check that base classes match. - if (const CXXRecordDecl *D1CXX = dyn_cast(RD1)) { - // If one of records is a CXXRecordDecl we are in C++ mode, - // thus the other one is a CXXRecordDecl, too. - const CXXRecordDecl *D2CXX = cast(RD2); - // Check number of base classes. - if (D1CXX->getNumBases() != D2CXX->getNumBases()) - return false; +static bool isLayoutCompatibleStruct(const ASTContext &C, const RecordDecl *RD1, + const RecordDecl *RD2) { + // Get to the class where the fields are declared + if (const CXXRecordDecl *D1CXX = dyn_cast(RD1)) + RD1 = D1CXX->getStandardLayoutBaseWithFields(); - // Check the base classes. - for (CXXRecordDecl::base_class_const_iterator - Base1 = D1CXX->bases_begin(), - BaseEnd1 = D1CXX->bases_end(), - Base2 = D2CXX->bases_begin(); - Base1 != BaseEnd1; - ++Base1, ++Base2) { - if (!isLayoutCompatible(C, Base1->getType(), Base2->getType())) - return false; - } - } else if (const CXXRecordDecl *D2CXX = dyn_cast(RD2)) { - // If only RD2 is a C++ class, it should have zero base classes. - if (D2CXX->getNumBases() > 0) - return false; - } + if (const CXXRecordDecl *D2CXX = dyn_cast(RD2)) + RD2 = D2CXX->getStandardLayoutBaseWithFields(); // Check the fields. - RecordDecl::field_iterator Field2 = RD2->field_begin(), - Field2End = RD2->field_end(), - Field1 = RD1->field_begin(), - Field1End = RD1->field_end(); - for ( ; Field1 != Field1End && Field2 != Field2End; ++Field1, ++Field2) { - if (!isLayoutCompatible(C, *Field1, *Field2)) - return false; - } - if (Field1 != Field1End || Field2 != Field2End) - return false; - - return true; + return llvm::equal(RD1->fields(), RD2->fields(), + [&C](const FieldDecl *F1, const FieldDecl *F2) -> bool { + return isLayoutCompatible(C, F1, F2); + }); } /// Check if two standard-layout unions are layout-compatible. /// (C++11 [class.mem] p18) -static bool isLayoutCompatibleUnion(ASTContext &C, RecordDecl *RD1, - RecordDecl *RD2) { - llvm::SmallPtrSet UnmatchedFields; +static bool isLayoutCompatibleUnion(const ASTContext &C, const RecordDecl *RD1, + const RecordDecl *RD2) { + llvm::SmallPtrSet UnmatchedFields; for (auto *Field2 : RD2->fields()) UnmatchedFields.insert(Field2); for (auto *Field1 : RD1->fields()) { - llvm::SmallPtrSet::iterator - I = UnmatchedFields.begin(), - E = UnmatchedFields.end(); + auto I = UnmatchedFields.begin(); + auto E = UnmatchedFields.end(); for ( ; I != E; ++I) { if (isLayoutCompatible(C, Field1, *I, /*IsUnionMember=*/true)) { @@ -14178,8 +14198,8 @@ static bool isLayoutCompatibleUnion(ASTContext &C, RecordDecl *RD1, return UnmatchedFields.empty(); } -static bool isLayoutCompatible(ASTContext &C, RecordDecl *RD1, - RecordDecl *RD2) { +static bool isLayoutCompatible(const ASTContext &C, const RecordDecl *RD1, + const RecordDecl *RD2) { if (RD1->isUnion() != RD2->isUnion()) return false; @@ -14190,7 +14210,7 @@ static bool isLayoutCompatible(ASTContext &C, RecordDecl *RD1, } /// Check if two types are layout-compatible in C++11 sense. -static bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2) { +static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2) { if (T1.isNull() || T2.isNull()) return false; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index a315ad3373b48..44aedb416e670 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -5946,7 +5946,7 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) { static QualType getCoreType(QualType Ty) { do { - if (Ty->isPointerType() || Ty->isReferenceType()) + if (Ty->isPointerOrReferenceType()) Ty = Ty->getPointeeType(); else if (Ty->isArrayType()) Ty = Ty->castAsArrayTypeUnsafe()->getElementType(); @@ -6949,6 +6949,11 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { } } + if (HybridPatchableAttr *Attr = ND.getAttr()) { + if (!ND.isExternallyVisible()) + S.Diag(Attr->getLocation(), + diag::warn_attribute_hybrid_patchable_non_extern); + } if (const InheritableAttr *Attr = getDLLAttr(&ND)) { auto *VD = dyn_cast(&ND); bool IsAnonymousNS = false; @@ -7495,10 +7500,10 @@ NamedDecl *Sema::ActOnVariableDeclarator( tryToFixVariablyModifiedVarType(TInfo, R, D.getIdentifierLoc(), /*DiagID=*/0); - if (const AutoType *AutoT = R->getAs()) - CheckConstrainedAuto( - AutoT, - TInfo->getTypeLoc().getContainedAutoTypeLoc().getConceptNameLoc()); + if (AutoTypeLoc TL = TInfo->getTypeLoc().getContainedAutoTypeLoc()) { + const AutoType *AT = TL.getTypePtr(); + CheckConstrainedAuto(AT, TL.getConceptNameLoc()); + } bool IsMemberSpecialization = false; bool IsVariableTemplateSpecialization = false; @@ -9437,7 +9442,7 @@ static OpenCLParamType getOpenCLKernelParameterType(Sema &S, QualType PT) { if (PT->isDependentType()) return InvalidKernelParam; - if (PT->isPointerType() || PT->isReferenceType()) { + if (PT->isPointerOrReferenceType()) { QualType PointeeType = PT->getPointeeType(); if (PointeeType.getAddressSpace() == LangAS::opencl_generic || PointeeType.getAddressSpace() == LangAS::opencl_private || @@ -10882,11 +10887,15 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, for (const ParmVarDecl *Param : NewFD->parameters()) { QualType PT = Param->getType(); - if (const PipeType *PipeTy = PT->getAs()) { - QualType ElemTy = PipeTy->getElementType(); - if (ElemTy->isReferenceType() || ElemTy->isPointerType()) { - Diag(Param->getTypeSpecStartLoc(), diag::err_reference_pipe_type ); - D.setInvalidType(); + // OpenCL 2.0 pipe restrictions forbids pipe packet types to be non-value + // types. + if (getLangOpts().getOpenCLCompatibleVersion() >= 200) { + if(const PipeType *PipeTy = PT->getAs()) { + QualType ElemTy = PipeTy->getElementType(); + if (ElemTy->isPointerOrReferenceType()) { + Diag(Param->getTypeSpecStartLoc(), diag::err_reference_pipe_type); + D.setInvalidType(); + } } } // WebAssembly tables can't be used as function parameters. @@ -11108,6 +11117,9 @@ static bool AttrCompatibleWithMultiVersion(attr::Kind Kind, switch (Kind) { default: return false; + case attr::ArmLocallyStreaming: + return MVKind == MultiVersionKind::TargetVersion || + MVKind == MultiVersionKind::TargetClones; case attr::Used: return MVKind == MultiVersionKind::Target; case attr::NonNull: @@ -11244,7 +11256,21 @@ bool Sema::areMultiversionVariantFunctionsCompatible( FunctionType::ExtInfo OldTypeInfo = OldType->getExtInfo(); FunctionType::ExtInfo NewTypeInfo = NewType->getExtInfo(); - if (OldTypeInfo.getCC() != NewTypeInfo.getCC()) + const auto *OldFPT = OldFD->getType()->getAs(); + const auto *NewFPT = NewFD->getType()->getAs(); + + bool ArmStreamingCCMismatched = false; + if (OldFPT && NewFPT) { + unsigned Diff = + OldFPT->getAArch64SMEAttributes() ^ NewFPT->getAArch64SMEAttributes(); + // Arm-streaming, arm-streaming-compatible and non-streaming versions + // cannot be mixed. + if (Diff & (FunctionType::SME_PStateSMEnabledMask | + FunctionType::SME_PStateSMCompatibleMask)) + ArmStreamingCCMismatched = true; + } + + if (OldTypeInfo.getCC() != NewTypeInfo.getCC() || ArmStreamingCCMismatched) return Diag(DiffDiagIDAt.first, DiffDiagIDAt.second) << CallingConv; QualType OldReturnType = OldType->getReturnType(); @@ -11264,9 +11290,8 @@ bool Sema::areMultiversionVariantFunctionsCompatible( if (!CLinkageMayDiffer && OldFD->isExternC() != NewFD->isExternC()) return Diag(DiffDiagIDAt.first, DiffDiagIDAt.second) << LanguageLinkage; - if (CheckEquivalentExceptionSpec( - OldFD->getType()->getAs(), OldFD->getLocation(), - NewFD->getType()->getAs(), NewFD->getLocation())) + if (CheckEquivalentExceptionSpec(OldFPT, OldFD->getLocation(), NewFPT, + NewFD->getLocation())) return true; } return false; @@ -20287,8 +20312,10 @@ Sema::FunctionEmissionStatus Sema::getEmissionStatus(const FunctionDecl *FD, // be emitted, because (say) the definition could include "inline". const FunctionDecl *Def = FD->getDefinition(); - return Def && !isDiscardableGVALinkage( - getASTContext().GetGVALinkageForFunction(Def)); + // We can't compute linkage when we skip function bodies. + return Def && !Def->hasSkippedBody() && + !isDiscardableGVALinkage( + getASTContext().GetGVALinkageForFunction(Def)); }; if (LangOpts.OpenMPIsTargetDevice) { diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 8e120b8c43510..b29346b7b33d4 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1527,6 +1527,14 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) { break; } + // Allow only pointers to be return type for functions with ownership_returns + // attribute. This matches with current OwnershipAttr::Takes semantics + if (K == OwnershipAttr::Returns && + !getFunctionOrMethodResultType(D)->isPointerType()) { + S.Diag(AL.getLoc(), diag::err_ownership_takes_return_type) << AL; + return; + } + IdentifierInfo *Module = AL.getArgAsIdent(0)->Ident; StringRef ModuleName = Module->getName(); @@ -1583,6 +1591,16 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) { << Idx.getSourceIndex() << Ex->getSourceRange(); return; } + } else if (K == OwnershipAttr::Takes && + I->getOwnKind() == OwnershipAttr::Takes) { + if (I->getModule()->getName() != ModuleName) { + S.Diag(I->getLocation(), diag::err_ownership_takes_class_mismatch) + << I->getModule()->getName(); + S.Diag(AL.getLoc(), diag::note_ownership_takes_class_mismatch) + << ModuleName << Ex->getSourceRange(); + + return; + } } } OwnershipArgs.push_back(Idx); @@ -3083,9 +3101,6 @@ bool Sema::checkTargetVersionAttr(SourceLocation LiteralLoc, Decl *D, return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) << Unsupported << None << CurFeature << TargetVersion; } - if (IsArmStreamingFunction(cast(D), - /*IncludeLocallyStreaming=*/false)) - return Diag(LiteralLoc, diag::err_sme_streaming_cannot_be_multiversioned); return false; } @@ -3182,10 +3197,6 @@ bool Sema::checkTargetClonesAttrString( HasNotDefault = true; } } - if (IsArmStreamingFunction(cast(D), - /*IncludeLocallyStreaming=*/false)) - return Diag(LiteralLoc, - diag::err_sme_streaming_cannot_be_multiversioned); } else { // Other targets ( currently X86 ) if (Cur.starts_with("arch=")) { @@ -3458,8 +3469,8 @@ static FormatAttrKind getFormatAttrKind(StringRef Format) { // Otherwise, check for supported formats. .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat) .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat) - .Case("kprintf", SupportedFormat) // OpenBSD. - .Case("freebsd_kprintf", SupportedFormat) // FreeBSD. + .Cases("kprintf", "syslog", SupportedFormat) // OpenBSD. + .Case("freebsd_kprintf", SupportedFormat) // FreeBSD. .Case("os_trace", SupportedFormat) .Case("os_log", SupportedFormat) @@ -5300,6 +5311,10 @@ static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) { static void handlePatchableFunctionEntryAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + if (S.Context.getTargetInfo().getTriple().isOSAIX()) { + S.Diag(AL.getLoc(), diag::err_aix_attr_unsupported) << AL; + return; + } uint32_t Count = 0, Offset = 0; if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), Count, 0, true)) return; @@ -5913,181 +5928,6 @@ static void handleZeroCallUsedRegsAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(ZeroCallUsedRegsAttr::Create(S.Context, Kind, AL)); } -static const RecordDecl *GetEnclosingNamedOrTopAnonRecord(const FieldDecl *FD) { - const auto *RD = FD->getParent(); - // An unnamed struct is anonymous struct only if it's not instantiated. - // However, the struct may not be fully processed yet to determine - // whether it's anonymous or not. In that case, this function treats it as - // an anonymous struct and tries to find a named parent. - while (RD && (RD->isAnonymousStructOrUnion() || - (!RD->isCompleteDefinition() && RD->getName().empty()))) { - const auto *Parent = dyn_cast(RD->getParent()); - if (!Parent) - break; - RD = Parent; - } - return RD; -} - -static CountAttributedType::DynamicCountPointerKind -getCountAttrKind(bool CountInBytes, bool OrNull) { - if (CountInBytes) - return OrNull ? CountAttributedType::SizedByOrNull - : CountAttributedType::SizedBy; - return OrNull ? CountAttributedType::CountedByOrNull - : CountAttributedType::CountedBy; -} - -enum class CountedByInvalidPointeeTypeKind { - INCOMPLETE, - SIZELESS, - FUNCTION, - FLEXIBLE_ARRAY_MEMBER, - VALID, -}; - -static bool -CheckCountedByAttrOnField(Sema &S, FieldDecl *FD, Expr *E, - llvm::SmallVectorImpl &Decls, - bool CountInBytes, bool OrNull) { - // Check the context the attribute is used in - - unsigned Kind = getCountAttrKind(CountInBytes, OrNull); - - if (FD->getParent()->isUnion()) { - S.Diag(FD->getBeginLoc(), diag::err_count_attr_in_union) - << Kind << FD->getSourceRange(); - return true; - } - - const auto FieldTy = FD->getType(); - if (FieldTy->isArrayType() && (CountInBytes || OrNull)) { - S.Diag(FD->getBeginLoc(), - diag::err_count_attr_not_on_ptr_or_flexible_array_member) - << Kind << FD->getLocation() << /* suggest counted_by */ 1; - return true; - } - if (!FieldTy->isArrayType() && !FieldTy->isPointerType()) { - S.Diag(FD->getBeginLoc(), - diag::err_count_attr_not_on_ptr_or_flexible_array_member) - << Kind << FD->getLocation() << /* do not suggest counted_by */ 0; - return true; - } - - LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel = - LangOptions::StrictFlexArraysLevelKind::IncompleteOnly; - if (FieldTy->isArrayType() && - !Decl::isFlexibleArrayMemberLike(S.getASTContext(), FD, FieldTy, - StrictFlexArraysLevel, true)) { - S.Diag(FD->getBeginLoc(), - diag::err_counted_by_attr_on_array_not_flexible_array_member) - << Kind << FD->getLocation(); - return true; - } - - CountedByInvalidPointeeTypeKind InvalidTypeKind = - CountedByInvalidPointeeTypeKind::VALID; - QualType PointeeTy; - int SelectPtrOrArr = 0; - if (FieldTy->isPointerType()) { - PointeeTy = FieldTy->getPointeeType(); - SelectPtrOrArr = 0; - } else { - assert(FieldTy->isArrayType()); - const ArrayType *AT = S.getASTContext().getAsArrayType(FieldTy); - PointeeTy = AT->getElementType(); - SelectPtrOrArr = 1; - } - // Note: The `Decl::isFlexibleArrayMemberLike` check earlier on means - // only `PointeeTy->isStructureTypeWithFlexibleArrayMember()` is reachable - // when `FieldTy->isArrayType()`. - bool ShouldWarn = false; - if (PointeeTy->isIncompleteType() && !CountInBytes) { - InvalidTypeKind = CountedByInvalidPointeeTypeKind::INCOMPLETE; - } else if (PointeeTy->isSizelessType()) { - InvalidTypeKind = CountedByInvalidPointeeTypeKind::SIZELESS; - } else if (PointeeTy->isFunctionType()) { - InvalidTypeKind = CountedByInvalidPointeeTypeKind::FUNCTION; - } else if (PointeeTy->isStructureTypeWithFlexibleArrayMember()) { - if (FieldTy->isArrayType()) { - // This is a workaround for the Linux kernel that has already adopted - // `counted_by` on a FAM where the pointee is a struct with a FAM. This - // should be an error because computing the bounds of the array cannot be - // done correctly without manually traversing every struct object in the - // array at runtime. To allow the code to be built this error is - // downgraded to a warning. - ShouldWarn = true; - } - InvalidTypeKind = CountedByInvalidPointeeTypeKind::FLEXIBLE_ARRAY_MEMBER; - } - - if (InvalidTypeKind != CountedByInvalidPointeeTypeKind::VALID) { - unsigned DiagID = ShouldWarn - ? diag::warn_counted_by_attr_elt_type_unknown_size - : diag::err_counted_by_attr_pointee_unknown_size; - S.Diag(FD->getBeginLoc(), DiagID) - << SelectPtrOrArr << PointeeTy << (int)InvalidTypeKind - << (ShouldWarn ? 1 : 0) << Kind << FD->getSourceRange(); - return true; - } - - // Check the expression - - if (!E->getType()->isIntegerType() || E->getType()->isBooleanType()) { - S.Diag(E->getBeginLoc(), diag::err_count_attr_argument_not_integer) - << Kind << E->getSourceRange(); - return true; - } - - auto *DRE = dyn_cast(E); - if (!DRE) { - S.Diag(E->getBeginLoc(), - diag::err_count_attr_only_support_simple_decl_reference) - << Kind << E->getSourceRange(); - return true; - } - - auto *CountDecl = DRE->getDecl(); - FieldDecl *CountFD = dyn_cast(CountDecl); - if (auto *IFD = dyn_cast(CountDecl)) { - CountFD = IFD->getAnonField(); - } - if (!CountFD) { - S.Diag(E->getBeginLoc(), diag::err_count_attr_must_be_in_structure) - << CountDecl << Kind << E->getSourceRange(); - - S.Diag(CountDecl->getBeginLoc(), - diag::note_flexible_array_counted_by_attr_field) - << CountDecl << CountDecl->getSourceRange(); - return true; - } - - if (FD->getParent() != CountFD->getParent()) { - if (CountFD->getParent()->isUnion()) { - S.Diag(CountFD->getBeginLoc(), diag::err_count_attr_refer_to_union) - << Kind << CountFD->getSourceRange(); - return true; - } - // Whether CountRD is an anonymous struct is not determined at this - // point. Thus, an additional diagnostic in case it's not anonymous struct - // is done later in `Parser::ParseStructDeclaration`. - auto *RD = GetEnclosingNamedOrTopAnonRecord(FD); - auto *CountRD = GetEnclosingNamedOrTopAnonRecord(CountFD); - - if (RD != CountRD) { - S.Diag(E->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct) - << CountFD << Kind << FieldTy->isArrayType() << E->getSourceRange(); - S.Diag(CountFD->getBeginLoc(), - diag::note_flexible_array_counted_by_attr_field) - << CountFD << CountFD->getSourceRange(); - return true; - } - } - - Decls.push_back(TypeCoupledDeclRefInfo(CountFD, /*IsDref*/ false)); - return false; -} - static void handleCountedByAttrField(Sema &S, Decl *D, const ParsedAttr &AL) { auto *FD = dyn_cast(D); assert(FD); @@ -6120,7 +5960,7 @@ static void handleCountedByAttrField(Sema &S, Decl *D, const ParsedAttr &AL) { } llvm::SmallVector Decls; - if (CheckCountedByAttrOnField(S, FD, CountExpr, Decls, CountInBytes, OrNull)) + if (S.CheckCountedByAttrOnField(FD, CountExpr, Decls, CountInBytes, OrNull)) return; QualType CAT = S.BuildCountAttributedArrayOrPointerType( @@ -6213,7 +6053,7 @@ static void handleMSAllocatorAttr(Sema &S, Decl *D, const ParsedAttr &AL) { // Warn if the return type is not a pointer or reference type. if (auto *FD = dyn_cast(D)) { QualType RetTy = FD->getReturnType(); - if (!RetTy->isPointerType() && !RetTy->isReferenceType()) { + if (!RetTy->isPointerOrReferenceType()) { S.Diag(AL.getLoc(), diag::warn_declspec_allocator_nonpointer) << AL.getRange() << RetTy; return; @@ -6503,9 +6343,16 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, return; // Ignore C++11 attributes on declarator chunks: they appertain to the type - // instead. - if (AL.isCXX11Attribute() && !Options.IncludeCXX11Attributes && - (!IsDeclLambdaCallOperator(D) || !AL.supportsNonconformingLambdaSyntax())) + // instead. Note, isCXX11Attribute() will look at whether the attribute is + // [[]] or alignas, while isC23Attribute() will only look at [[]]. This is + // important for ensuring that alignas in C23 is properly handled on a + // structure member declaration because it is a type-specifier-qualifier in + // C but still applies to the declaration rather than the type. + if ((S.getLangOpts().CPlusPlus + ? AL.isCXX11Attribute() && (!IsDeclLambdaCallOperator(D) || + !AL.supportsNonconformingLambdaSyntax()) + : AL.isC23Attribute()) && + !Options.IncludeCXX11Attributes) return; // Unknown attributes are automatically warned on. Target-specific attributes @@ -7172,6 +7019,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_MSConstexpr: handleMSConstexprAttr(S, D, AL); break; + case ParsedAttr::AT_HybridPatchable: + handleSimpleAttribute(S, D, AL); + break; // HLSL attributes: case ParsedAttr::AT_HLSLNumThreads: @@ -7716,29 +7566,37 @@ void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { // Ordering of attributes can be important, so we take care to process // attributes in the order in which they appeared in the source code. + auto ProcessAttributesWithSliding = + [&](const ParsedAttributesView &Src, + const ProcessDeclAttributeOptions &Options) { + ParsedAttributesView NonSlidingAttrs; + for (ParsedAttr &AL : Src) { + // FIXME: this sliding is specific to standard attributes and should + // eventually be deprecated and removed as those are not intended to + // slide to anything. + if ((AL.isStandardAttributeSyntax() || AL.isAlignas()) && + AL.slidesFromDeclToDeclSpecLegacyBehavior()) { + // Skip processing the attribute, but do check if it appertains to + // the declaration. This is needed for the `MatrixType` attribute, + // which, despite being a type attribute, defines a `SubjectList` + // that only allows it to be used on typedef declarations. + AL.diagnoseAppertainsTo(*this, D); + } else { + NonSlidingAttrs.addAtEnd(&AL); + } + } + ProcessDeclAttributeList(S, D, NonSlidingAttrs, Options); + }; + // First, process attributes that appeared on the declaration itself (but // only if they don't have the legacy behavior of "sliding" to the DeclSepc). - ParsedAttributesView NonSlidingAttrs; - for (ParsedAttr &AL : PD.getDeclarationAttributes()) { - if (AL.slidesFromDeclToDeclSpecLegacyBehavior()) { - // Skip processing the attribute, but do check if it appertains to the - // declaration. This is needed for the `MatrixType` attribute, which, - // despite being a type attribute, defines a `SubjectList` that only - // allows it to be used on typedef declarations. - AL.diagnoseAppertainsTo(*this, D); - } else { - NonSlidingAttrs.addAtEnd(&AL); - } - } - ProcessDeclAttributeList(S, D, NonSlidingAttrs); + ProcessAttributesWithSliding(PD.getDeclarationAttributes(), {}); // Apply decl attributes from the DeclSpec if present. - if (!PD.getDeclSpec().getAttributes().empty()) { - ProcessDeclAttributeList(S, D, PD.getDeclSpec().getAttributes(), - ProcessDeclAttributeOptions() - .WithIncludeCXX11Attributes(false) - .WithIgnoreTypeAttributes(true)); - } + ProcessAttributesWithSliding(PD.getDeclSpec().getAttributes(), + ProcessDeclAttributeOptions() + .WithIncludeCXX11Attributes(false) + .WithIgnoreTypeAttributes(true)); // Walk the declarator structure, applying decl attributes that were in a type // position to the decl itself. This handles cases like: diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 072577f7c742d..626fcb997fc1b 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -10413,7 +10413,7 @@ void Sema::checkIncorrectVTablePointerAuthenticationAttribute( while (1) { assert(PrimaryBase); const CXXRecordDecl *Base = nullptr; - for (auto BasePtr : PrimaryBase->bases()) { + for (const CXXBaseSpecifier &BasePtr : PrimaryBase->bases()) { if (!BasePtr.getType()->getAsCXXRecordDecl()->isDynamicClass()) continue; Base = BasePtr.getType()->getAsCXXRecordDecl(); @@ -12276,16 +12276,15 @@ Decl *Sema::ActOnUsingEnumDeclaration(Scope *S, AccessSpecifier AS, SourceLocation EnumLoc, SourceRange TyLoc, const IdentifierInfo &II, ParsedType Ty, CXXScopeSpec *SS) { - assert(!SS->isInvalid() && "ScopeSpec is invalid"); + assert(SS && !SS->isInvalid() && "ScopeSpec is invalid"); TypeSourceInfo *TSI = nullptr; SourceLocation IdentLoc = TyLoc.getBegin(); QualType EnumTy = GetTypeFromParser(Ty, &TSI); if (EnumTy.isNull()) { - Diag(IdentLoc, SS && isDependentScopeSpecifier(*SS) + Diag(IdentLoc, isDependentScopeSpecifier(*SS) ? diag::err_using_enum_is_dependent : diag::err_unknown_typename) - << II.getName() - << SourceRange(SS ? SS->getBeginLoc() : IdentLoc, TyLoc.getEnd()); + << II.getName() << SourceRange(SS->getBeginLoc(), TyLoc.getEnd()); return nullptr; } diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 3727261f76d2b..288b95e8c9343 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1470,6 +1470,8 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Stmt::OMPSimdDirectiveClass: case Stmt::OMPTileDirectiveClass: case Stmt::OMPUnrollDirectiveClass: + case Stmt::OMPReverseDirectiveClass: + case Stmt::OMPInterchangeDirectiveClass: case Stmt::OMPSingleDirectiveClass: case Stmt::OMPTargetDataDirectiveClass: case Stmt::OMPTargetDirectiveClass: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index f74bdbf728281..d287c43bec22d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4185,6 +4185,21 @@ static bool CheckVectorElementsTraitOperandType(Sema &S, QualType T, return false; } +static bool checkPtrAuthTypeDiscriminatorOperandType(Sema &S, QualType T, + SourceLocation Loc, + SourceRange ArgRange) { + if (S.checkPointerAuthEnabled(Loc, ArgRange)) + return true; + + if (!T->isFunctionType() && !T->isFunctionPointerType() && + !T->isFunctionReferenceType() && !T->isMemberFunctionPointerType()) { + S.Diag(Loc, diag::err_ptrauth_type_disc_undiscriminated) << T << ArgRange; + return true; + } + + return false; +} + static bool CheckExtensionTraitOperandType(Sema &S, QualType T, SourceLocation Loc, SourceRange ArgRange, @@ -4579,6 +4594,10 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType ExprType, return CheckVectorElementsTraitOperandType(*this, ExprType, OpLoc, ExprRange); + if (ExprKind == UETT_PtrAuthTypeDiscriminator) + return checkPtrAuthTypeDiscriminatorOperandType(*this, ExprType, OpLoc, + ExprRange); + // Explicitly list some types as extensions. if (!CheckExtensionTraitOperandType(*this, ExprType, OpLoc, ExprRange, ExprKind)) @@ -5779,7 +5798,6 @@ static bool isParenthetizedAndQualifiedAddressOfExpr(Expr *Fn) { if (!UO || UO->getOpcode() != clang::UO_AddrOf) return false; if (auto *DRE = dyn_cast(UO->getSubExpr()->IgnoreParens())) { - assert(isa(DRE->getDecl()) && "expected a function"); return DRE->hasQualifier(); } if (auto *OVL = dyn_cast(UO->getSubExpr()->IgnoreParens())) @@ -10982,6 +11000,14 @@ QualType Sema::CheckAdditionOperands(ExprResult &LHS, ExprResult &RHS, if (isObjCPointer && checkArithmeticOnObjCPointer(*this, Loc, PExp)) return QualType(); + // Arithmetic on label addresses is normally allowed, except when we add + // a ptrauth signature to the addresses. + if (isa(PExp) && getLangOpts().PointerAuthIndirectGotos) { + Diag(Loc, diag::err_ptrauth_indirect_goto_addrlabel_arithmetic) + << /*addition*/ 1; + return QualType(); + } + // Check array bounds for pointer arithemtic CheckArrayAccess(PExp, IExp); @@ -11056,6 +11082,15 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS, checkArithmeticOnObjCPointer(*this, Loc, LHS.get())) return QualType(); + // Arithmetic on label addresses is normally allowed, except when we add + // a ptrauth signature to the addresses. + if (isa(LHS.get()) && + getLangOpts().PointerAuthIndirectGotos) { + Diag(Loc, diag::err_ptrauth_indirect_goto_addrlabel_arithmetic) + << /*subtraction*/ 0; + return QualType(); + } + // The result type of a pointer-int computation is the pointer type. if (RHS.get()->getType()->isIntegerType()) { // Subtracting from a null pointer should produce a warning. @@ -14190,7 +14225,14 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) { // Okay: we can take the address of a field. // Could be a pointer to member, though, if there is an explicit // scope qualifier for the class. - if (isa(op) && cast(op)->getQualifier()) { + + // [C++26] [expr.prim.id.general] + // If an id-expression E denotes a non-static non-type member + // of some class C [...] and if E is a qualified-id, E is + // not the un-parenthesized operand of the unary & operator [...] + // the id-expression is transformed into a class member access expression. + if (isa(op) && cast(op)->getQualifier() && + !isa(OrigOp.get())) { DeclContext *Ctx = dcl->getDeclContext(); if (Ctx && Ctx->isRecord()) { if (dcl->getType()->isReferenceType()) { @@ -14200,22 +14242,6 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) { return QualType(); } - // C++11 [expr.unary.op] p4: - // A pointer to member is only formed when an explicit & is used and - // its operand is a qualified-id not enclosed in parentheses. - if (isa(OrigOp.get())) { - SourceLocation LeftParenLoc = OrigOp.get()->getBeginLoc(), - RightParenLoc = OrigOp.get()->getEndLoc(); - - Diag(LeftParenLoc, - diag::err_form_ptr_to_member_from_parenthesized_expr) - << SourceRange(OpLoc, RightParenLoc) - << FixItHint::CreateRemoval(LeftParenLoc) - << FixItHint::CreateRemoval(RightParenLoc); - - // Continuing might lead to better error recovery. - } - while (cast(Ctx)->isAnonymousStructOrUnion()) Ctx = Ctx->getParent(); @@ -17092,7 +17118,8 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, // not a constant expression as a side-effect. bool Folded = E->EvaluateAsRValue(EvalResult, Context, /*isConstantContext*/ true) && - EvalResult.Val.isInt() && !EvalResult.HasSideEffects; + EvalResult.Val.isInt() && !EvalResult.HasSideEffects && + (!getLangOpts().CPlusPlus || !EvalResult.HasUndefinedBehavior); if (!isa(E)) E = ConstantExpr::Create(Context, E, EvalResult.Val); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 2b21586e8a263..722f59f00b83b 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -711,7 +711,7 @@ getUuidAttrOfType(Sema &SemaRef, QualType QT, llvm::SmallSetVector &UuidAttrs) { // Optionally remove one level of pointer, reference or array indirection. const Type *Ty = QT.getTypePtr(); - if (QT->isPointerType() || QT->isReferenceType()) + if (QT->isPointerOrReferenceType()) Ty = QT->getPointeeType().getTypePtr(); else if (QT->isArrayType()) Ty = Ty->getBaseElementTypeUnsafe(); @@ -3815,6 +3815,9 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, Overaligned, DeleteName); } + if (OperatorDelete->isInvalidDecl()) + return ExprError(); + MarkFunctionReferenced(StartLoc, OperatorDelete); // Check access and ambiguity of destructor if we're going to call it. @@ -6036,6 +6039,32 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceI return cast(rhsRecord->getDecl()) ->isDerivedFrom(cast(lhsRecord->getDecl())); } + case BTT_IsVirtualBaseOf: { + const RecordType *BaseRecord = LhsT->getAs(); + const RecordType *DerivedRecord = RhsT->getAs(); + + if (!BaseRecord || !DerivedRecord) { + DiagnoseVLAInCXXTypeTrait(Self, Lhs, + tok::kw___builtin_is_virtual_base_of); + DiagnoseVLAInCXXTypeTrait(Self, Rhs, + tok::kw___builtin_is_virtual_base_of); + return false; + } + + if (BaseRecord->isUnionType() || DerivedRecord->isUnionType()) + return false; + + if (!BaseRecord->isStructureOrClassType() || + !DerivedRecord->isStructureOrClassType()) + return false; + + if (Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT, + diag::err_incomplete_type)) + return false; + + return cast(DerivedRecord->getDecl()) + ->isVirtuallyDerivedFrom(cast(BaseRecord->getDecl())); + } case BTT_IsSame: return Self.Context.hasSameType(LhsT, RhsT); case BTT_TypeCompatible: { diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 7ccecf055feed..2751c7cec2842 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -3206,9 +3206,10 @@ ExprResult SemaObjC::BuildInstanceMessage( } if (!isDesignatedInitChain) { const ObjCMethodDecl *InitMethod = nullptr; + auto *CurMD = SemaRef.getCurMethodDecl(); + assert(CurMD && "Current method declaration should not be null"); bool isDesignated = - SemaRef.getCurMethodDecl()->isDesignatedInitializerForTheInterface( - &InitMethod); + CurMD->isDesignatedInitializerForTheInterface(&InitMethod); assert(isDesignated && InitMethod); (void)isDesignated; Diag(SelLoc, SuperLoc.isValid() ? diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 9940bc5b4a606..7724fafb253c5 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -650,7 +650,10 @@ class DiagnoseHLSLAvailability bool HasMatchingEnvironmentOrNone(const AvailabilityAttr *AA); public: - DiagnoseHLSLAvailability(Sema &SemaRef) : SemaRef(SemaRef) {} + DiagnoseHLSLAvailability(Sema &SemaRef) + : SemaRef(SemaRef), + CurrentShaderEnvironment(llvm::Triple::UnknownEnvironment), + CurrentShaderStageBit(0), ReportOnlyShaderStageIssues(false) {} // AST traversal methods void RunOnTranslationUnit(const TranslationUnitDecl *TU); @@ -1014,8 +1017,8 @@ void SetElementTypeAsReturnType(Sema *S, CallExpr *TheCall, // returning an ExprError bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { switch (BuiltinID) { - case Builtin::BI__builtin_hlsl_elementwise_all: - case Builtin::BI__builtin_hlsl_elementwise_any: { + case Builtin::BI__builtin_hlsl_all: + case Builtin::BI__builtin_hlsl_any: { if (SemaRef.checkArgCount(TheCall, 1)) return true; break; diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index d7a7f1f123185..be417489506e1 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -1986,6 +1986,9 @@ static bool checkDestructorReference(QualType ElementType, SourceLocation Loc, return false; CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(CXXRD); + if (!Destructor) + return false; + SemaRef.CheckDestructorAccess(Loc, Destructor, SemaRef.PDiag(diag::err_access_dtor_temp) << ElementType); @@ -2016,7 +2019,7 @@ canInitializeArrayWithEmbedDataString(ArrayRef ExprList, if (InitType->isArrayType()) { const ArrayType *InitArrayType = InitType->getAsArrayTypeUnsafe(); QualType InitElementTy = InitArrayType->getElementType(); - QualType EmbedExprElementTy = EE->getType(); + QualType EmbedExprElementTy = EE->getDataStringLiteral()->getType(); const bool TypesMatch = Context.typesAreCompatible(InitElementTy, EmbedExprElementTy) || (InitElementTy->isCharType() && EmbedExprElementTy->isCharType()); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index b48640c48ed45..cabf22f97c3e6 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -40,6 +40,7 @@ #include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/PointerEmbeddedInt.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Sequence.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Frontend/OpenMP/OMPAssume.h" @@ -167,10 +168,6 @@ class DSAStackTy { SourceLocation DefaultAttrLoc; DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown + 1]; OpenMPDirectiveKind Directive = OMPD_unknown; - /// GenericLoopDirective with bind clause is mapped to other directives, - /// like for, distribute and simd. Presently, set MappedDirective to - /// OMPLoop. This may also be used in a similar way for other constructs. - OpenMPDirectiveKind MappedDirective = OMPD_unknown; DeclarationNameInfo DirectiveName; Scope *CurScope = nullptr; DeclContext *Context = nullptr; @@ -644,24 +641,6 @@ class DSAStackTy { const SharingMapTy *Top = getTopOfStackOrNull(); return Top ? Top->Directive : OMPD_unknown; } - OpenMPDirectiveKind getMappedDirective() const { - const SharingMapTy *Top = getTopOfStackOrNull(); - return Top ? Top->MappedDirective : OMPD_unknown; - } - void setCurrentDirective(OpenMPDirectiveKind NewDK) { - SharingMapTy *Top = getTopOfStackOrNull(); - assert(Top && - "Before calling setCurrentDirective Top of Stack not to be NULL."); - // Store the old into MappedDirective & assign argument NewDK to Directive. - Top->Directive = NewDK; - } - void setMappedDirective(OpenMPDirectiveKind NewDK) { - SharingMapTy *Top = getTopOfStackOrNull(); - assert(Top && - "Before calling setMappedDirective Top of Stack not to be NULL."); - // Store the old into MappedDirective & assign argument NewDK to Directive. - Top->MappedDirective = NewDK; - } /// Returns directive kind at specified level. OpenMPDirectiveKind getDirective(unsigned Level) const { assert(!isStackEmpty() && "No directive at specified level."); @@ -822,7 +801,8 @@ class DSAStackTy { return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || (M == OMPC_DEFAULTMAP_MODIFIER_to) || (M == OMPC_DEFAULTMAP_MODIFIER_from) || - (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); + (M == OMPC_DEFAULTMAP_MODIFIER_tofrom) || + (M == OMPC_DEFAULTMAP_MODIFIER_present); } return true; } @@ -2853,7 +2833,7 @@ static void checkReductionClauses(Sema &S, DSAStackTy *Stack, S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); continue; } - for (Expr *Ref : RC->varlists()) { + for (Expr *Ref : RC->varlist()) { assert(Ref && "NULL expr in OpenMP nontemporal clause."); SourceLocation ELoc; SourceRange ERange; @@ -2893,7 +2873,7 @@ void SemaOpenMP::EndOpenMPDSABlock(Stmt *CurDirective) { for (OMPClause *C : D->clauses()) { if (auto *Clause = dyn_cast(C)) { SmallVector PrivateCopies; - for (Expr *DE : Clause->varlists()) { + for (Expr *DE : Clause->varlist()) { if (DE->isValueDependent() || DE->isTypeDependent()) { PrivateCopies.push_back(nullptr); continue; @@ -2931,7 +2911,7 @@ void SemaOpenMP::EndOpenMPDSABlock(Stmt *CurDirective) { // Finalize nontemporal clause by handling private copies, if any. if (auto *Clause = dyn_cast(C)) { SmallVector PrivateRefs; - for (Expr *RefExpr : Clause->varlists()) { + for (Expr *RefExpr : Clause->varlist()) { assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); SourceLocation ELoc; SourceRange ERange; @@ -3101,11 +3081,11 @@ ExprResult SemaOpenMP::ActOnOpenMPIdExpression(Scope *CurScope, if (TypoCorrection Corrected = SemaRef.CorrectTypo(Id, Sema::LookupOrdinaryName, CurScope, nullptr, CCC, Sema::CTK_ErrorRecovery)) { - SemaRef.diagnoseTypo(Corrected, - PDiag(Lookup.empty() - ? diag::err_undeclared_var_use_suggest - : diag::err_omp_expected_var_arg_suggest) - << Id.getName()); + SemaRef.diagnoseTypo( + Corrected, + SemaRef.PDiag(Lookup.empty() ? diag::err_undeclared_var_use_suggest + : diag::err_omp_expected_var_arg_suggest) + << Id.getName()); VD = Corrected.getCorrectionDeclAs(); } else { Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use @@ -3774,7 +3754,7 @@ class DSAAttrChecker final : public StmtVisitor { !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { for (OMPClause *C : S->clauses()) if (auto *FC = dyn_cast(C)) { - for (Expr *Ref : FC->varlists()) + for (Expr *Ref : FC->varlist()) Visit(Ref); } } @@ -4407,6 +4387,8 @@ void SemaOpenMP::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, case OMPD_section: case OMPD_tile: case OMPD_unroll: + case OMPD_reverse: + case OMPD_interchange: break; default: processCapturedRegions(SemaRef, DKind, CurScope, @@ -4749,7 +4731,7 @@ StmtResult SemaOpenMP::ActOnOpenMPRegionEnd(StmtResult S, SemaRef.MarkDeclarationsReferencedInExpr(E); } if (auto *AC = dyn_cast(C)) { - for (Expr *E : AC->varlists()) + for (Expr *E : AC->varlist()) SemaRef.MarkDeclarationsReferencedInExpr(E); } } @@ -5331,7 +5313,7 @@ static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, diag::warn_omp_allocate_thread_on_task_target_directive) << getOpenMPDirectiveName(Stack->getCurrentDirective()); } - for (Expr *E : AC->varlists()) { + for (Expr *E : AC->varlist()) { SourceLocation ELoc; SourceRange ERange; Expr *SimpleRefExpr = E; @@ -5980,127 +5962,63 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema &SemaRef) { return Checker.teamsLoopCanBeParallelFor(); } -bool SemaOpenMP::mapLoopConstruct( - llvm::SmallVector &ClausesWithoutBind, - ArrayRef Clauses, OpenMPBindClauseKind &BindKind, - OpenMPDirectiveKind &Kind, OpenMPDirectiveKind &PrevMappedDirective, - SourceLocation StartLoc, SourceLocation EndLoc, - const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion) { - - bool UseClausesWithoutBind = false; - - // Restricting to "#pragma omp loop bind" - if (getLangOpts().OpenMP >= 50 && Kind == OMPD_loop) { - - const OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); - - if (BindKind == OMPC_BIND_unknown) { - // Setting the enclosing teams or parallel construct for the loop - // directive without bind clause. - // [5.0:129:25-28] If the bind clause is not present on the construct and - // the loop construct is closely nested inside a teams or parallel - // construct, the binding region is the corresponding teams or parallel - // region. If none of those conditions hold, the binding region is not - // defined. - BindKind = OMPC_BIND_thread; // Default bind(thread) if binding is unknown - ArrayRef ParentLeafs = - getLeafConstructsOrSelf(ParentDirective); - - if (ParentDirective == OMPD_unknown) { - Diag(DSAStack->getDefaultDSALocation(), - diag::err_omp_bind_required_on_loop); - } else if (ParentLeafs.back() == OMPD_parallel) { - BindKind = OMPC_BIND_parallel; - } else if (ParentLeafs.back() == OMPD_teams) { - BindKind = OMPC_BIND_teams; - } - } else { - // bind clause is present in loop directive. When the loop directive is - // changed to a new directive the bind clause is not used. So, we should - // set flag indicating to only use the clauses that aren't the - // bind clause. - UseClausesWithoutBind = true; - } - - for (OMPClause *C : Clauses) { - // Spec restriction : bind(teams) and reduction not permitted. - if (BindKind == OMPC_BIND_teams && - C->getClauseKind() == llvm::omp::Clause::OMPC_reduction) - Diag(DSAStack->getDefaultDSALocation(), - diag::err_omp_loop_reduction_clause); - - // A new Vector ClausesWithoutBind, which does not contain the bind - // clause, for passing to new directive. - if (C->getClauseKind() != llvm::omp::Clause::OMPC_bind) - ClausesWithoutBind.push_back(C); - } - - switch (BindKind) { - case OMPC_BIND_parallel: - Kind = OMPD_for; - DSAStack->setCurrentDirective(OMPD_for); - DSAStack->setMappedDirective(OMPD_loop); - PrevMappedDirective = OMPD_loop; - break; - case OMPC_BIND_teams: - Kind = OMPD_distribute; - DSAStack->setCurrentDirective(OMPD_distribute); - DSAStack->setMappedDirective(OMPD_loop); - PrevMappedDirective = OMPD_loop; - break; - case OMPC_BIND_thread: - Kind = OMPD_simd; - DSAStack->setCurrentDirective(OMPD_simd); - DSAStack->setMappedDirective(OMPD_loop); - PrevMappedDirective = OMPD_loop; - break; - case OMPC_BIND_unknown: - break; - } - } else if (PrevMappedDirective == OMPD_loop) { - /// An initial pass after recognizing all the statements is done in the - /// Parser when the directive OMPD_loop is mapped to OMPD_for, - /// OMPD_distribute or OMPD_simd. A second transform pass with call from - /// clang::TreeTransform::TransformOMPExecutableDirective() is done - /// with the Directive as one of the above mapped directive without - /// the bind clause. Then "PrevMappedDirective" stored in the - /// OMPExecutableDirective is accessed and hence this else statement. - - DSAStack->setMappedDirective(OMPD_loop); - } - - return UseClausesWithoutBind; -} - StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective( OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef Clauses, - Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - OpenMPDirectiveKind PrevMappedDirective) { + Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { assert(isOpenMPExecutableDirective(Kind) && "Unexpected directive category"); StmtResult Res = StmtError(); OpenMPBindClauseKind BindKind = OMPC_BIND_unknown; - llvm::SmallVector ClausesWithoutBind; - bool UseClausesWithoutBind = false; + llvm::SmallVector ClausesWithImplicit; if (const OMPBindClause *BC = OMPExecutableDirective::getSingleClause(Clauses)) BindKind = BC->getBindKind(); - // Variable used to note down the DirectiveKind because mapLoopConstruct may - // change "Kind" variable, due to mapping of "omp loop" to other directives. - OpenMPDirectiveKind DK = Kind; - if (Kind == OMPD_loop || PrevMappedDirective == OMPD_loop) { - UseClausesWithoutBind = mapLoopConstruct( - ClausesWithoutBind, Clauses, BindKind, Kind, PrevMappedDirective, - StartLoc, EndLoc, DirName, CancelRegion); - DK = OMPD_loop; + if (Kind == OMPD_loop && BindKind == OMPC_BIND_unknown) { + const OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); + + // Setting the enclosing teams or parallel construct for the loop + // directive without bind clause. + // [5.0:129:25-28] If the bind clause is not present on the construct and + // the loop construct is closely nested inside a teams or parallel + // construct, the binding region is the corresponding teams or parallel + // region. If none of those conditions hold, the binding region is not + // defined. + BindKind = OMPC_BIND_thread; // Default bind(thread) if binding is unknown + ArrayRef ParentLeafs = + getLeafConstructsOrSelf(ParentDirective); + + if (ParentDirective == OMPD_unknown) { + Diag(DSAStack->getDefaultDSALocation(), + diag::err_omp_bind_required_on_loop); + } else if (ParentLeafs.back() == OMPD_parallel) { + BindKind = OMPC_BIND_parallel; + } else if (ParentLeafs.back() == OMPD_teams) { + BindKind = OMPC_BIND_teams; + } + + assert(BindKind != OMPC_BIND_unknown && "Expecting BindKind"); + + OMPClause *C = + ActOnOpenMPBindClause(BindKind, SourceLocation(), SourceLocation(), + SourceLocation(), SourceLocation()); + ClausesWithImplicit.push_back(C); + } + + // Diagnose "loop bind(teams)" with "reduction". + if (Kind == OMPD_loop && BindKind == OMPC_BIND_teams) { + for (OMPClause *C : Clauses) { + if (C->getClauseKind() == OMPC_reduction) + Diag(DSAStack->getDefaultDSALocation(), + diag::err_omp_loop_reduction_clause); + } } // First check CancelRegion which is then used in checkNestingOfRegions. if (checkCancelRegion(SemaRef, Kind, CancelRegion, StartLoc) || - checkNestingOfRegions(SemaRef, DSAStack, DK, DirName, CancelRegion, + checkNestingOfRegions(SemaRef, DSAStack, Kind, DirName, CancelRegion, BindKind, StartLoc)) { return StmtError(); } @@ -6110,15 +6028,10 @@ StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective( isOpenMPTargetDataManagementDirective(Kind))) Diag(StartLoc, diag::warn_hip_omp_target_directives); - llvm::SmallVector ClausesWithImplicit; VarsWithInheritedDSAType VarsWithInheritedDSA; bool ErrorFound = false; - if (getLangOpts().OpenMP >= 50 && UseClausesWithoutBind) { - ClausesWithImplicit.append(ClausesWithoutBind.begin(), - ClausesWithoutBind.end()); - } else { - ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); - } + ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); + if (AStmt && !SemaRef.CurContext->isDependentContext() && isOpenMPCapturingDirective(Kind)) { assert(isa(AStmt) && "Captured statement expected"); @@ -6167,14 +6080,14 @@ StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective( DMC->getDefaultmapModifierLoc(); } for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) { - auto Kind = static_cast(VC); + auto K = static_cast(VC); for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { - ArrayRef ImplicitMap = DSAChecker.getImplicitMap( - Kind, static_cast(I)); + ArrayRef ImplicitMap = + DSAChecker.getImplicitMap(K, static_cast(I)); ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end()); } ArrayRef ImplicitModifier = - DSAChecker.getImplicitMapModifier(Kind); + DSAChecker.getImplicitMapModifier(K); ImplicitMapModifiers[VC].append(ImplicitModifier.begin(), ImplicitModifier.end()); std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]), @@ -6224,7 +6137,7 @@ StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective( SmallVector ImplicitExprs; for (OMPClause *C : Clauses) { if (auto *RC = dyn_cast(C)) - for (Expr *E : RC->varlists()) + for (Expr *E : RC->varlist()) if (!isa(E->IgnoreParenImpCasts())) ImplicitExprs.emplace_back(E); } @@ -6248,10 +6161,10 @@ StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective( continue; CXXScopeSpec MapperIdScopeSpec; DeclarationNameInfo MapperId; - auto Kind = static_cast(ClauseKindCnt); + auto K = static_cast(ClauseKindCnt); if (OMPClause *Implicit = ActOnOpenMPMapClause( nullptr, ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I], - MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true, + MapperIdScopeSpec, MapperId, K, /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), ImplicitMap, OMPVarListLocTy())) { ClausesWithImplicit.emplace_back(Implicit); @@ -6286,6 +6199,15 @@ StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective( Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); break; + case OMPD_reverse: + assert(ClausesWithImplicit.empty() && + "reverse directive does not support any clauses"); + Res = ActOnOpenMPReverseDirective(AStmt, StartLoc, EndLoc); + break; + case OMPD_interchange: + Res = ActOnOpenMPInterchangeDirective(ClausesWithImplicit, AStmt, StartLoc, + EndLoc); + break; case OMPD_for: Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); @@ -7581,9 +7503,9 @@ SemaOpenMP::checkOpenMPDeclareVariantFunction(SemaOpenMP::DeclGroupPtrTy DG, PartialDiagnostic::NullDiagnostic()), PartialDiagnosticAt( VariantRef->getExprLoc(), - PDiag(diag::err_omp_declare_variant_doesnt_support)), + SemaRef.PDiag(diag::err_omp_declare_variant_doesnt_support)), PartialDiagnosticAt(VariantRef->getExprLoc(), - PDiag(diag::err_omp_declare_variant_diff) + SemaRef.PDiag(diag::err_omp_declare_variant_diff) << FD->getLocation()), /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, /*CLinkageMayDiffer=*/true)) @@ -9160,13 +9082,9 @@ static bool checkOpenMPIterationSpace( auto *CXXFor = dyn_cast_or_null(S); // Ranged for is supported only in OpenMP 5.0. if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { - OpenMPDirectiveKind DK = (SemaRef.getLangOpts().OpenMP < 50 || - DSA.getMappedDirective() == OMPD_unknown) - ? DKind - : DSA.getMappedDirective(); SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) - << getOpenMPDirectiveName(DK) << TotalNestedLoopCount + << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; if (TotalNestedLoopCount > 1) { if (CollapseLoopCountExpr && OrderedLoopCountExpr) @@ -9504,7 +9422,7 @@ static Stmt *buildPreInits(ASTContext &Context, /// contained DeclStmts need to be visible after the execution of the list. Used /// for OpenMP pre-init declarations/statements. static void appendFlattenedStmtList(SmallVectorImpl &TargetList, - Stmt *Item) { + Stmt *Item) { // nullptr represents an empty list. if (!Item) return; @@ -10321,33 +10239,13 @@ static bool checkSimdlenSafelenSpecified(Sema &S, return false; } -static bool checkGenericLoopLastprivate(Sema &S, ArrayRef Clauses, - OpenMPDirectiveKind K, - DSAStackTy *Stack); - -bool SemaOpenMP::checkLastPrivateForMappedDirectives( - ArrayRef Clauses) { - - // Check for syntax of lastprivate - // Param of the lastprivate have different meanings in the mapped directives - // e.g. "omp loop" Only loop iteration vars are allowed in lastprivate clause - // "omp for" lastprivate vars must be shared - if (getLangOpts().OpenMP >= 50 && - DSAStack->getMappedDirective() == OMPD_loop && - checkGenericLoopLastprivate(SemaRef, Clauses, OMPD_loop, DSAStack)) { - return false; - } - return true; -} - StmtResult SemaOpenMP::ActOnOpenMPSimdDirective( ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { if (!AStmt) return StmtError(); - if (!checkLastPrivateForMappedDirectives(Clauses)) - return StmtError(); + CapturedStmt *CS = setBranchProtectedScope(SemaRef, OMPD_simd, AStmt); assert(isa(AStmt) && "Captured statement expected"); OMPLoopBasedDirective::HelperExprs B; @@ -10355,7 +10253,7 @@ StmtResult SemaOpenMP::ActOnOpenMPSimdDirective( // define the nested loops number. unsigned NestedLoopCount = checkOpenMPLoop( OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), - AStmt, SemaRef, *DSAStack, VarsWithImplicitDSA, B); + CS, SemaRef, *DSAStack, VarsWithImplicitDSA, B); if (NestedLoopCount == 0) return StmtError(); @@ -10365,10 +10263,8 @@ StmtResult SemaOpenMP::ActOnOpenMPSimdDirective( if (checkSimdlenSafelenSpecified(SemaRef, Clauses)) return StmtError(); - SemaRef.setFunctionHasBranchProtectedScope(); auto *SimdDirective = OMPSimdDirective::Create( - getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, - DSAStack->getMappedDirective()); + getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); return SimdDirective; } @@ -10378,9 +10274,6 @@ StmtResult SemaOpenMP::ActOnOpenMPForDirective( if (!AStmt) return StmtError(); - if (!checkLastPrivateForMappedDirectives(Clauses)) - return StmtError(); - assert(isa(AStmt) && "Captured statement expected"); OMPLoopBasedDirective::HelperExprs B; // In presence of clause 'collapse' or 'ordered' with number of loops, it will @@ -10396,8 +10289,7 @@ StmtResult SemaOpenMP::ActOnOpenMPForDirective( auto *ForDirective = OMPForDirective::Create( getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, - DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion(), - DSAStack->getMappedDirective()); + DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); return ForDirective; } @@ -10407,13 +10299,15 @@ StmtResult SemaOpenMP::ActOnOpenMPForSimdDirective( if (!AStmt) return StmtError(); + CapturedStmt *CS = setBranchProtectedScope(SemaRef, OMPD_for_simd, AStmt); + assert(isa(AStmt) && "Captured statement expected"); OMPLoopBasedDirective::HelperExprs B; // In presence of clause 'collapse' or 'ordered' with number of loops, it will // define the nested loops number. unsigned NestedLoopCount = checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), - getOrderedNumberExpr(Clauses), AStmt, SemaRef, *DSAStack, + getOrderedNumberExpr(Clauses), CS, SemaRef, *DSAStack, VarsWithImplicitDSA, B); if (NestedLoopCount == 0) return StmtError(); @@ -10424,7 +10318,6 @@ StmtResult SemaOpenMP::ActOnOpenMPForSimdDirective( if (checkSimdlenSafelenSpecified(SemaRef, Clauses)) return StmtError(); - SemaRef.setFunctionHasBranchProtectedScope(); return OMPForSimdDirective::Create(getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); } @@ -10554,7 +10447,7 @@ static bool checkGenericLoopLastprivate(Sema &S, ArrayRef Clauses, bool ErrorFound = false; for (OMPClause *C : Clauses) { if (auto *LPC = dyn_cast(C)) { - for (Expr *RefExpr : LPC->varlists()) { + for (Expr *RefExpr : LPC->varlist()) { SourceLocation ELoc; SourceRange ERange; Expr *SimpleRefExpr = RefExpr; @@ -10876,14 +10769,15 @@ StmtResult SemaOpenMP::ActOnOpenMPParallelForSimdDirective( if (!AStmt) return StmtError(); - setBranchProtectedScope(SemaRef, OMPD_parallel_for_simd, AStmt); + CapturedStmt *CS = + setBranchProtectedScope(SemaRef, OMPD_parallel_for_simd, AStmt); OMPLoopBasedDirective::HelperExprs B; // In presence of clause 'collapse' or 'ordered' with number of loops, it will // define the nested loops number. unsigned NestedLoopCount = checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), - getOrderedNumberExpr(Clauses), AStmt, SemaRef, *DSAStack, + getOrderedNumberExpr(Clauses), CS, SemaRef, *DSAStack, VarsWithImplicitDSA, B); if (NestedLoopCount == 0) return StmtError(); @@ -13233,14 +13127,17 @@ StmtResult SemaOpenMP::ActOnOpenMPTaskLoopSimdDirective( if (!AStmt) return StmtError(); + CapturedStmt *CS = + setBranchProtectedScope(SemaRef, OMPD_taskloop_simd, AStmt); + assert(isa(AStmt) && "Captured statement expected"); OMPLoopBasedDirective::HelperExprs B; // In presence of clause 'collapse' or 'ordered' with number of loops, it will // define the nested loops number. unsigned NestedLoopCount = checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), - /*OrderedLoopCountExpr=*/nullptr, AStmt, SemaRef, - *DSAStack, VarsWithImplicitDSA, B); + /*OrderedLoopCountExpr=*/nullptr, CS, SemaRef, *DSAStack, + VarsWithImplicitDSA, B); if (NestedLoopCount == 0) return StmtError(); @@ -13261,7 +13158,6 @@ StmtResult SemaOpenMP::ActOnOpenMPTaskLoopSimdDirective( if (checkSimdlenSafelenSpecified(SemaRef, Clauses)) return StmtError(); - SemaRef.setFunctionHasBranchProtectedScope(); return OMPTaskLoopSimdDirective::Create(getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); } @@ -13348,14 +13244,17 @@ StmtResult SemaOpenMP::ActOnOpenMPMasterTaskLoopSimdDirective( if (!AStmt) return StmtError(); + CapturedStmt *CS = + setBranchProtectedScope(SemaRef, OMPD_master_taskloop_simd, AStmt); + assert(isa(AStmt) && "Captured statement expected"); OMPLoopBasedDirective::HelperExprs B; // In presence of clause 'collapse' or 'ordered' with number of loops, it will // define the nested loops number. unsigned NestedLoopCount = checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), - /*OrderedLoopCountExpr=*/nullptr, AStmt, SemaRef, - *DSAStack, VarsWithImplicitDSA, B); + /*OrderedLoopCountExpr=*/nullptr, CS, SemaRef, *DSAStack, + VarsWithImplicitDSA, B); if (NestedLoopCount == 0) return StmtError(); @@ -13376,7 +13275,6 @@ StmtResult SemaOpenMP::ActOnOpenMPMasterTaskLoopSimdDirective( if (checkSimdlenSafelenSpecified(SemaRef, Clauses)) return StmtError(); - SemaRef.setFunctionHasBranchProtectedScope(); return OMPMasterTaskLoopSimdDirective::Create( getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); } @@ -13387,14 +13285,17 @@ StmtResult SemaOpenMP::ActOnOpenMPMaskedTaskLoopSimdDirective( if (!AStmt) return StmtError(); + CapturedStmt *CS = + setBranchProtectedScope(SemaRef, OMPD_masked_taskloop_simd, AStmt); + assert(isa(AStmt) && "Captured statement expected"); OMPLoopBasedDirective::HelperExprs B; // In presence of clause 'collapse' or 'ordered' with number of loops, it will // define the nested loops number. unsigned NestedLoopCount = checkOpenMPLoop(OMPD_masked_taskloop_simd, getCollapseNumberExpr(Clauses), - /*OrderedLoopCountExpr=*/nullptr, AStmt, SemaRef, - *DSAStack, VarsWithImplicitDSA, B); + /*OrderedLoopCountExpr=*/nullptr, CS, SemaRef, *DSAStack, + VarsWithImplicitDSA, B); if (NestedLoopCount == 0) return StmtError(); @@ -13415,7 +13316,6 @@ StmtResult SemaOpenMP::ActOnOpenMPMaskedTaskLoopSimdDirective( if (checkSimdlenSafelenSpecified(SemaRef, Clauses)) return StmtError(); - SemaRef.setFunctionHasBranchProtectedScope(); return OMPMaskedTaskLoopSimdDirective::Create( getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); } @@ -13584,9 +13484,6 @@ StmtResult SemaOpenMP::ActOnOpenMPDistributeDirective( if (!AStmt) return StmtError(); - if (!checkLastPrivateForMappedDirectives(Clauses)) - return StmtError(); - assert(isa(AStmt) && "Captured statement expected"); OMPLoopBasedDirective::HelperExprs B; // In presence of clause 'collapse' with number of loops, it will @@ -13603,8 +13500,7 @@ StmtResult SemaOpenMP::ActOnOpenMPDistributeDirective( SemaRef.setFunctionHasBranchProtectedScope(); auto *DistributeDirective = OMPDistributeDirective::Create( - getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, - DSAStack->getMappedDirective()); + getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); return DistributeDirective; } @@ -14042,6 +13938,10 @@ bool SemaOpenMP::checkTransformableLoopNest( DependentPreInits = Dir->getPreInits(); else if (auto *Dir = dyn_cast(Transform)) DependentPreInits = Dir->getPreInits(); + else if (auto *Dir = dyn_cast(Transform)) + DependentPreInits = Dir->getPreInits(); + else if (auto *Dir = dyn_cast(Transform)) + DependentPreInits = Dir->getPreInits(); else llvm_unreachable("Unhandled loop transformation"); @@ -14660,6 +14560,345 @@ StmtResult SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef Clauses, buildPreInits(Context, PreInits)); } +StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt, + SourceLocation StartLoc, + SourceLocation EndLoc) { + ASTContext &Context = getASTContext(); + Scope *CurScope = SemaRef.getCurScope(); + + // Empty statement should only be possible if there already was an error. + if (!AStmt) + return StmtError(); + + constexpr unsigned NumLoops = 1; + Stmt *Body = nullptr; + SmallVector LoopHelpers( + NumLoops); + SmallVector, NumLoops + 1> OriginalInits; + if (!checkTransformableLoopNest(OMPD_reverse, AStmt, NumLoops, LoopHelpers, + Body, OriginalInits)) + return StmtError(); + + // Delay applying the transformation to when template is completely + // instantiated. + if (SemaRef.CurContext->isDependentContext()) + return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt, + nullptr, nullptr); + + assert(LoopHelpers.size() == NumLoops && + "Expecting a single-dimensional loop iteration space"); + assert(OriginalInits.size() == NumLoops && + "Expecting a single-dimensional loop iteration space"); + OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front(); + + // Find the loop statement. + Stmt *LoopStmt = nullptr; + collectLoopStmts(AStmt, {LoopStmt}); + + // Determine the PreInit declarations. + SmallVector PreInits; + addLoopPreInits(Context, LoopHelper, LoopStmt, OriginalInits[0], PreInits); + + auto *IterationVarRef = cast(LoopHelper.IterationVarRef); + QualType IVTy = IterationVarRef->getType(); + uint64_t IVWidth = Context.getTypeSize(IVTy); + auto *OrigVar = cast(LoopHelper.Counters.front()); + + // Iteration variable SourceLocations. + SourceLocation OrigVarLoc = OrigVar->getExprLoc(); + SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc(); + SourceLocation OrigVarLocEnd = OrigVar->getEndLoc(); + + // Locations pointing to the transformation. + SourceLocation TransformLoc = StartLoc; + SourceLocation TransformLocBegin = StartLoc; + SourceLocation TransformLocEnd = EndLoc; + + // Internal variable names. + std::string OrigVarName = OrigVar->getNameInfo().getAsString(); + SmallString<64> ForwardIVName(".forward.iv."); + ForwardIVName += OrigVarName; + SmallString<64> ReversedIVName(".reversed.iv."); + ReversedIVName += OrigVarName; + + // LoopHelper.Updates will read the logical iteration number from + // LoopHelper.IterationVarRef, compute the value of the user loop counter of + // that logical iteration from it, then assign it to the user loop counter + // variable. We cannot directly use LoopHelper.IterationVarRef as the + // induction variable of the generated loop because it may cause an underflow: + // \code{.c} + // for (unsigned i = 0; i < n; ++i) + // body(i); + // \endcode + // + // Naive reversal: + // \code{.c} + // for (unsigned i = n-1; i >= 0; --i) + // body(i); + // \endcode + // + // Instead, we introduce a new iteration variable representing the logical + // iteration counter of the original loop, convert it to the logical iteration + // number of the reversed loop, then let LoopHelper.Updates compute the user's + // loop iteration variable from it. + // \code{.cpp} + // for (auto .forward.iv = 0; .forward.iv < n; ++.forward.iv) { + // auto .reversed.iv = n - .forward.iv - 1; + // i = (.reversed.iv + 0) * 1; // LoopHelper.Updates + // body(i); // Body + // } + // \endcode + + // Subexpressions with more than one use. One of the constraints of an AST is + // that every node object must appear at most once, hence we define a lambda + // that creates a new AST node at every use. + CaptureVars CopyTransformer(SemaRef); + auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * { + return AssertSuccess( + CopyTransformer.TransformExpr(LoopHelper.NumIterations)); + }; + + // Create the iteration variable for the forward loop (from 0 to n-1). + VarDecl *ForwardIVDecl = + buildVarDecl(SemaRef, {}, IVTy, ForwardIVName, nullptr, OrigVar); + auto MakeForwardRef = [&SemaRef = this->SemaRef, ForwardIVDecl, IVTy, + OrigVarLoc]() { + return buildDeclRefExpr(SemaRef, ForwardIVDecl, IVTy, OrigVarLoc); + }; + + // Iteration variable for the reversed induction variable (from n-1 downto 0): + // Reuse the iteration variable created by checkOpenMPLoop. + auto *ReversedIVDecl = cast(IterationVarRef->getDecl()); + ReversedIVDecl->setDeclName( + &SemaRef.PP.getIdentifierTable().get(ReversedIVName)); + + // For init-statement: + // \code{.cpp} + // auto .forward.iv = 0; + // \endcode + auto *Zero = IntegerLiteral::Create(Context, llvm::APInt::getZero(IVWidth), + ForwardIVDecl->getType(), OrigVarLoc); + SemaRef.AddInitializerToDecl(ForwardIVDecl, Zero, /*DirectInit=*/false); + StmtResult Init = new (Context) + DeclStmt(DeclGroupRef(ForwardIVDecl), OrigVarLocBegin, OrigVarLocEnd); + if (!Init.isUsable()) + return StmtError(); + + // Forward iv cond-expression: + // \code{.cpp} + // .forward.iv < MakeNumIterations() + // \endcode + ExprResult Cond = + SemaRef.BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, + MakeForwardRef(), MakeNumIterations()); + if (!Cond.isUsable()) + return StmtError(); + + // Forward incr-statement: + // \code{.c} + // ++.forward.iv + // \endcode + ExprResult Incr = SemaRef.BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), + UO_PreInc, MakeForwardRef()); + if (!Incr.isUsable()) + return StmtError(); + + // Reverse the forward-iv: + // \code{.cpp} + // auto .reversed.iv = MakeNumIterations() - 1 - .forward.iv + // \endcode + auto *One = IntegerLiteral::Create(Context, llvm::APInt(IVWidth, 1), IVTy, + TransformLoc); + ExprResult Minus = SemaRef.BuildBinOp(CurScope, TransformLoc, BO_Sub, + MakeNumIterations(), One); + if (!Minus.isUsable()) + return StmtError(); + Minus = SemaRef.BuildBinOp(CurScope, TransformLoc, BO_Sub, Minus.get(), + MakeForwardRef()); + if (!Minus.isUsable()) + return StmtError(); + StmtResult InitReversed = new (Context) DeclStmt( + DeclGroupRef(ReversedIVDecl), TransformLocBegin, TransformLocEnd); + if (!InitReversed.isUsable()) + return StmtError(); + SemaRef.AddInitializerToDecl(ReversedIVDecl, Minus.get(), + /*DirectInit=*/false); + + // The new loop body. + SmallVector BodyStmts; + BodyStmts.reserve(LoopHelper.Updates.size() + 2 + + (isa(LoopStmt) ? 1 : 0)); + BodyStmts.push_back(InitReversed.get()); + llvm::append_range(BodyStmts, LoopHelper.Updates); + if (auto *CXXRangeFor = dyn_cast(LoopStmt)) + BodyStmts.push_back(CXXRangeFor->getLoopVarStmt()); + BodyStmts.push_back(Body); + auto *ReversedBody = + CompoundStmt::Create(Context, BodyStmts, FPOptionsOverride(), + Body->getBeginLoc(), Body->getEndLoc()); + + // Finally create the reversed For-statement. + auto *ReversedFor = new (Context) + ForStmt(Context, Init.get(), Cond.get(), nullptr, Incr.get(), + ReversedBody, LoopHelper.Init->getBeginLoc(), + LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); + return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt, + ReversedFor, + buildPreInits(Context, PreInits)); +} + +StmtResult SemaOpenMP::ActOnOpenMPInterchangeDirective( + ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc) { + ASTContext &Context = getASTContext(); + DeclContext *CurContext = SemaRef.CurContext; + Scope *CurScope = SemaRef.getCurScope(); + + // Empty statement should only be possible if there already was an error. + if (!AStmt) + return StmtError(); + + // interchange without permutation clause swaps two loops. + constexpr size_t NumLoops = 2; + + // Verify and diagnose loop nest. + SmallVector LoopHelpers(NumLoops); + Stmt *Body = nullptr; + SmallVector, 2> OriginalInits; + if (!checkTransformableLoopNest(OMPD_interchange, AStmt, NumLoops, + LoopHelpers, Body, OriginalInits)) + return StmtError(); + + // Delay interchange to when template is completely instantiated. + if (CurContext->isDependentContext()) + return OMPInterchangeDirective::Create(Context, StartLoc, EndLoc, Clauses, + NumLoops, AStmt, nullptr, nullptr); + + assert(LoopHelpers.size() == NumLoops && + "Expecting loop iteration space dimensionaly to match number of " + "affected loops"); + assert(OriginalInits.size() == NumLoops && + "Expecting loop iteration space dimensionaly to match number of " + "affected loops"); + + // Decode the permutation clause. + constexpr uint64_t Permutation[] = {1, 0}; + + // Find the affected loops. + SmallVector LoopStmts(NumLoops, nullptr); + collectLoopStmts(AStmt, LoopStmts); + + // Collect pre-init statements on the order before the permuation. + SmallVector PreInits; + for (auto I : llvm::seq(NumLoops)) { + OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; + + assert(LoopHelper.Counters.size() == 1 && + "Single-dimensional loop iteration space expected"); + auto *OrigCntVar = cast(LoopHelper.Counters.front()); + + std::string OrigVarName = OrigCntVar->getNameInfo().getAsString(); + addLoopPreInits(Context, LoopHelper, LoopStmts[I], OriginalInits[I], + PreInits); + } + + SmallVector PermutedIndVars(NumLoops); + CaptureVars CopyTransformer(SemaRef); + + // Create the permuted loops from the inside to the outside of the + // interchanged loop nest. Body of the innermost new loop is the original + // innermost body. + Stmt *Inner = Body; + for (auto TargetIdx : llvm::reverse(llvm::seq(NumLoops))) { + // Get the original loop that belongs to this new position. + uint64_t SourceIdx = Permutation[TargetIdx]; + OMPLoopBasedDirective::HelperExprs &SourceHelper = LoopHelpers[SourceIdx]; + Stmt *SourceLoopStmt = LoopStmts[SourceIdx]; + assert(SourceHelper.Counters.size() == 1 && + "Single-dimensional loop iteration space expected"); + auto *OrigCntVar = cast(SourceHelper.Counters.front()); + + // Normalized loop counter variable: From 0 to n-1, always an integer type. + DeclRefExpr *IterVarRef = cast(SourceHelper.IterationVarRef); + QualType IVTy = IterVarRef->getType(); + assert(IVTy->isIntegerType() && + "Expected the logical iteration counter to be an integer"); + + std::string OrigVarName = OrigCntVar->getNameInfo().getAsString(); + SourceLocation OrigVarLoc = IterVarRef->getExprLoc(); + + // Make a copy of the NumIterations expression for each use: By the AST + // constraints, every expression object in a DeclContext must be unique. + auto MakeNumIterations = [&CopyTransformer, &SourceHelper]() -> Expr * { + return AssertSuccess( + CopyTransformer.TransformExpr(SourceHelper.NumIterations)); + }; + + // Iteration variable for the permuted loop. Reuse the one from + // checkOpenMPLoop which will also be used to update the original loop + // variable. + SmallString<64> PermutedCntName(".permuted_"); + PermutedCntName.append({llvm::utostr(TargetIdx), ".iv.", OrigVarName}); + auto *PermutedCntDecl = cast(IterVarRef->getDecl()); + PermutedCntDecl->setDeclName( + &SemaRef.PP.getIdentifierTable().get(PermutedCntName)); + PermutedIndVars[TargetIdx] = PermutedCntDecl; + auto MakePermutedRef = [this, PermutedCntDecl, IVTy, OrigVarLoc]() { + return buildDeclRefExpr(SemaRef, PermutedCntDecl, IVTy, OrigVarLoc); + }; + + // For init-statement: + // \code + // auto .permuted_{target}.iv = 0 + // \endcode + ExprResult Zero = SemaRef.ActOnIntegerConstant(OrigVarLoc, 0); + if (!Zero.isUsable()) + return StmtError(); + SemaRef.AddInitializerToDecl(PermutedCntDecl, Zero.get(), + /*DirectInit=*/false); + StmtResult InitStmt = new (Context) + DeclStmt(DeclGroupRef(PermutedCntDecl), OrigCntVar->getBeginLoc(), + OrigCntVar->getEndLoc()); + if (!InitStmt.isUsable()) + return StmtError(); + + // For cond-expression: + // \code + // .permuted_{target}.iv < MakeNumIterations() + // \endcode + ExprResult CondExpr = + SemaRef.BuildBinOp(CurScope, SourceHelper.Cond->getExprLoc(), BO_LT, + MakePermutedRef(), MakeNumIterations()); + if (!CondExpr.isUsable()) + return StmtError(); + + // For incr-statement: + // \code + // ++.tile.iv + // \endcode + ExprResult IncrStmt = SemaRef.BuildUnaryOp( + CurScope, SourceHelper.Inc->getExprLoc(), UO_PreInc, MakePermutedRef()); + if (!IncrStmt.isUsable()) + return StmtError(); + + SmallVector BodyParts(SourceHelper.Updates.begin(), + SourceHelper.Updates.end()); + if (auto *SourceCXXFor = dyn_cast(SourceLoopStmt)) + BodyParts.push_back(SourceCXXFor->getLoopVarStmt()); + BodyParts.push_back(Inner); + Inner = CompoundStmt::Create(Context, BodyParts, FPOptionsOverride(), + Inner->getBeginLoc(), Inner->getEndLoc()); + Inner = new (Context) ForStmt( + Context, InitStmt.get(), CondExpr.get(), nullptr, IncrStmt.get(), Inner, + SourceHelper.Init->getBeginLoc(), SourceHelper.Init->getBeginLoc(), + SourceHelper.Inc->getEndLoc()); + } + + return OMPInterchangeDirective::Create(Context, StartLoc, EndLoc, Clauses, + NumLoops, AStmt, Inner, + buildPreInits(Context, PreInits)); +} + OMPClause *SemaOpenMP::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, @@ -18886,7 +19125,7 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, auto CurInit = Clause.inits().begin(); auto CurPrivate = Clause.privates().begin(); OpenMPLinearClauseKind LinKind = Clause.getModifier(); - for (Expr *RefExpr : Clause.varlists()) { + for (Expr *RefExpr : Clause.varlist()) { SourceLocation ELoc; SourceRange ERange; Expr *SimpleRefExpr = RefExpr; @@ -21656,7 +21895,9 @@ OMPClause *SemaOpenMP::ActOnOpenMPDefaultmapClause( bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || (getLangOpts().OpenMP >= 50 && KindLoc.isInvalid()); if (!isDefaultmapKind || !isDefaultmapModifier) { - StringRef KindValue = "'scalar', 'aggregate', 'pointer'"; + StringRef KindValue = getLangOpts().OpenMP < 52 + ? "'scalar', 'aggregate', 'pointer'" + : "'scalar', 'aggregate', 'pointer', 'all'"; if (getLangOpts().OpenMP == 50) { StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', " "'firstprivate', 'none', 'default'"; @@ -21700,7 +21941,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPDefaultmapClause( return nullptr; } } - if (Kind == OMPC_DEFAULTMAP_unknown) { + if (Kind == OMPC_DEFAULTMAP_unknown || Kind == OMPC_DEFAULTMAP_all) { // Variable category is not specified - mark all categories. DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); @@ -21773,7 +22014,7 @@ NamedDecl *SemaOpenMP::lookupOpenMPDeclareTargetName( SemaRef.CorrectTypo(Id, Sema::LookupOrdinaryName, CurScope, nullptr, CCC, Sema::CTK_ErrorRecovery)) { SemaRef.diagnoseTypo(Corrected, - PDiag(diag::err_undeclared_var_use_suggest) + SemaRef.PDiag(diag::err_undeclared_var_use_suggest) << Id.getName()); checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); return nullptr; @@ -22848,8 +23089,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPDoacrossClause( if (DSAStack->getCurrentDirective() == OMPD_ordered && DepType != OMPC_DOACROSS_source && DepType != OMPC_DOACROSS_sink && DepType != OMPC_DOACROSS_sink_omp_cur_iteration && - DepType != OMPC_DOACROSS_source_omp_cur_iteration && - DepType != OMPC_DOACROSS_source) { + DepType != OMPC_DOACROSS_source_omp_cur_iteration) { Diag(DepLoc, diag::err_omp_unexpected_clause_value) << "'source' or 'sink'" << getOpenMPClauseName(OMPC_doacross); return nullptr; diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 39af562f089b2..bce0bf497a952 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "CheckExprLifetime.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTLambda.h" #include "clang/AST/CXXInheritance.h" @@ -47,6 +48,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Casting.h" #include +#include #include #include #include @@ -6874,10 +6876,7 @@ void Sema::AddOverloadCandidate( Candidate.Viable = true; Candidate.RewriteKind = CandidateSet.getRewriteInfo().getRewriteKind(Function, PO); - Candidate.IsSurrogate = false; Candidate.IsADLCandidate = IsADLCandidate; - Candidate.IgnoreObjectArgument = false; - Candidate.TookAddressOfOverload = false; Candidate.ExplicitCallArguments = Args.size(); // Explicit functions are not actually candidates at all if we're not @@ -7439,8 +7438,6 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, Candidate.Function = Method; Candidate.RewriteKind = CandidateSet.getRewriteInfo().getRewriteKind(Method, PO); - Candidate.IsSurrogate = false; - Candidate.IgnoreObjectArgument = false; Candidate.TookAddressOfOverload = CandidateSet.getKind() == OverloadCandidateSet::CSK_AddressOfOverloadSet; Candidate.ExplicitCallArguments = Args.size(); @@ -7634,7 +7631,6 @@ void Sema::AddMethodTemplateCandidate( Candidate.IgnoreObjectArgument = cast(Candidate.Function)->isStatic() || ObjectType.isNull(); - Candidate.TookAddressOfOverload = false; Candidate.ExplicitCallArguments = Args.size(); if (Result == TemplateDeductionResult::NonDependentConversionFailure) Candidate.FailureKind = ovl_fail_bad_conversion; @@ -7722,7 +7718,6 @@ void Sema::AddTemplateOverloadCandidate( Candidate.IgnoreObjectArgument = isa(Candidate.Function) && !isa(Candidate.Function); - Candidate.TookAddressOfOverload = false; Candidate.ExplicitCallArguments = Args.size(); if (Result == TemplateDeductionResult::NonDependentConversionFailure) Candidate.FailureKind = ovl_fail_bad_conversion; @@ -7903,9 +7898,6 @@ void Sema::AddConversionCandidate( OverloadCandidate &Candidate = CandidateSet.addCandidate(1); Candidate.FoundDecl = FoundDecl; Candidate.Function = Conversion; - Candidate.IsSurrogate = false; - Candidate.IgnoreObjectArgument = false; - Candidate.TookAddressOfOverload = false; Candidate.FinalConversion.setAsIdentityConversion(); Candidate.FinalConversion.setFromType(ConvType); Candidate.FinalConversion.setAllToTypes(ToType); @@ -8101,9 +8093,6 @@ void Sema::AddTemplateConversionCandidate( Candidate.Function = FunctionTemplate->getTemplatedDecl(); Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_deduction; - Candidate.IsSurrogate = false; - Candidate.IgnoreObjectArgument = false; - Candidate.TookAddressOfOverload = false; Candidate.ExplicitCallArguments = 1; Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, Info); @@ -8136,10 +8125,8 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion, Candidate.FoundDecl = FoundDecl; Candidate.Function = nullptr; Candidate.Surrogate = Conversion; - Candidate.Viable = true; Candidate.IsSurrogate = true; - Candidate.IgnoreObjectArgument = false; - Candidate.TookAddressOfOverload = false; + Candidate.Viable = true; Candidate.ExplicitCallArguments = Args.size(); // Determine the implicit conversion sequence for the implicit @@ -8345,9 +8332,6 @@ void Sema::AddBuiltinCandidate(QualType *ParamTys, ArrayRef Args, OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size()); Candidate.FoundDecl = DeclAccessPair::make(nullptr, AS_none); Candidate.Function = nullptr; - Candidate.IsSurrogate = false; - Candidate.IgnoreObjectArgument = false; - Candidate.TookAddressOfOverload = false; std::copy(ParamTys, ParamTys + Args.size(), Candidate.BuiltinParamTypes); // Determine the implicit conversion sequences for each of the @@ -10012,8 +9996,9 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name, CandEnd = CandidateSet.end(); Cand != CandEnd; ++Cand) if (Cand->Function) { - Fns.erase(Cand->Function); - if (FunctionTemplateDecl *FunTmpl = Cand->Function->getPrimaryTemplate()) + FunctionDecl *Fn = Cand->Function; + Fns.erase(Fn); + if (FunctionTemplateDecl *FunTmpl = Fn->getPrimaryTemplate()) Fns.erase(FunTmpl); } @@ -11175,7 +11160,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, if (isa(Fn) && !isa(Fn)) { if (I == 0) isObjectArgument = true; - else + else if (!Fn->hasCXXExplicitFunctionObjectParameter()) I--; } @@ -11376,8 +11361,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, } } - if (TakingCandidateAddress && - !checkAddressOfCandidateIsAvailable(S, Cand->Function)) + if (TakingCandidateAddress && !checkAddressOfCandidateIsAvailable(S, Fn)) return; // Emit the generic diagnostic and, optionally, add the hints to it. @@ -11403,6 +11387,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, /// over a candidate in any candidate set. static bool CheckArityMismatch(Sema &S, OverloadCandidate *Cand, unsigned NumArgs, bool IsAddressOf = false) { + assert(Cand->Function && "Candidate is required to be a function."); FunctionDecl *Fn = Cand->Function; unsigned MinParams = Fn->getMinRequiredExplicitArguments() + ((IsAddressOf && !Fn->isStatic()) ? 1 : 0); @@ -11493,8 +11478,10 @@ static void DiagnoseArityMismatch(Sema &S, NamedDecl *Found, Decl *D, /// Arity mismatch diagnosis specific to a function overload candidate. static void DiagnoseArityMismatch(Sema &S, OverloadCandidate *Cand, unsigned NumFormalArgs) { + assert(Cand->Function && "Candidate must be a function"); + FunctionDecl *Fn = Cand->Function; if (!CheckArityMismatch(S, Cand, NumFormalArgs, Cand->TookAddressOfOverload)) - DiagnoseArityMismatch(S, Cand->FoundDecl, Cand->Function, NumFormalArgs, + DiagnoseArityMismatch(S, Cand->FoundDecl, Fn, NumFormalArgs, Cand->TookAddressOfOverload); } @@ -11794,19 +11781,22 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, static void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand, unsigned NumArgs, bool TakingCandidateAddress) { + assert(Cand->Function && "Candidate must be a function"); + FunctionDecl *Fn = Cand->Function; TemplateDeductionResult TDK = Cand->DeductionFailure.getResult(); if (TDK == TemplateDeductionResult::TooFewArguments || TDK == TemplateDeductionResult::TooManyArguments) { if (CheckArityMismatch(S, Cand, NumArgs)) return; } - DiagnoseBadDeduction(S, Cand->FoundDecl, Cand->Function, // pattern + DiagnoseBadDeduction(S, Cand->FoundDecl, Fn, // pattern Cand->DeductionFailure, NumArgs, TakingCandidateAddress); } /// CUDA: diagnose an invalid call across targets. static void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) { FunctionDecl *Caller = S.getCurFunctionDecl(/*AllowLambda=*/true); + assert(Cand->Function && "Candidate must be a Function."); FunctionDecl *Callee = Cand->Function; CUDAFunctionTarget CallerTarget = S.CUDA().IdentifyTarget(Caller), @@ -11864,6 +11854,7 @@ static void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) { } static void DiagnoseFailedEnableIfAttr(Sema &S, OverloadCandidate *Cand) { + assert(Cand->Function && "Candidate must be a function"); FunctionDecl *Callee = Cand->Function; EnableIfAttr *Attr = static_cast(Cand->DeductionFailure.Data); @@ -11873,11 +11864,13 @@ static void DiagnoseFailedEnableIfAttr(Sema &S, OverloadCandidate *Cand) { } static void DiagnoseFailedExplicitSpec(Sema &S, OverloadCandidate *Cand) { - ExplicitSpecifier ES = ExplicitSpecifier::getFromDecl(Cand->Function); + assert(Cand->Function && "Candidate must be a function"); + FunctionDecl *Fn = Cand->Function; + ExplicitSpecifier ES = ExplicitSpecifier::getFromDecl(Fn); assert(ES.isExplicit() && "not an explicit candidate"); unsigned Kind; - switch (Cand->Function->getDeclKind()) { + switch (Fn->getDeclKind()) { case Decl::Kind::CXXConstructor: Kind = 0; break; @@ -11885,7 +11878,7 @@ static void DiagnoseFailedExplicitSpec(Sema &S, OverloadCandidate *Cand) { Kind = 1; break; case Decl::Kind::CXXDeductionGuide: - Kind = Cand->Function->isImplicit() ? 0 : 2; + Kind = Fn->isImplicit() ? 0 : 2; break; default: llvm_unreachable("invalid Decl"); @@ -11895,7 +11888,7 @@ static void DiagnoseFailedExplicitSpec(Sema &S, OverloadCandidate *Cand) { // (particularly an out-of-class definition) will typically lack the // 'explicit' specifier. // FIXME: This is probably a good thing to do for all 'candidate' notes. - FunctionDecl *First = Cand->Function->getFirstDecl(); + FunctionDecl *First = Fn->getFirstDecl(); if (FunctionDecl *Pattern = First->getTemplateInstantiationPattern()) First = Pattern->getFirstDecl(); @@ -11964,6 +11957,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, unsigned NumArgs, bool TakingCandidateAddress, LangAS CtorDestAS = LangAS::Default) { + assert(Cand->Function && "Candidate must be a function"); FunctionDecl *Fn = Cand->Function; if (shouldSkipNotingLambdaConversionDecl(Fn)) return; @@ -11978,8 +11972,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, // Skip implicit member functions when trying to resolve // the address of a an overload set for a function pointer. if (Cand->TookAddressOfOverload && - !Cand->Function->hasCXXExplicitFunctionObjectParameter() && - !Cand->Function->isStatic()) + !Fn->hasCXXExplicitFunctionObjectParameter() && !Fn->isStatic()) return; // Note deleted candidates, but only if they're viable. @@ -12077,7 +12070,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, return; case ovl_fail_addr_not_available: { - bool Available = checkAddressOfCandidateIsAvailable(S, Cand->Function); + bool Available = checkAddressOfCandidateIsAvailable(S, Fn); (void)Available; assert(!Available); break; @@ -14741,10 +14734,12 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, FnDecl)) return ExprError(); - // Check for a self move. - if (Op == OO_Equal) + if (Op == OO_Equal) { + // Check for a self move. DiagnoseSelfMove(Args[0], Args[1], OpLoc); - + // lifetime check. + checkExprLifetime(*this, AssignedEntity{Args[0]}, Args[1]); + } if (ImplicitThis) { QualType ThisType = Context.getPointerType(ImplicitThis->getType()); QualType ThisTypeFromDecl = Context.getPointerType( diff --git a/clang/lib/Sema/SemaPPC.cpp b/clang/lib/Sema/SemaPPC.cpp index 99f46b12e6968..5b764ed396ebc 100644 --- a/clang/lib/Sema/SemaPPC.cpp +++ b/clang/lib/Sema/SemaPPC.cpp @@ -93,7 +93,6 @@ bool SemaPPC::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall) { ASTContext &Context = getASTContext(); - unsigned i = 0, l = 0, u = 0; bool IsTarget64Bit = TI.getTypeWidth(TI.getIntPtrType()) == 64; llvm::APSInt Result; @@ -248,7 +247,7 @@ bool SemaPPC::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, return BuiltinPPCMMACall(TheCall, BuiltinID, Types); #include "clang/Basic/BuiltinsPPC.def" } - return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u); + llvm_unreachable("must return from switch"); } // Check if the given type is a non-pointer PPC MMA type. This function is used diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index f736de01e6339..b6ce0d9ecfb50 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -634,7 +634,6 @@ class CallExprFinder : public ConstEvaluatedExprVisitor { static Attr *handleNoMergeAttr(Sema &S, Stmt *St, const ParsedAttr &A, SourceRange Range) { - NoMergeAttr NMA(S.Context, A); CallExprFinder CEF(S, St); if (!CEF.foundCallExpr() && !CEF.foundAsmStmt()) { @@ -646,6 +645,19 @@ static Attr *handleNoMergeAttr(Sema &S, Stmt *St, const ParsedAttr &A, return ::new (S.Context) NoMergeAttr(S.Context, A); } +static Attr *handleNoConvergentAttr(Sema &S, Stmt *St, const ParsedAttr &A, + SourceRange Range) { + CallExprFinder CEF(S, St); + + if (!CEF.foundCallExpr() && !CEF.foundAsmStmt()) { + S.Diag(St->getBeginLoc(), diag::warn_attribute_ignored_no_calls_in_stmt) + << A; + return nullptr; + } + + return ::new (S.Context) NoConvergentAttr(S.Context, A); +} + template static bool CheckStmtInlineAttr(Sema &SemaRef, const Stmt *OrigSt, const Stmt *CurSt, @@ -1138,13 +1150,6 @@ static Attr *handleHLSLLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A, unsigned UnrollFactor = 0; if (A.getNumArgs() == 1) { - - if (A.isArgIdent(0)) { - S.Diag(A.getLoc(), diag::err_attribute_argument_type) - << A << AANT_ArgumentIntegerConstant << A.getRange(); - return nullptr; - } - Expr *E = A.getArgAsExpr(0); if (S.CheckLoopHintExpr(E, St->getBeginLoc(), @@ -1239,6 +1244,8 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A, return handleCodeAlignAttr(S, St, A); case ParsedAttr::AT_MSConstexpr: return handleMSConstexprAttr(S, St, A, Range); + case ParsedAttr::AT_NoConvergent: + return handleNoConvergentAttr(S, St, A, Range); default: // N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a // declaration attribute is not written on a statement, but this code is diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 9d96201625389..c22e329bef2b9 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -3344,6 +3344,10 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, *this, /*PointOfInstantiation=*/TemplateLoc, /*Entity=*/AliasTemplate, /*TemplateArgs=*/TemplateArgLists.getInnermost()); + + // Diagnose uses of this alias. + (void)DiagnoseUseOfDecl(AliasTemplate, TemplateLoc); + if (Inst.isInvalid()) return QualType(); @@ -6715,7 +6719,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, auto *VD = const_cast(Base.dyn_cast()); // For a non-type template-parameter of pointer or reference type, // the value of the constant expression shall not refer to - assert(ParamType->isPointerType() || ParamType->isReferenceType() || + assert(ParamType->isPointerOrReferenceType() || ParamType->isNullPtrType()); // -- a temporary object // -- a string literal diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index b7b857ebf804b..db7f233dcef73 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -951,9 +951,11 @@ class PackDeductionScope { // Skip over the pack elements that were expanded into separate arguments. // If we partially expanded, this is the number of partial arguments. + // FIXME: `&& FixedNumExpansions` is a workaround for UB described in + // https://github.com/llvm/llvm-project/issues/100095 if (IsPartiallyExpanded) PackElements += NumPartialPackArgs; - else if (IsExpanded) + else if (IsExpanded && FixedNumExpansions) PackElements += *FixedNumExpansions; for (auto &Pack : Packs) { diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp index 7dff2c8f98589..545da21183c3c 100644 --- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp +++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp @@ -39,6 +39,7 @@ #include "clang/Sema/Overload.h" #include "clang/Sema/Ownership.h" #include "clang/Sema/Scope.h" +#include "clang/Sema/SemaInternal.h" #include "clang/Sema/Template.h" #include "clang/Sema/TemplateDeduction.h" #include "llvm/ADT/ArrayRef.h" @@ -241,11 +242,10 @@ NamedDecl *buildDeductionGuide( } // Transform a given template type parameter `TTP`. -TemplateTypeParmDecl * -transformTemplateTypeParam(Sema &SemaRef, DeclContext *DC, - TemplateTypeParmDecl *TTP, - MultiLevelTemplateArgumentList &Args, - unsigned NewDepth, unsigned NewIndex) { +TemplateTypeParmDecl *transformTemplateTypeParam( + Sema &SemaRef, DeclContext *DC, TemplateTypeParmDecl *TTP, + MultiLevelTemplateArgumentList &Args, unsigned NewDepth, unsigned NewIndex, + bool EvaluateConstraint) { // TemplateTypeParmDecl's index cannot be changed after creation, so // substitute it directly. auto *NewTTP = TemplateTypeParmDecl::Create( @@ -257,7 +257,7 @@ transformTemplateTypeParam(Sema &SemaRef, DeclContext *DC, : std::nullopt); if (const auto *TC = TTP->getTypeConstraint()) SemaRef.SubstTypeConstraint(NewTTP, TC, Args, - /*EvaluateConstraint=*/true); + /*EvaluateConstraint=*/EvaluateConstraint); if (TTP->hasDefaultArgument()) { TemplateArgumentLoc InstantiatedDefaultArg; if (!SemaRef.SubstTemplateArgument( @@ -284,6 +284,22 @@ transformTemplateParam(Sema &SemaRef, DeclContext *DC, return NewParam; } +NamedDecl *transformTemplateParameter(Sema &SemaRef, DeclContext *DC, + NamedDecl *TemplateParam, + MultiLevelTemplateArgumentList &Args, + unsigned NewIndex, unsigned NewDepth, + bool EvaluateConstraint = true) { + if (auto *TTP = dyn_cast(TemplateParam)) + return transformTemplateTypeParam( + SemaRef, DC, TTP, Args, NewDepth, NewIndex, + /*EvaluateConstraint=*/EvaluateConstraint); + if (auto *TTP = dyn_cast(TemplateParam)) + return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex, NewDepth); + if (auto *NTTP = dyn_cast(TemplateParam)) + return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex, NewDepth); + llvm_unreachable("Unhandled template parameter types"); +} + /// Transform to convert portions of a constructor declaration into the /// corresponding deduction guide, per C++1z [over.match.class.deduct]p1. struct ConvertConstructorToDeductionGuideTransform { @@ -358,29 +374,28 @@ struct ConvertConstructorToDeductionGuideTransform { Args.addOuterRetainedLevel(); if (NestedPattern) Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth()); - NamedDecl *NewParam = transformTemplateParameter(Param, Args); + auto [Depth, Index] = getDepthAndIndex(Param); + NamedDecl *NewParam = transformTemplateParameter( + SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment, Depth - 1); if (!NewParam) return nullptr; // Constraints require that we substitute depth-1 arguments // to match depths when substituted for evaluation later - Depth1Args.push_back(SemaRef.Context.getCanonicalTemplateArgument( - SemaRef.Context.getInjectedTemplateArg(NewParam))); + Depth1Args.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam)); if (NestedPattern) { - TemplateDeclInstantiator Instantiator(SemaRef, DC, - OuterInstantiationArgs); - Instantiator.setEvaluateConstraints(false); - SemaRef.runWithSufficientStackSpace(NewParam->getLocation(), [&] { - NewParam = cast(Instantiator.Visit(NewParam)); - }); + auto [Depth, Index] = getDepthAndIndex(NewParam); + NewParam = transformTemplateParameter( + SemaRef, DC, NewParam, OuterInstantiationArgs, Index, + Depth - OuterInstantiationArgs.getNumSubstitutedLevels(), + /*EvaluateConstraint=*/false); } assert(NewParam->getTemplateDepth() == 0 && "Unexpected template parameter depth"); AllParams.push_back(NewParam); - SubstArgs.push_back(SemaRef.Context.getCanonicalTemplateArgument( - SemaRef.Context.getInjectedTemplateArg(NewParam))); + SubstArgs.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam)); } // Substitute new template parameters into requires-clause if present. @@ -481,25 +496,6 @@ struct ConvertConstructorToDeductionGuideTransform { } private: - /// Transform a constructor template parameter into a deduction guide template - /// parameter, rebuilding any internal references to earlier parameters and - /// renumbering as we go. - NamedDecl *transformTemplateParameter(NamedDecl *TemplateParam, - MultiLevelTemplateArgumentList &Args) { - if (auto *TTP = dyn_cast(TemplateParam)) - return transformTemplateTypeParam( - SemaRef, DC, TTP, Args, TTP->getDepth() - 1, - Depth1IndexAdjustment + TTP->getIndex()); - if (auto *TTP = dyn_cast(TemplateParam)) - return transformTemplateParam(SemaRef, DC, TTP, Args, - Depth1IndexAdjustment + TTP->getIndex(), - TTP->getDepth() - 1); - auto *NTTP = cast(TemplateParam); - return transformTemplateParam(SemaRef, DC, NTTP, Args, - Depth1IndexAdjustment + NTTP->getIndex(), - NTTP->getDepth() - 1); - } - QualType transformFunctionProtoType( TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, SmallVectorImpl &Params, @@ -636,26 +632,6 @@ struct ConvertConstructorToDeductionGuideTransform { } }; -unsigned getTemplateParameterDepth(NamedDecl *TemplateParam) { - if (auto *TTP = dyn_cast(TemplateParam)) - return TTP->getDepth(); - if (auto *TTP = dyn_cast(TemplateParam)) - return TTP->getDepth(); - if (auto *NTTP = dyn_cast(TemplateParam)) - return NTTP->getDepth(); - llvm_unreachable("Unhandled template parameter types"); -} - -unsigned getTemplateParameterIndex(NamedDecl *TemplateParam) { - if (auto *TTP = dyn_cast(TemplateParam)) - return TTP->getIndex(); - if (auto *TTP = dyn_cast(TemplateParam)) - return TTP->getIndex(); - if (auto *NTTP = dyn_cast(TemplateParam)) - return NTTP->getIndex(); - llvm_unreachable("Unhandled template parameter types"); -} - // Find all template parameters that appear in the given DeducedArgs. // Return the indices of the template parameters in the TemplateParams. SmallVector TemplateParamsReferencedInTemplateArgumentList( @@ -691,8 +667,10 @@ SmallVector TemplateParamsReferencedInTemplateArgumentList( void MarkAppeared(NamedDecl *ND) { if (llvm::isa(ND)) - Mark(getTemplateParameterDepth(ND), getTemplateParameterIndex(ND)); + TemplateTemplateParmDecl>(ND)) { + auto [Depth, Index] = getDepthAndIndex(ND); + Mark(Depth, Index); + } } void Mark(unsigned Depth, unsigned Index) { if (Index < TemplateParamList->size() && @@ -724,20 +702,6 @@ bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) { return false; } -NamedDecl *transformTemplateParameter(Sema &SemaRef, DeclContext *DC, - NamedDecl *TemplateParam, - MultiLevelTemplateArgumentList &Args, - unsigned NewIndex, unsigned NewDepth) { - if (auto *TTP = dyn_cast(TemplateParam)) - return transformTemplateTypeParam(SemaRef, DC, TTP, Args, NewDepth, - NewIndex); - if (auto *TTP = dyn_cast(TemplateParam)) - return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex, NewDepth); - if (auto *NTTP = dyn_cast(TemplateParam)) - return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex, NewDepth); - llvm_unreachable("Unhandled template parameter types"); -} - // Build the associated constraints for the alias deduction guides. // C++ [over.match.class.deduct]p3.3: // The associated constraints ([temp.constr.decl]) are the conjunction of the @@ -793,10 +757,10 @@ buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F, NamedDecl *NewParam = transformTemplateParameter( SemaRef, AliasTemplate->getDeclContext(), TP, Args, /*NewIndex=*/AdjustedAliasTemplateArgs.size(), - getTemplateParameterDepth(TP) + AdjustDepth); + getDepthAndIndex(TP).first + AdjustDepth); - auto NewTemplateArgument = Context.getCanonicalTemplateArgument( - Context.getInjectedTemplateArg(NewParam)); + TemplateArgument NewTemplateArgument = + Context.getInjectedTemplateArg(NewParam); AdjustedAliasTemplateArgs.push_back(NewTemplateArgument); } // Template arguments used to transform the template arguments in @@ -816,14 +780,14 @@ buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F, Args.setKind(TemplateSubstitutionKind::Rewrite); Args.addOuterTemplateArguments(TemplateArgsForBuildingRC); // Rebuild the template parameter with updated depth and index. - NamedDecl *NewParam = transformTemplateParameter( - SemaRef, F->getDeclContext(), TP, Args, - /*NewIndex=*/FirstUndeducedParamIdx, - getTemplateParameterDepth(TP) + AdjustDepth); + NamedDecl *NewParam = + transformTemplateParameter(SemaRef, F->getDeclContext(), TP, Args, + /*NewIndex=*/FirstUndeducedParamIdx, + getDepthAndIndex(TP).first + AdjustDepth); FirstUndeducedParamIdx += 1; assert(TemplateArgsForBuildingRC[Index].isNull()); - TemplateArgsForBuildingRC[Index] = Context.getCanonicalTemplateArgument( - Context.getInjectedTemplateArg(NewParam)); + TemplateArgsForBuildingRC[Index] = + Context.getInjectedTemplateArg(NewParam); continue; } TemplateArgumentLoc Input = @@ -921,10 +885,10 @@ Expr *buildIsDeducibleConstraint(Sema &SemaRef, NamedDecl *NewParam = transformTemplateParameter( SemaRef, AliasTemplate->getDeclContext(), TP, Args, /*NewIndex=*/TransformedTemplateArgs.size(), - getTemplateParameterDepth(TP) + AdjustDepth); + getDepthAndIndex(TP).first + AdjustDepth); - auto NewTemplateArgument = Context.getCanonicalTemplateArgument( - Context.getInjectedTemplateArg(NewParam)); + TemplateArgument NewTemplateArgument = + Context.getInjectedTemplateArg(NewParam); TransformedTemplateArgs.push_back(NewTemplateArgument); } // Transformed the ReturnType to restore the uninstantiated depth. @@ -1083,12 +1047,11 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef, Args.addOuterTemplateArguments(TransformedDeducedAliasArgs); NamedDecl *NewParam = transformTemplateParameter( SemaRef, AliasTemplate->getDeclContext(), TP, Args, - /*NewIndex=*/FPrimeTemplateParams.size(), - getTemplateParameterDepth(TP)); + /*NewIndex=*/FPrimeTemplateParams.size(), getDepthAndIndex(TP).first); FPrimeTemplateParams.push_back(NewParam); - auto NewTemplateArgument = Context.getCanonicalTemplateArgument( - Context.getInjectedTemplateArg(NewParam)); + TemplateArgument NewTemplateArgument = + Context.getInjectedTemplateArg(NewParam); TransformedDeducedAliasArgs[AliasTemplateParamIdx] = NewTemplateArgument; } unsigned FirstUndeducedParamIdx = FPrimeTemplateParams.size(); @@ -1103,14 +1066,13 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef, Args.addOuterTemplateArguments(TemplateArgsForBuildingFPrime); NamedDecl *NewParam = transformTemplateParameter( SemaRef, F->getDeclContext(), TP, Args, FPrimeTemplateParams.size(), - getTemplateParameterDepth(TP)); + getDepthAndIndex(TP).first); FPrimeTemplateParams.push_back(NewParam); assert(TemplateArgsForBuildingFPrime[FTemplateParamIdx].isNull() && "The argument must be null before setting"); TemplateArgsForBuildingFPrime[FTemplateParamIdx] = - Context.getCanonicalTemplateArgument( - Context.getInjectedTemplateArg(NewParam)); + Context.getInjectedTemplateArg(NewParam); } // To form a deduction guide f' from f, we leverage clang's instantiation diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 10e555e313de7..821dbae2aff13 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2673,16 +2673,12 @@ createSubstDiag(Sema &S, TemplateDeductionInfo &Info, } else { ErrorLoc = Info.getLocation(); } - char *MessageBuf = new (S.Context) char[Message.size()]; - std::copy(Message.begin(), Message.end(), MessageBuf); SmallString<128> Entity; llvm::raw_svector_ostream OS(Entity); Printer(OS); - char *EntityBuf = new (S.Context) char[Entity.size()]; - std::copy(Entity.begin(), Entity.end(), EntityBuf); - return new (S.Context) concepts::Requirement::SubstitutionDiagnostic{ - StringRef(EntityBuf, Entity.size()), ErrorLoc, - StringRef(MessageBuf, Message.size())}; + const ASTContext &C = S.Context; + return new (C) concepts::Requirement::SubstitutionDiagnostic{ + C.backupStr(Entity), ErrorLoc, C.backupStr(Message)}; } concepts::Requirement::SubstitutionDiagnostic * @@ -2691,10 +2687,9 @@ concepts::createSubstDiagAt(Sema &S, SourceLocation Location, SmallString<128> Entity; llvm::raw_svector_ostream OS(Entity); Printer(OS); - char *EntityBuf = new (S.Context) char[Entity.size()]; - llvm::copy(Entity, EntityBuf); - return new (S.Context) concepts::Requirement::SubstitutionDiagnostic{ - /*SubstitutedEntity=*/StringRef(EntityBuf, Entity.size()), + const ASTContext &C = S.Context; + return new (C) concepts::Requirement::SubstitutionDiagnostic{ + /*SubstitutedEntity=*/C.backupStr(Entity), /*DiagLoc=*/Location, /*DiagMessage=*/StringRef()}; } @@ -2870,23 +2865,21 @@ TemplateInstantiator::TransformNestedRequirement( assert(!Trap.hasErrorOccurred() && "Substitution failures must be handled " "by CheckConstraintSatisfaction."); } + ASTContext &C = SemaRef.Context; if (TransConstraint.isUsable() && TransConstraint.get()->isInstantiationDependent()) - return new (SemaRef.Context) - concepts::NestedRequirement(TransConstraint.get()); + return new (C) concepts::NestedRequirement(TransConstraint.get()); if (TransConstraint.isInvalid() || !TransConstraint.get() || Satisfaction.HasSubstitutionFailure()) { SmallString<128> Entity; llvm::raw_svector_ostream OS(Entity); Req->getConstraintExpr()->printPretty(OS, nullptr, SemaRef.getPrintingPolicy()); - char *EntityBuf = new (SemaRef.Context) char[Entity.size()]; - std::copy(Entity.begin(), Entity.end(), EntityBuf); - return new (SemaRef.Context) concepts::NestedRequirement( - SemaRef.Context, StringRef(EntityBuf, Entity.size()), Satisfaction); + return new (C) concepts::NestedRequirement( + SemaRef.Context, C.backupStr(Entity), Satisfaction); } - return new (SemaRef.Context) concepts::NestedRequirement( - SemaRef.Context, TransConstraint.get(), Satisfaction); + return new (C) + concepts::NestedRequirement(C, TransConstraint.get(), Satisfaction); } TypeSourceInfo *Sema::SubstType(TypeSourceInfo *T, @@ -3523,11 +3516,16 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, return true; llvm::TimeTraceScope TimeScope("InstantiateClass", [&]() { - std::string Name; - llvm::raw_string_ostream OS(Name); + llvm::TimeTraceMetadata M; + llvm::raw_string_ostream OS(M.Detail); Instantiation->getNameForDiagnostic(OS, getPrintingPolicy(), /*Qualified=*/true); - return Name; + if (llvm::isTimeTraceVerbose()) { + auto Loc = SourceMgr.getExpansionLoc(Instantiation->getLocation()); + M.File = SourceMgr.getFilename(Loc); + M.Line = SourceMgr.getExpansionLineNumber(Loc); + } + return M; }); Pattern = PatternDef; diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 8731602be0db6..27c07de65378b 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -331,7 +331,7 @@ instantiateDependentModeAttr(Sema &S, static void instantiateOMPDeclareSimdDeclAttr( Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const OMPDeclareSimdDeclAttr &Attr, Decl *New) { - // Allow 'this' in clauses with varlists. + // Allow 'this' in clauses with varlist. if (auto *FTD = dyn_cast(New)) New = FTD->getTemplatedDecl(); auto *FD = cast(New); @@ -414,7 +414,7 @@ static void instantiateOMPDeclareSimdDeclAttr( static void instantiateOMPDeclareVariantAttr( Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const OMPDeclareVariantAttr &Attr, Decl *New) { - // Allow 'this' in clauses with varlists. + // Allow 'this' in clauses with varlist. if (auto *FTD = dyn_cast(New)) New = FTD->getTemplatedDecl(); auto *FD = cast(New); @@ -4108,7 +4108,7 @@ Decl *TemplateDeclInstantiator::VisitUsingPackDecl(UsingPackDecl *D) { Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl( OMPThreadPrivateDecl *D) { SmallVector Vars; - for (auto *I : D->varlists()) { + for (auto *I : D->varlist()) { Expr *Var = SemaRef.SubstExpr(I, TemplateArgs).get(); assert(isa(Var) && "threadprivate arg is not a DeclRefExpr"); Vars.push_back(Var); @@ -4125,7 +4125,7 @@ Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl( Decl *TemplateDeclInstantiator::VisitOMPAllocateDecl(OMPAllocateDecl *D) { SmallVector Vars; - for (auto *I : D->varlists()) { + for (auto *I : D->varlist()) { Expr *Var = SemaRef.SubstExpr(I, TemplateArgs).get(); assert(isa(Var) && "allocate arg is not a DeclRefExpr"); Vars.push_back(Var); @@ -4302,7 +4302,7 @@ TemplateDeclInstantiator::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) { for (OMPClause *C : D->clauselists()) { auto *OldC = cast(C); SmallVector NewVars; - for (Expr *OE : OldC->varlists()) { + for (Expr *OE : OldC->varlist()) { Expr *NE = SemaRef.SubstExpr(OE, TemplateArgs).get(); if (!NE) { IsCorrect = false; @@ -5486,11 +5486,16 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, } llvm::TimeTraceScope TimeScope("InstantiateFunction", [&]() { - std::string Name; - llvm::raw_string_ostream OS(Name); + llvm::TimeTraceMetadata M; + llvm::raw_string_ostream OS(M.Detail); Function->getNameForDiagnostic(OS, getPrintingPolicy(), /*Qualified=*/true); - return Name; + if (llvm::isTimeTraceVerbose()) { + auto Loc = SourceMgr.getExpansionLoc(Function->getLocation()); + M.File = SourceMgr.getFilename(Loc); + M.Line = SourceMgr.getExpansionLineNumber(Loc); + } + return M; }); // If we're performing recursive template instantiation, create our own @@ -6761,7 +6766,12 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, getTrivialTemplateArgumentLoc(UnpackedArg, QualType(), Loc)); } QualType T = CheckTemplateIdType(TemplateName(TD), Loc, Args); - if (T.isNull()) + // We may get a non-null type with errors, in which case + // `getAsCXXRecordDecl` will return `nullptr`. For instance, this + // happens when one of the template arguments is an invalid + // expression. We return early to avoid triggering the assertion + // about the `CodeSynthesisContext`. + if (T.isNull() || T->containsErrors()) return nullptr; CXXRecordDecl *SubstRecord = T->getAsCXXRecordDecl(); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index e3383f3623bcd..570aa10a58019 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -6389,11 +6389,10 @@ TypeResult Sema::ActOnTypeName(Declarator &D) { CheckExtraCXXDefaultArguments(D); } - if (const AutoType *AutoT = T->getAs()) - CheckConstrainedAuto( - AutoT, - TInfo->getTypeLoc().getContainedAutoTypeLoc().getConceptNameLoc()); - + if (AutoTypeLoc TL = TInfo->getTypeLoc().getContainedAutoTypeLoc()) { + const AutoType *AT = TL.getTypePtr(); + CheckConstrainedAuto(AT, TL.getConceptNameLoc()); + } return CreateParsedType(T, TInfo); } diff --git a/clang/lib/Sema/SemaX86.cpp b/clang/lib/Sema/SemaX86.cpp index be26454ce909d..8f9057bbaf259 100644 --- a/clang/lib/Sema/SemaX86.cpp +++ b/clang/lib/Sema/SemaX86.cpp @@ -502,7 +502,6 @@ bool SemaX86::CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, switch (BuiltinID) { default: return false; - case X86::BI__builtin_ia32_vec_ext_v2si: case X86::BI__builtin_ia32_vec_ext_v2di: case X86::BI__builtin_ia32_vextractf128_pd256: case X86::BI__builtin_ia32_vextractf128_ps256: diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 34c92de087c1c..98ff398344b67 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1669,15 +1669,15 @@ class TreeTransform { /// /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildOMPExecutableDirective( - OpenMPDirectiveKind Kind, DeclarationNameInfo DirName, - OpenMPDirectiveKind CancelRegion, ArrayRef Clauses, - Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - OpenMPDirectiveKind PrevMappedDirective = OMPD_unknown) { + StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind, + DeclarationNameInfo DirName, + OpenMPDirectiveKind CancelRegion, + ArrayRef Clauses, + Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc) { return getSema().OpenMP().ActOnOpenMPExecutableDirective( - Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc, - PrevMappedDirective); + Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc); } /// Build a new OpenMP 'if' clause. @@ -9210,8 +9210,7 @@ StmtResult TreeTransform::TransformOMPExecutableDirective( return getDerived().RebuildOMPExecutableDirective( D->getDirectiveKind(), DirName, CancelRegion, TClauses, - AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc(), - D->getMappedDirective()); + AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc()); } template @@ -9267,6 +9266,28 @@ TreeTransform::TransformOMPUnrollDirective(OMPUnrollDirective *D) { return Res; } +template +StmtResult +TreeTransform::TransformOMPReverseDirective(OMPReverseDirective *D) { + DeclarationNameInfo DirName; + getDerived().getSema().OpenMP().StartOpenMPDSABlock( + D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc()); + StmtResult Res = getDerived().TransformOMPExecutableDirective(D); + getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get()); + return Res; +} + +template +StmtResult TreeTransform::TransformOMPInterchangeDirective( + OMPInterchangeDirective *D) { + DeclarationNameInfo DirName; + getDerived().getSema().OpenMP().StartOpenMPDSABlock( + D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc()); + StmtResult Res = getDerived().TransformOMPExecutableDirective(D); + getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get()); + return Res; +} + template StmtResult TreeTransform::TransformOMPForDirective(OMPForDirective *D) { @@ -10316,7 +10337,7 @@ OMPClause *TreeTransform::TransformOMPInitClause(OMPInitClause *C) { OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync()); InteropInfo.PreferTypes.reserve(C->varlist_size() - 1); - for (Expr *E : llvm::drop_begin(C->varlists())) { + for (Expr *E : llvm::drop_begin(C->varlist())) { ExprResult ER = getDerived().TransformExpr(cast(E)); if (ER.isInvalid()) return nullptr; @@ -10454,7 +10475,7 @@ OMPClause * TreeTransform::TransformOMPPrivateClause(OMPPrivateClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -10469,7 +10490,7 @@ OMPClause *TreeTransform::TransformOMPFirstprivateClause( OMPFirstprivateClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -10484,7 +10505,7 @@ OMPClause * TreeTransform::TransformOMPLastprivateClause(OMPLastprivateClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -10500,7 +10521,7 @@ OMPClause * TreeTransform::TransformOMPSharedClause(OMPSharedClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -10515,7 +10536,7 @@ OMPClause * TreeTransform::TransformOMPReductionClause(OMPReductionClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -10562,7 +10583,7 @@ OMPClause *TreeTransform::TransformOMPTaskReductionClause( OMPTaskReductionClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -10608,7 +10629,7 @@ OMPClause * TreeTransform::TransformOMPInReductionClause(OMPInReductionClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -10654,7 +10675,7 @@ OMPClause * TreeTransform::TransformOMPLinearClause(OMPLinearClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -10674,7 +10695,7 @@ OMPClause * TreeTransform::TransformOMPAlignedClause(OMPAlignedClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -10693,7 +10714,7 @@ OMPClause * TreeTransform::TransformOMPCopyinClause(OMPCopyinClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -10708,7 +10729,7 @@ OMPClause * TreeTransform::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -10722,7 +10743,7 @@ template OMPClause *TreeTransform::TransformOMPFlushClause(OMPFlushClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -10754,7 +10775,7 @@ TreeTransform::TransformOMPDependClause(OMPDependClause *C) { DepModifier = DepModRes.get(); } Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -10785,7 +10806,7 @@ bool transformOMPMappableExprListClause( llvm::SmallVectorImpl &UnresolvedMappers) { // Transform expressions in the list. Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = TT.getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return true; @@ -10865,7 +10886,7 @@ TreeTransform::TransformOMPAllocateClause(OMPAllocateClause *C) { } llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -10997,7 +11018,7 @@ OMPClause *TreeTransform::TransformOMPUseDevicePtrClause( OMPUseDevicePtrClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -11012,7 +11033,7 @@ OMPClause *TreeTransform::TransformOMPUseDeviceAddrClause( OMPUseDeviceAddrClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -11027,7 +11048,7 @@ OMPClause * TreeTransform::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -11042,7 +11063,7 @@ OMPClause *TreeTransform::TransformOMPHasDeviceAddrClause( OMPHasDeviceAddrClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -11057,7 +11078,7 @@ OMPClause * TreeTransform::TransformOMPNontemporalClause(OMPNontemporalClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -11072,7 +11093,7 @@ OMPClause * TreeTransform::TransformOMPInclusiveClause(OMPInclusiveClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -11087,7 +11108,7 @@ OMPClause * TreeTransform::TransformOMPExclusiveClause(OMPExclusiveClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; @@ -11134,7 +11155,7 @@ TreeTransform::TransformOMPAffinityClause(OMPAffinityClause *C) { if (ModifierRes.isInvalid()) return nullptr; } - for (Expr *E : C->varlists()) { + for (Expr *E : C->varlist()) { ExprResult Locator = getDerived().TransformExpr(E); if (Locator.isInvalid()) continue; @@ -11174,7 +11195,7 @@ OMPClause * TreeTransform::TransformOMPDoacrossClause(OMPDoacrossClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); if (EVar.isInvalid()) return nullptr; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 5a53d0d4ebade..a4bf5bf2f748e 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1051,10 +1051,10 @@ IdentifierID ASTIdentifierLookupTrait::ReadIdentifierID(const unsigned char *d) return Reader.getGlobalIdentifierID(F, RawID >> 1); } -static void markIdentifierFromAST(ASTReader &Reader, IdentifierInfo &II) { +static void markIdentifierFromAST(ASTReader &Reader, IdentifierInfo &II, + bool IsModule) { if (!II.isFromAST()) { II.setIsFromAST(); - bool IsModule = Reader.getPreprocessor().getCurrentModule() != nullptr; if (isInterestingIdentifier(Reader, II, IsModule)) II.setChangedSinceDeserialization(); } @@ -1080,7 +1080,8 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k, II = &Reader.getIdentifierTable().getOwn(k); KnownII = II; } - markIdentifierFromAST(Reader, *II); + bool IsModule = Reader.getPreprocessor().getCurrentModule() != nullptr; + markIdentifierFromAST(Reader, *II, IsModule); Reader.markIdentifierUpToDate(II); IdentifierID ID = Reader.getGlobalIdentifierID(F, RawID); @@ -3023,8 +3024,9 @@ ASTReader::ReadControlBlock(ModuleFile &F, case METADATA: { if (Record[0] != VERSION_MAJOR && !DisableValidation) { if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0) - Diag(Record[0] < VERSION_MAJOR? diag::err_pch_version_too_old - : diag::err_pch_version_too_new); + Diag(Record[0] < VERSION_MAJOR ? diag::err_ast_file_version_too_old + : diag::err_ast_file_version_too_new) + << moduleKindForDiagnostic(F.Kind) << F.FileName; return VersionMismatch; } @@ -3037,7 +3039,8 @@ ASTReader::ReadControlBlock(ModuleFile &F, return OutOfDate; if (!AllowASTWithCompilerErrors) { - Diag(diag::err_pch_with_compiler_errors); + Diag(diag::err_ast_file_with_compiler_errors) + << moduleKindForDiagnostic(F.Kind) << F.FileName; return HadErrors; } } @@ -3060,7 +3063,9 @@ ASTReader::ReadControlBlock(ModuleFile &F, StringRef ASTBranch = Blob; if (StringRef(CurBranch) != ASTBranch && !DisableValidation) { if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0) - Diag(diag::err_pch_different_branch) << ASTBranch << CurBranch; + Diag(diag::err_ast_file_different_branch) + << moduleKindForDiagnostic(F.Kind) << F.FileName << ASTBranch + << CurBranch; return VersionMismatch; } break; @@ -4543,7 +4548,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, ModuleKind Type, // Mark this identifier as being from an AST file so that we can track // whether we need to serialize it. - markIdentifierFromAST(*this, *II); + markIdentifierFromAST(*this, *II, /*IsModule=*/true); // Associate the ID with the identifier so that the writer can reuse it. auto ID = Trait.ReadIdentifierID(Data + KeyDataLen.first); @@ -4827,7 +4832,8 @@ ASTReader::ReadASTCore(StringRef FileName, case AST_BLOCK_ID: if (!HaveReadControlBlock) { if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0) - Diag(diag::err_pch_version_too_old); + Diag(diag::err_ast_file_version_too_old) + << moduleKindForDiagnostic(Type) << FileName; return VersionMismatch; } @@ -8968,7 +8974,8 @@ IdentifierInfo *ASTReader::DecodeIdentifierInfo(IdentifierID ID) { auto Key = Trait.ReadKey(Data, KeyDataLen.first); auto &II = PP.getIdentifierTable().get(Key); IdentifiersLoaded[Index] = &II; - markIdentifierFromAST(*this, II); + bool IsModule = getPreprocessor().getCurrentModule() != nullptr; + markIdentifierFromAST(*this, II, IsModule); if (DeserializationListener) DeserializationListener->IdentifierRead(ID, &II); } @@ -9882,6 +9889,7 @@ void ASTReader::finishPendingActions() { // We only perform ODR checks for decls not in the explicit // global module fragment. !shouldSkipCheckingODR(FD) && + !shouldSkipCheckingODR(NonConstDefn) && FD->getODRHash() != NonConstDefn->getODRHash()) { if (!isa(FD)) { PendingFunctionOdrMergeFailures[FD].push_back(NonConstDefn); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 3de9d327f1b3b..31ab6c651d59f 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -821,7 +821,7 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) { Reader.mergeDefinitionVisibility(OldDef, ED); // We don't want to check the ODR hash value for declarations from global // module fragment. - if (!shouldSkipCheckingODR(ED) && + if (!shouldSkipCheckingODR(ED) && !shouldSkipCheckingODR(OldDef) && OldDef->getODRHash() != ED->getODRHash()) Reader.PendingEnumOdrMergeFailures[OldDef].push_back(ED); } else { @@ -2134,7 +2134,7 @@ void ASTDeclReader::MergeDefinitionData( } // We don't want to check ODR for decls in the global module fragment. - if (shouldSkipCheckingODR(MergeDD.Definition)) + if (shouldSkipCheckingODR(MergeDD.Definition) || shouldSkipCheckingODR(D)) return; if (D->getODRHash() != MergeDD.ODRHash) { diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 39cecf750cc4e..caaa2da3cfe53 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -795,29 +795,22 @@ void ASTStmtReader::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { E->setRParenLoc(readSourceLocation()); } -static StringRef saveStrToCtx(const std::string &S, ASTContext &Ctx) { - char *Buf = new (Ctx) char[S.size()]; - std::copy(S.begin(), S.end(), Buf); - return StringRef(Buf, S.size()); -} - static ConstraintSatisfaction readConstraintSatisfaction(ASTRecordReader &Record) { ConstraintSatisfaction Satisfaction; Satisfaction.IsSatisfied = Record.readInt(); Satisfaction.ContainsErrors = Record.readInt(); + const ASTContext &C = Record.getContext(); if (!Satisfaction.IsSatisfied) { unsigned NumDetailRecords = Record.readInt(); for (unsigned i = 0; i != NumDetailRecords; ++i) { if (/* IsDiagnostic */Record.readInt()) { SourceLocation DiagLocation = Record.readSourceLocation(); - StringRef DiagMessage = - saveStrToCtx(Record.readString(), Record.getContext()); + StringRef DiagMessage = C.backupStr(Record.readString()); Satisfaction.Details.emplace_back( - new (Record.getContext()) - ConstraintSatisfaction::SubstitutionDiagnostic(DiagLocation, - DiagMessage)); + new (C) ConstraintSatisfaction::SubstitutionDiagnostic( + DiagLocation, DiagMessage)); } else Satisfaction.Details.emplace_back(Record.readExpr()); } @@ -838,12 +831,10 @@ void ASTStmtReader::VisitConceptSpecializationExpr( static concepts::Requirement::SubstitutionDiagnostic * readSubstitutionDiagnostic(ASTRecordReader &Record) { - StringRef SubstitutedEntity = - saveStrToCtx(Record.readString(), Record.getContext()); - + const ASTContext &C = Record.getContext(); + StringRef SubstitutedEntity = C.backupStr(Record.readString()); SourceLocation DiagLoc = Record.readSourceLocation(); - StringRef DiagMessage = - saveStrToCtx(Record.readString(), Record.getContext()); + StringRef DiagMessage = C.backupStr(Record.readString()); return new (Record.getContext()) concepts::Requirement::SubstitutionDiagnostic{SubstitutedEntity, DiagLoc, @@ -929,22 +920,21 @@ void ASTStmtReader::VisitRequiresExpr(RequiresExpr *E) { std::move(*Req)); } break; case concepts::Requirement::RK_Nested: { + ASTContext &C = Record.getContext(); bool HasInvalidConstraint = Record.readInt(); if (HasInvalidConstraint) { - StringRef InvalidConstraint = - saveStrToCtx(Record.readString(), Record.getContext()); - R = new (Record.getContext()) concepts::NestedRequirement( + StringRef InvalidConstraint = C.backupStr(Record.readString()); + R = new (C) concepts::NestedRequirement( Record.getContext(), InvalidConstraint, readConstraintSatisfaction(Record)); break; } Expr *E = Record.readExpr(); if (E->isInstantiationDependent()) - R = new (Record.getContext()) concepts::NestedRequirement(E); + R = new (C) concepts::NestedRequirement(E); else - R = new (Record.getContext()) - concepts::NestedRequirement(Record.getContext(), E, - readConstraintSatisfaction(Record)); + R = new (C) concepts::NestedRequirement( + C, E, readConstraintSatisfaction(Record)); } break; } if (!R) @@ -2432,7 +2422,6 @@ void ASTStmtReader::VisitOMPExecutableDirective(OMPExecutableDirective *E) { Record.readOMPChildren(E->Data); E->setLocStart(readSourceLocation()); E->setLocEnd(readSourceLocation()); - E->setMappedDirective(Record.readEnum()); } void ASTStmtReader::VisitOMPLoopBasedDirective(OMPLoopBasedDirective *D) { @@ -2477,6 +2466,14 @@ void ASTStmtReader::VisitOMPUnrollDirective(OMPUnrollDirective *D) { VisitOMPLoopTransformationDirective(D); } +void ASTStmtReader::VisitOMPReverseDirective(OMPReverseDirective *D) { + VisitOMPLoopTransformationDirective(D); +} + +void ASTStmtReader::VisitOMPInterchangeDirective(OMPInterchangeDirective *D) { + VisitOMPLoopTransformationDirective(D); +} + void ASTStmtReader::VisitOMPForDirective(OMPForDirective *D) { VisitOMPLoopDirective(D); D->setHasCancel(Record.readBool()); @@ -3500,6 +3497,22 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; } + case STMT_OMP_REVERSE_DIRECTIVE: { + assert(Record[ASTStmtReader::NumStmtFields] == 1 && + "Reverse directive accepts only a single loop"); + assert(Record[ASTStmtReader::NumStmtFields + 1] == 0 && + "Reverse directive has no clauses"); + S = OMPReverseDirective::CreateEmpty(Context); + break; + } + + case STMT_OMP_INTERCHANGE_DIRECTIVE: { + unsigned NumLoops = Record[ASTStmtReader::NumStmtFields]; + unsigned NumClauses = Record[ASTStmtReader::NumStmtFields + 1]; + S = OMPInterchangeDirective::CreateEmpty(Context, NumClauses, NumLoops); + break; + } + case STMT_OMP_FOR_DIRECTIVE: { unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields]; unsigned NumClauses = Record[ASTStmtReader::NumStmtFields + 1]; diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index c78d8943d6d92..f0f9d397f1717 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -7220,7 +7220,7 @@ void OMPClauseWriter::VisitOMPNogroupClause(OMPNogroupClause *) {} void OMPClauseWriter::VisitOMPInitClause(OMPInitClause *C) { Record.push_back(C->varlist_size()); - for (Expr *VE : C->varlists()) + for (Expr *VE : C->varlist()) Record.AddStmt(VE); Record.writeBool(C->getIsTarget()); Record.writeBool(C->getIsTargetSync()); @@ -7266,7 +7266,7 @@ void OMPClauseWriter::VisitOMPAlignClause(OMPAlignClause *C) { void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) { Record.push_back(C->varlist_size()); Record.AddSourceLocation(C->getLParenLoc()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { Record.AddStmt(VE); } for (auto *VE : C->private_copies()) { @@ -7278,7 +7278,7 @@ void OMPClauseWriter::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) { Record.push_back(C->varlist_size()); VisitOMPClauseWithPreInit(C); Record.AddSourceLocation(C->getLParenLoc()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { Record.AddStmt(VE); } for (auto *VE : C->private_copies()) { @@ -7296,7 +7296,7 @@ void OMPClauseWriter::VisitOMPLastprivateClause(OMPLastprivateClause *C) { Record.writeEnum(C->getKind()); Record.AddSourceLocation(C->getKindLoc()); Record.AddSourceLocation(C->getColonLoc()); - for (auto *VE : C->varlists()) + for (auto *VE : C->varlist()) Record.AddStmt(VE); for (auto *E : C->private_copies()) Record.AddStmt(E); @@ -7311,7 +7311,7 @@ void OMPClauseWriter::VisitOMPLastprivateClause(OMPLastprivateClause *C) { void OMPClauseWriter::VisitOMPSharedClause(OMPSharedClause *C) { Record.push_back(C->varlist_size()); Record.AddSourceLocation(C->getLParenLoc()); - for (auto *VE : C->varlists()) + for (auto *VE : C->varlist()) Record.AddStmt(VE); } @@ -7324,7 +7324,7 @@ void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) { Record.AddSourceLocation(C->getColonLoc()); Record.AddNestedNameSpecifierLoc(C->getQualifierLoc()); Record.AddDeclarationNameInfo(C->getNameInfo()); - for (auto *VE : C->varlists()) + for (auto *VE : C->varlist()) Record.AddStmt(VE); for (auto *VE : C->privates()) Record.AddStmt(VE); @@ -7351,7 +7351,7 @@ void OMPClauseWriter::VisitOMPTaskReductionClause(OMPTaskReductionClause *C) { Record.AddSourceLocation(C->getColonLoc()); Record.AddNestedNameSpecifierLoc(C->getQualifierLoc()); Record.AddDeclarationNameInfo(C->getNameInfo()); - for (auto *VE : C->varlists()) + for (auto *VE : C->varlist()) Record.AddStmt(VE); for (auto *VE : C->privates()) Record.AddStmt(VE); @@ -7370,7 +7370,7 @@ void OMPClauseWriter::VisitOMPInReductionClause(OMPInReductionClause *C) { Record.AddSourceLocation(C->getColonLoc()); Record.AddNestedNameSpecifierLoc(C->getQualifierLoc()); Record.AddDeclarationNameInfo(C->getNameInfo()); - for (auto *VE : C->varlists()) + for (auto *VE : C->varlist()) Record.AddStmt(VE); for (auto *VE : C->privates()) Record.AddStmt(VE); @@ -7391,7 +7391,7 @@ void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) { Record.AddSourceLocation(C->getColonLoc()); Record.push_back(C->getModifier()); Record.AddSourceLocation(C->getModifierLoc()); - for (auto *VE : C->varlists()) { + for (auto *VE : C->varlist()) { Record.AddStmt(VE); } for (auto *VE : C->privates()) { @@ -7416,7 +7416,7 @@ void OMPClauseWriter::VisitOMPAlignedClause(OMPAlignedClause *C) { Record.push_back(C->varlist_size()); Record.AddSourceLocation(C->getLParenLoc()); Record.AddSourceLocation(C->getColonLoc()); - for (auto *VE : C->varlists()) + for (auto *VE : C->varlist()) Record.AddStmt(VE); Record.AddStmt(C->getAlignment()); } @@ -7424,7 +7424,7 @@ void OMPClauseWriter::VisitOMPAlignedClause(OMPAlignedClause *C) { void OMPClauseWriter::VisitOMPCopyinClause(OMPCopyinClause *C) { Record.push_back(C->varlist_size()); Record.AddSourceLocation(C->getLParenLoc()); - for (auto *VE : C->varlists()) + for (auto *VE : C->varlist()) Record.AddStmt(VE); for (auto *E : C->source_exprs()) Record.AddStmt(E); @@ -7437,7 +7437,7 @@ void OMPClauseWriter::VisitOMPCopyinClause(OMPCopyinClause *C) { void OMPClauseWriter::VisitOMPCopyprivateClause(OMPCopyprivateClause *C) { Record.push_back(C->varlist_size()); Record.AddSourceLocation(C->getLParenLoc()); - for (auto *VE : C->varlists()) + for (auto *VE : C->varlist()) Record.AddStmt(VE); for (auto *E : C->source_exprs()) Record.AddStmt(E); @@ -7450,7 +7450,7 @@ void OMPClauseWriter::VisitOMPCopyprivateClause(OMPCopyprivateClause *C) { void OMPClauseWriter::VisitOMPFlushClause(OMPFlushClause *C) { Record.push_back(C->varlist_size()); Record.AddSourceLocation(C->getLParenLoc()); - for (auto *VE : C->varlists()) + for (auto *VE : C->varlist()) Record.AddStmt(VE); } @@ -7468,7 +7468,7 @@ void OMPClauseWriter::VisitOMPDependClause(OMPDependClause *C) { Record.AddSourceLocation(C->getDependencyLoc()); Record.AddSourceLocation(C->getColonLoc()); Record.AddSourceLocation(C->getOmpAllMemoryLoc()); - for (auto *VE : C->varlists()) + for (auto *VE : C->varlist()) Record.AddStmt(VE); for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I) Record.AddStmt(C->getLoopData(I)); @@ -7500,7 +7500,7 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) { Record.push_back(C->getMapType()); Record.AddSourceLocation(C->getMapLoc()); Record.AddSourceLocation(C->getColonLoc()); - for (auto *E : C->varlists()) + for (auto *E : C->varlist()) Record.AddStmt(E); for (auto *E : C->mapperlists()) Record.AddStmt(E); @@ -7523,7 +7523,7 @@ void OMPClauseWriter::VisitOMPAllocateClause(OMPAllocateClause *C) { Record.AddSourceLocation(C->getLParenLoc()); Record.AddSourceLocation(C->getColonLoc()); Record.AddStmt(C->getAllocator()); - for (auto *VE : C->varlists()) + for (auto *VE : C->varlist()) Record.AddStmt(VE); } @@ -7596,7 +7596,7 @@ void OMPClauseWriter::VisitOMPToClause(OMPToClause *C) { Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc()); Record.AddDeclarationNameInfo(C->getMapperIdInfo()); Record.AddSourceLocation(C->getColonLoc()); - for (auto *E : C->varlists()) + for (auto *E : C->varlist()) Record.AddStmt(E); for (auto *E : C->mapperlists()) Record.AddStmt(E); @@ -7626,7 +7626,7 @@ void OMPClauseWriter::VisitOMPFromClause(OMPFromClause *C) { Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc()); Record.AddDeclarationNameInfo(C->getMapperIdInfo()); Record.AddSourceLocation(C->getColonLoc()); - for (auto *E : C->varlists()) + for (auto *E : C->varlist()) Record.AddStmt(E); for (auto *E : C->mapperlists()) Record.AddStmt(E); @@ -7649,7 +7649,7 @@ void OMPClauseWriter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *C) { Record.push_back(C->getTotalComponentListNum()); Record.push_back(C->getTotalComponentsNum()); Record.AddSourceLocation(C->getLParenLoc()); - for (auto *E : C->varlists()) + for (auto *E : C->varlist()) Record.AddStmt(E); for (auto *VE : C->private_copies()) Record.AddStmt(VE); @@ -7673,7 +7673,7 @@ void OMPClauseWriter::VisitOMPUseDeviceAddrClause(OMPUseDeviceAddrClause *C) { Record.push_back(C->getTotalComponentListNum()); Record.push_back(C->getTotalComponentsNum()); Record.AddSourceLocation(C->getLParenLoc()); - for (auto *E : C->varlists()) + for (auto *E : C->varlist()) Record.AddStmt(E); for (auto *D : C->all_decls()) Record.AddDeclRef(D); @@ -7693,7 +7693,7 @@ void OMPClauseWriter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) { Record.push_back(C->getTotalComponentListNum()); Record.push_back(C->getTotalComponentsNum()); Record.AddSourceLocation(C->getLParenLoc()); - for (auto *E : C->varlists()) + for (auto *E : C->varlist()) Record.AddStmt(E); for (auto *D : C->all_decls()) Record.AddDeclRef(D); @@ -7713,7 +7713,7 @@ void OMPClauseWriter::VisitOMPHasDeviceAddrClause(OMPHasDeviceAddrClause *C) { Record.push_back(C->getTotalComponentListNum()); Record.push_back(C->getTotalComponentsNum()); Record.AddSourceLocation(C->getLParenLoc()); - for (auto *E : C->varlists()) + for (auto *E : C->varlist()) Record.AddStmt(E); for (auto *D : C->all_decls()) Record.AddDeclRef(D); @@ -7765,7 +7765,7 @@ void OMPClauseWriter::VisitOMPMessageClause(OMPMessageClause *C) { void OMPClauseWriter::VisitOMPNontemporalClause(OMPNontemporalClause *C) { Record.push_back(C->varlist_size()); Record.AddSourceLocation(C->getLParenLoc()); - for (auto *VE : C->varlists()) + for (auto *VE : C->varlist()) Record.AddStmt(VE); for (auto *E : C->private_refs()) Record.AddStmt(E); @@ -7774,14 +7774,14 @@ void OMPClauseWriter::VisitOMPNontemporalClause(OMPNontemporalClause *C) { void OMPClauseWriter::VisitOMPInclusiveClause(OMPInclusiveClause *C) { Record.push_back(C->varlist_size()); Record.AddSourceLocation(C->getLParenLoc()); - for (auto *VE : C->varlists()) + for (auto *VE : C->varlist()) Record.AddStmt(VE); } void OMPClauseWriter::VisitOMPExclusiveClause(OMPExclusiveClause *C) { Record.push_back(C->varlist_size()); Record.AddSourceLocation(C->getLParenLoc()); - for (auto *VE : C->varlists()) + for (auto *VE : C->varlist()) Record.AddStmt(VE); } @@ -7810,7 +7810,7 @@ void OMPClauseWriter::VisitOMPAffinityClause(OMPAffinityClause *C) { Record.AddSourceLocation(C->getLParenLoc()); Record.AddStmt(C->getModifier()); Record.AddSourceLocation(C->getColonLoc()); - for (Expr *E : C->varlists()) + for (Expr *E : C->varlist()) Record.AddStmt(E); } @@ -7833,7 +7833,7 @@ void OMPClauseWriter::VisitOMPDoacrossClause(OMPDoacrossClause *C) { Record.push_back(C->getDependenceType()); Record.AddSourceLocation(C->getDependenceLoc()); Record.AddSourceLocation(C->getColonLoc()); - for (auto *VE : C->varlists()) + for (auto *VE : C->varlist()) Record.AddStmt(VE); for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I) Record.AddStmt(C->getLoopData(I)); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 006dead02e486..8c78fb316c5ff 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -2426,7 +2426,6 @@ void ASTStmtWriter::VisitOMPExecutableDirective(OMPExecutableDirective *E) { Record.writeOMPChildren(E->Data); Record.AddSourceLocation(E->getBeginLoc()); Record.AddSourceLocation(E->getEndLoc()); - Record.writeEnum(E->getMappedDirective()); } void ASTStmtWriter::VisitOMPLoopBasedDirective(OMPLoopBasedDirective *D) { @@ -2474,6 +2473,16 @@ void ASTStmtWriter::VisitOMPUnrollDirective(OMPUnrollDirective *D) { Code = serialization::STMT_OMP_UNROLL_DIRECTIVE; } +void ASTStmtWriter::VisitOMPReverseDirective(OMPReverseDirective *D) { + VisitOMPLoopTransformationDirective(D); + Code = serialization::STMT_OMP_REVERSE_DIRECTIVE; +} + +void ASTStmtWriter::VisitOMPInterchangeDirective(OMPInterchangeDirective *D) { + VisitOMPLoopTransformationDirective(D); + Code = serialization::STMT_OMP_INTERCHANGE_DIRECTIVE; +} + void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) { VisitOMPLoopDirective(D); Record.writeBool(D->hasCancel()); diff --git a/clang/lib/Serialization/CMakeLists.txt b/clang/lib/Serialization/CMakeLists.txt index 5a4b3a58e9c45..99c47c15a2f47 100644 --- a/clang/lib/Serialization/CMakeLists.txt +++ b/clang/lib/Serialization/CMakeLists.txt @@ -1,6 +1,7 @@ set(LLVM_LINK_COMPONENTS BitReader BitstreamReader + Object Support TargetParser ) @@ -21,6 +22,7 @@ add_clang_library(clangSerialization ModuleFileExtension.cpp ModuleManager.cpp PCHContainerOperations.cpp + ObjectFilePCHContainerReader.cpp ADDITIONAL_HEADERS ASTCommon.h diff --git a/clang/lib/Serialization/ObjectFilePCHContainerReader.cpp b/clang/lib/Serialization/ObjectFilePCHContainerReader.cpp new file mode 100644 index 0000000000000..59fc46960dc60 --- /dev/null +++ b/clang/lib/Serialization/ObjectFilePCHContainerReader.cpp @@ -0,0 +1,56 @@ +//===--- ObjectFilePCHContainerReader.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/Serialization/ObjectFilePCHContainerReader.h" +#include "llvm/Object/COFF.h" +#include "llvm/Object/ObjectFile.h" + +using namespace clang; + +ArrayRef ObjectFilePCHContainerReader::getFormats() const { + static StringRef Formats[] = {"obj", "raw"}; + return Formats; +} + +StringRef +ObjectFilePCHContainerReader::ExtractPCH(llvm::MemoryBufferRef Buffer) const { + StringRef PCH; + auto OFOrErr = llvm::object::ObjectFile::createObjectFile(Buffer); + if (OFOrErr) { + auto &OF = OFOrErr.get(); + bool IsCOFF = isa(*OF); + // Find the clang AST section in the container. + for (auto &Section : OF->sections()) { + StringRef Name; + if (Expected NameOrErr = Section.getName()) + Name = *NameOrErr; + else + consumeError(NameOrErr.takeError()); + + if ((!IsCOFF && Name == "__clangast") || (IsCOFF && Name == "clangast")) { + if (Expected E = Section.getContents()) + return *E; + else { + handleAllErrors(E.takeError(), [&](const llvm::ErrorInfoBase &EIB) { + EIB.log(llvm::errs()); + }); + return ""; + } + } + } + } + handleAllErrors(OFOrErr.takeError(), [&](const llvm::ErrorInfoBase &EIB) { + if (EIB.convertToErrorCode() == + llvm::object::object_error::invalid_file_type) + // As a fallback, treat the buffer as a raw AST. + PCH = Buffer.getBuffer(); + else + EIB.log(llvm::errs()); + }); + return PCH; +} diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp index f82288f1099e8..3f837564cf47c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp @@ -373,14 +373,14 @@ static std::optional getConcreteValue(std::optional SV) { } static Messages getPrecedesMsgs(const SubRegion *Region, NonLoc Offset) { - std::string RegName = getRegionName(Region); - SmallString<128> Buf; - llvm::raw_svector_ostream Out(Buf); - Out << "Access of " << RegName << " at negative byte offset"; - if (auto ConcreteIdx = Offset.getAs()) - Out << ' ' << ConcreteIdx->getValue(); - return {formatv("Out of bound access to memory preceding {0}", RegName), - std::string(Buf)}; + std::string RegName = getRegionName(Region), OffsetStr = ""; + + if (auto ConcreteOffset = getConcreteValue(Offset)) + OffsetStr = formatv(" {0}", ConcreteOffset); + + return { + formatv("Out of bound access to memory preceding {0}", RegName), + formatv("Access of {0} at negative byte offset{1}", RegName, OffsetStr)}; } /// Try to divide `Val1` and `Val2` (in place) by `Divisor` and return true if @@ -609,7 +609,7 @@ void ArrayBoundCheckerV2::performCheck(const Expr *E, CheckerContext &C) const { // CHECK UPPER BOUND DefinedOrUnknownSVal Size = getDynamicExtent(State, Reg, SVB); if (auto KnownSize = Size.getAs()) { - // In a situation where both overflow and overflow are possible (but the + // In a situation where both underflow and overflow are possible (but the // index is either tainted or known to be invalid), the logic of this // checker will first assume that the offset is non-negative, and then // (with this additional assumption) it will detect an overflow error. diff --git a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp index 1a75d7b52ad6e..b198b1c2ff4d1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp @@ -18,6 +18,7 @@ #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h" @@ -30,8 +31,40 @@ namespace { class BuiltinFunctionChecker : public Checker { public: bool evalCall(const CallEvent &Call, CheckerContext &C) const; + +private: + // From: clang/include/clang/Basic/Builtins.def + // C++ standard library builtins in namespace 'std'. + const CallDescriptionSet BuiltinLikeStdFunctions{ + {CDM::SimpleFunc, {"std", "addressof"}}, // + {CDM::SimpleFunc, {"std", "__addressof"}}, // + {CDM::SimpleFunc, {"std", "as_const"}}, // + {CDM::SimpleFunc, {"std", "forward"}}, // + {CDM::SimpleFunc, {"std", "forward_like"}}, // + {CDM::SimpleFunc, {"std", "move"}}, // + {CDM::SimpleFunc, {"std", "move_if_noexcept"}}, // + }; + + bool isBuiltinLikeFunction(const CallEvent &Call) const; }; +} // namespace + +bool BuiltinFunctionChecker::isBuiltinLikeFunction( + const CallEvent &Call) const { + const auto *FD = llvm::dyn_cast_or_null(Call.getDecl()); + if (!FD || FD->getNumParams() != 1) + return false; + + if (QualType RetTy = FD->getReturnType(); + !RetTy->isPointerType() && !RetTy->isReferenceType()) + return false; + + if (QualType ParmTy = FD->getParamDecl(0)->getType(); + !ParmTy->isPointerType() && !ParmTy->isReferenceType()) + return false; + + return BuiltinLikeStdFunctions.contains(Call); } bool BuiltinFunctionChecker::evalCall(const CallEvent &Call, @@ -44,6 +77,11 @@ bool BuiltinFunctionChecker::evalCall(const CallEvent &Call, const LocationContext *LCtx = C.getLocationContext(); const Expr *CE = Call.getOriginExpr(); + if (isBuiltinLikeFunction(Call)) { + C.addTransition(state->BindExpr(CE, LCtx, Call.getArgSVal(0))); + return true; + } + switch (FD->getBuiltinID()) { default: return false; diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index fe202c79ed620..95ec28bfd20da 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -103,14 +103,48 @@ using namespace std::placeholders; namespace { // Used to check correspondence between allocators and deallocators. -enum AllocationFamily { +enum AllocationFamilyKind { AF_None, AF_Malloc, AF_CXXNew, AF_CXXNewArray, AF_IfNameIndex, AF_Alloca, - AF_InnerBuffer + AF_InnerBuffer, + AF_Custom, +}; + +struct AllocationFamily { + AllocationFamilyKind Kind; + std::optional CustomName; + + explicit AllocationFamily(AllocationFamilyKind AKind, + std::optional Name = std::nullopt) + : Kind(AKind), CustomName(Name) { + assert((Kind != AF_Custom || CustomName.has_value()) && + "Custom family must specify also the name"); + + // Preseve previous behavior when "malloc" class means AF_Malloc + if (Kind == AF_Custom && CustomName.value() == "malloc") { + Kind = AF_Malloc; + CustomName = std::nullopt; + } + } + + bool operator==(const AllocationFamily &Other) const { + return std::tie(Kind, CustomName) == std::tie(Other.Kind, Other.CustomName); + } + + bool operator!=(const AllocationFamily &Other) const { + return !(*this == Other); + } + + void Profile(llvm::FoldingSetNodeID &ID) const { + ID.AddInteger(Kind); + + if (Kind == AF_Custom) + ID.AddString(CustomName.value()); + } }; } // end of anonymous namespace @@ -158,7 +192,7 @@ class RefState { RefState(Kind k, const Stmt *s, AllocationFamily family) : S(s), K(k), Family(family) { - assert(family != AF_None); + assert(family.Kind != AF_None); } public: @@ -194,7 +228,7 @@ class RefState { void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(K); ID.AddPointer(S); - ID.AddInteger(Family); + Family.Profile(ID); } LLVM_DUMP_METHOD void dump(raw_ostream &OS) const { @@ -899,7 +933,7 @@ class MallocBugVisitor final : public BugReporterVisitor { bool IsReleased = (RSCurr && RSCurr->isReleased()) && (!RSPrev || !RSPrev->isReleased()); assert(!IsReleased || (isa_and_nonnull(Stmt)) || - (!Stmt && RSCurr->getAllocationFamily() == AF_InnerBuffer)); + (!Stmt && RSCurr->getAllocationFamily().Kind == AF_InnerBuffer)); return IsReleased; } @@ -1122,7 +1156,7 @@ MallocChecker::performKernelMalloc(const CallEvent &Call, CheckerContext &C, if (TrueState && !FalseState) { SVal ZeroVal = C.getSValBuilder().makeZeroVal(Ctx.CharTy); return MallocMemAux(C, Call, Call.getArgExpr(0), ZeroVal, TrueState, - AF_Malloc); + AllocationFamily(AF_Malloc)); } return std::nullopt; @@ -1143,7 +1177,7 @@ void MallocChecker::checkBasicAlloc(const CallEvent &Call, CheckerContext &C) const { ProgramStateRef State = C.getState(); State = MallocMemAux(C, Call, Call.getArgExpr(0), UndefinedVal(), State, - AF_Malloc); + AllocationFamily(AF_Malloc)); State = ProcessZeroAllocCheck(Call, 0, State); C.addTransition(State); } @@ -1157,7 +1191,7 @@ void MallocChecker::checkKernelMalloc(const CallEvent &Call, State = *MaybeState; else State = MallocMemAux(C, Call, Call.getArgExpr(0), UndefinedVal(), State, - AF_Malloc); + AllocationFamily(AF_Malloc)); C.addTransition(State); } @@ -1194,7 +1228,8 @@ void MallocChecker::checkRealloc(const CallEvent &Call, CheckerContext &C, return; ProgramStateRef State = C.getState(); - State = ReallocMemAux(C, Call, ShouldFreeOnFail, State, AF_Malloc); + State = ReallocMemAux(C, Call, ShouldFreeOnFail, State, + AllocationFamily(AF_Malloc)); State = ProcessZeroAllocCheck(Call, 1, State); C.addTransition(State); } @@ -1214,7 +1249,7 @@ void MallocChecker::checkFree(const CallEvent &Call, CheckerContext &C) const { if (suppressDeallocationsInSuspiciousContexts(Call, C)) return; State = FreeMemAux(C, Call, State, 0, false, IsKnownToBeAllocatedMemory, - AF_Malloc); + AllocationFamily(AF_Malloc)); C.addTransition(State); } @@ -1222,7 +1257,7 @@ void MallocChecker::checkAlloca(const CallEvent &Call, CheckerContext &C) const { ProgramStateRef State = C.getState(); State = MallocMemAux(C, Call, Call.getArgExpr(0), UndefinedVal(), State, - AF_Alloca); + AllocationFamily(AF_Alloca)); State = ProcessZeroAllocCheck(Call, 0, State); C.addTransition(State); } @@ -1233,7 +1268,7 @@ void MallocChecker::checkStrdup(const CallEvent &Call, const auto *CE = dyn_cast_or_null(Call.getOriginExpr()); if (!CE) return; - State = MallocUpdateRefState(C, CE, State, AF_Malloc); + State = MallocUpdateRefState(C, CE, State, AllocationFamily(AF_Malloc)); C.addTransition(State); } @@ -1243,8 +1278,8 @@ void MallocChecker::checkIfNameIndex(const CallEvent &Call, ProgramStateRef State = C.getState(); // Should we model this differently? We can allocate a fixed number of // elements with zeros in the last one. - State = - MallocMemAux(C, Call, UnknownVal(), UnknownVal(), State, AF_IfNameIndex); + State = MallocMemAux(C, Call, UnknownVal(), UnknownVal(), State, + AllocationFamily(AF_IfNameIndex)); C.addTransition(State); } @@ -1254,7 +1289,7 @@ void MallocChecker::checkIfFreeNameIndex(const CallEvent &Call, ProgramStateRef State = C.getState(); bool IsKnownToBeAllocatedMemory = false; State = FreeMemAux(C, Call, State, 0, false, IsKnownToBeAllocatedMemory, - AF_IfNameIndex); + AllocationFamily(AF_IfNameIndex)); C.addTransition(State); } @@ -1275,25 +1310,26 @@ void MallocChecker::checkCXXNewOrCXXDelete(const CallEvent &Call, const FunctionDecl *FD = C.getCalleeDecl(CE); switch (FD->getOverloadedOperator()) { case OO_New: - State = - MallocMemAux(C, Call, CE->getArg(0), UndefinedVal(), State, AF_CXXNew); + State = MallocMemAux(C, Call, CE->getArg(0), UndefinedVal(), State, + AllocationFamily(AF_CXXNew)); State = ProcessZeroAllocCheck(Call, 0, State); break; case OO_Array_New: State = MallocMemAux(C, Call, CE->getArg(0), UndefinedVal(), State, - AF_CXXNewArray); + AllocationFamily(AF_CXXNewArray)); State = ProcessZeroAllocCheck(Call, 0, State); break; case OO_Delete: State = FreeMemAux(C, Call, State, 0, false, IsKnownToBeAllocatedMemory, - AF_CXXNew); + AllocationFamily(AF_CXXNew)); break; case OO_Array_Delete: State = FreeMemAux(C, Call, State, 0, false, IsKnownToBeAllocatedMemory, - AF_CXXNewArray); + AllocationFamily(AF_CXXNewArray)); break; default: - llvm_unreachable("not a new/delete operator"); + assert(false && "not a new/delete operator"); + return; } C.addTransition(State); @@ -1304,7 +1340,8 @@ void MallocChecker::checkGMalloc0(const CallEvent &Call, ProgramStateRef State = C.getState(); SValBuilder &svalBuilder = C.getSValBuilder(); SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy); - State = MallocMemAux(C, Call, Call.getArgExpr(0), zeroVal, State, AF_Malloc); + State = MallocMemAux(C, Call, Call.getArgExpr(0), zeroVal, State, + AllocationFamily(AF_Malloc)); State = ProcessZeroAllocCheck(Call, 0, State); C.addTransition(State); } @@ -1312,8 +1349,8 @@ void MallocChecker::checkGMalloc0(const CallEvent &Call, void MallocChecker::checkGMemdup(const CallEvent &Call, CheckerContext &C) const { ProgramStateRef State = C.getState(); - State = - MallocMemAux(C, Call, Call.getArgExpr(1), UnknownVal(), State, AF_Malloc); + State = MallocMemAux(C, Call, Call.getArgExpr(1), UnknownVal(), State, + AllocationFamily(AF_Malloc)); State = ProcessZeroAllocCheck(Call, 1, State); C.addTransition(State); } @@ -1323,7 +1360,8 @@ void MallocChecker::checkGMallocN(const CallEvent &Call, ProgramStateRef State = C.getState(); SVal Init = UndefinedVal(); SVal TotalSize = evalMulForBufferSize(C, Call.getArgExpr(0), Call.getArgExpr(1)); - State = MallocMemAux(C, Call, TotalSize, Init, State, AF_Malloc); + State = MallocMemAux(C, Call, TotalSize, Init, State, + AllocationFamily(AF_Malloc)); State = ProcessZeroAllocCheck(Call, 0, State); State = ProcessZeroAllocCheck(Call, 1, State); C.addTransition(State); @@ -1335,7 +1373,8 @@ void MallocChecker::checkGMallocN0(const CallEvent &Call, SValBuilder &SB = C.getSValBuilder(); SVal Init = SB.makeZeroVal(SB.getContext().CharTy); SVal TotalSize = evalMulForBufferSize(C, Call.getArgExpr(0), Call.getArgExpr(1)); - State = MallocMemAux(C, Call, TotalSize, Init, State, AF_Malloc); + State = MallocMemAux(C, Call, TotalSize, Init, State, + AllocationFamily(AF_Malloc)); State = ProcessZeroAllocCheck(Call, 0, State); State = ProcessZeroAllocCheck(Call, 1, State); C.addTransition(State); @@ -1365,7 +1404,8 @@ void MallocChecker::preGetdelim(const CallEvent &Call, // of reporting any violation of the preconditions. bool IsKnownToBeAllocated = false; State = FreeMemAux(C, Call.getArgExpr(0), Call, State, false, - IsKnownToBeAllocated, AF_Malloc, false, LinePtr); + IsKnownToBeAllocated, AllocationFamily(AF_Malloc), false, + LinePtr); if (State) C.addTransition(State); } @@ -1394,13 +1434,15 @@ void MallocChecker::checkGetdelim(const CallEvent &Call, return; State = setDynamicExtent(State, LinePtr->getAsRegion(), *Size, SVB); - C.addTransition(MallocUpdateRefState(C, CE, State, AF_Malloc, *LinePtr)); + C.addTransition(MallocUpdateRefState(C, CE, State, + AllocationFamily(AF_Malloc), *LinePtr)); } void MallocChecker::checkReallocN(const CallEvent &Call, CheckerContext &C) const { ProgramStateRef State = C.getState(); - State = ReallocMemAux(C, Call, /*ShouldFreeOnFail=*/false, State, AF_Malloc, + State = ReallocMemAux(C, Call, /*ShouldFreeOnFail=*/false, State, + AllocationFamily(AF_Malloc), /*SuffixWithN=*/true); State = ProcessZeroAllocCheck(Call, 1, State); State = ProcessZeroAllocCheck(Call, 2, State); @@ -1489,8 +1531,10 @@ ProgramStateRef MallocChecker::ProcessZeroAllocCheck( } else { return State; } - } else - llvm_unreachable("not a CallExpr or CXXNewExpr"); + } else { + assert(false && "not a CallExpr or CXXNewExpr"); + return nullptr; + } assert(Arg); @@ -1598,7 +1642,8 @@ MallocChecker::processNewAllocation(const CXXAllocatorCall &Call, SVal Target = Call.getObjectUnderConstruction(); if (Call.getOriginExpr()->isArray()) { if (auto SizeEx = NE->getArraySize()) - checkTaintedness(C, Call, C.getSVal(*SizeEx), State, AF_CXXNewArray); + checkTaintedness(C, Call, C.getSVal(*SizeEx), State, + AllocationFamily(AF_CXXNewArray)); } State = MallocUpdateRefState(C, NE, State, Family, Target); @@ -1611,7 +1656,8 @@ void MallocChecker::checkNewAllocator(const CXXAllocatorCall &Call, if (!C.wasInlined) { ProgramStateRef State = processNewAllocation( Call, C, - (Call.getOriginExpr()->isArray() ? AF_CXXNewArray : AF_CXXNew)); + AllocationFamily(Call.getOriginExpr()->isArray() ? AF_CXXNewArray + : AF_CXXNew)); C.addTransition(State); } } @@ -1655,10 +1701,10 @@ void MallocChecker::checkPostObjCMessage(const ObjCMethodCall &Call, return; bool IsKnownToBeAllocatedMemory; - ProgramStateRef State = - FreeMemAux(C, Call.getArgExpr(0), Call, C.getState(), - /*Hold=*/true, IsKnownToBeAllocatedMemory, AF_Malloc, - /*ReturnsNullOnFailure=*/true); + ProgramStateRef State = FreeMemAux(C, Call.getArgExpr(0), Call, C.getState(), + /*Hold=*/true, IsKnownToBeAllocatedMemory, + AllocationFamily(AF_Malloc), + /*ReturnsNullOnFailure=*/true); C.addTransition(State); } @@ -1670,15 +1716,15 @@ MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallEvent &Call, if (!State) return nullptr; - if (Att->getModule()->getName() != "malloc") - return nullptr; + auto attrClassName = Att->getModule()->getName(); + auto Family = AllocationFamily(AF_Custom, attrClassName); if (!Att->args().empty()) { return MallocMemAux(C, Call, Call.getArgExpr(Att->args_begin()->getASTIndex()), - UndefinedVal(), State, AF_Malloc); + UndefinedVal(), State, Family); } - return MallocMemAux(C, Call, UnknownVal(), UndefinedVal(), State, AF_Malloc); + return MallocMemAux(C, Call, UnknownVal(), UndefinedVal(), State, Family); } ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C, @@ -1768,10 +1814,10 @@ ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C, unsigned Count = C.blockCount(); SValBuilder &SVB = C.getSValBuilder(); const LocationContext *LCtx = C.getPredecessor()->getLocationContext(); - DefinedSVal RetVal = - ((Family == AF_Alloca) ? SVB.getAllocaRegionVal(CE, LCtx, Count) - : SVB.getConjuredHeapSymbolVal(CE, LCtx, Count) - .castAs()); + DefinedSVal RetVal = ((Family.Kind == AF_Alloca) + ? SVB.getAllocaRegionVal(CE, LCtx, Count) + : SVB.getConjuredHeapSymbolVal(CE, LCtx, Count) + .castAs()); State = State->BindExpr(CE, C.getLocationContext(), RetVal); // Fill the region with the initialization value. @@ -1781,7 +1827,7 @@ ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C, if (Size.isUndef()) Size = UnknownVal(); - checkTaintedness(C, Call, Size, State, AF_Malloc); + checkTaintedness(C, Call, Size, State, AllocationFamily(AF_Malloc)); // Set the region's extent. State = setDynamicExtent(State, RetVal.getAsRegion(), @@ -1830,8 +1876,8 @@ ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C, if (!State) return nullptr; - if (Att->getModule()->getName() != "malloc") - return nullptr; + auto attrClassName = Att->getModule()->getName(); + auto Family = AllocationFamily(AF_Custom, attrClassName); bool IsKnownToBeAllocated = false; @@ -1839,7 +1885,7 @@ ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C, ProgramStateRef StateI = FreeMemAux(C, Call, State, Arg.getASTIndex(), Att->getOwnKind() == OwnershipAttr::Holds, - IsKnownToBeAllocated, AF_Malloc); + IsKnownToBeAllocated, Family); if (StateI) State = StateI; } @@ -1877,6 +1923,27 @@ static bool didPreviousFreeFail(ProgramStateRef State, return false; } +static void printOwnershipTakesList(raw_ostream &os, CheckerContext &C, + const Expr *E) { + const CallExpr *CE = dyn_cast(E); + + if (!CE) + return; + + const FunctionDecl *FD = CE->getDirectCallee(); + if (!FD) + return; + + // Only one ownership_takes attribute is allowed. + for (const auto *I : FD->specific_attrs()) { + if (I->getOwnKind() != OwnershipAttr::Takes) + continue; + + os << ", which takes ownership of '" << I->getModule()->getName() << '\''; + break; + } +} + static bool printMemFnName(raw_ostream &os, CheckerContext &C, const Expr *E) { if (const CallExpr *CE = dyn_cast(E)) { // FIXME: This doesn't handle indirect calls. @@ -1884,9 +1951,12 @@ static bool printMemFnName(raw_ostream &os, CheckerContext &C, const Expr *E) { if (!FD) return false; - os << *FD; + os << '\'' << *FD; + if (!FD->isOverloadedOperator()) os << "()"; + + os << '\''; return true; } @@ -1918,26 +1988,55 @@ static bool printMemFnName(raw_ostream &os, CheckerContext &C, const Expr *E) { static void printExpectedAllocName(raw_ostream &os, AllocationFamily Family) { - switch(Family) { - case AF_Malloc: os << "malloc()"; return; - case AF_CXXNew: os << "'new'"; return; - case AF_CXXNewArray: os << "'new[]'"; return; - case AF_IfNameIndex: os << "'if_nameindex()'"; return; - case AF_InnerBuffer: os << "container-specific allocator"; return; - case AF_Alloca: - case AF_None: llvm_unreachable("not a deallocation expression"); + switch (Family.Kind) { + case AF_Malloc: + os << "'malloc()'"; + return; + case AF_CXXNew: + os << "'new'"; + return; + case AF_CXXNewArray: + os << "'new[]'"; + return; + case AF_IfNameIndex: + os << "'if_nameindex()'"; + return; + case AF_InnerBuffer: + os << "container-specific allocator"; + return; + case AF_Custom: + os << Family.CustomName.value(); + return; + case AF_Alloca: + case AF_None: + assert(false && "not a deallocation expression"); } } static void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family) { - switch(Family) { - case AF_Malloc: os << "free()"; return; - case AF_CXXNew: os << "'delete'"; return; - case AF_CXXNewArray: os << "'delete[]'"; return; - case AF_IfNameIndex: os << "'if_freenameindex()'"; return; - case AF_InnerBuffer: os << "container-specific deallocator"; return; - case AF_Alloca: - case AF_None: llvm_unreachable("suspicious argument"); + switch (Family.Kind) { + case AF_Malloc: + os << "'free()'"; + return; + case AF_CXXNew: + os << "'delete'"; + return; + case AF_CXXNewArray: + os << "'delete[]'"; + return; + case AF_IfNameIndex: + os << "'if_freenameindex()'"; + return; + case AF_InnerBuffer: + os << "container-specific deallocator"; + return; + case AF_Custom: + os << "function that takes ownership of '" << Family.CustomName.value() + << "\'"; + return; + case AF_Alloca: + case AF_None: + assert(false && "not a deallocation expression"); } } @@ -1991,7 +2090,7 @@ MallocChecker::FreeMemAux(CheckerContext &C, const Expr *ArgExpr, // code. In that case, the ZERO_SIZE_PTR defines a special value used for a // zero-sized memory block which is allowed to be freed, despite not being a // null pointer. - if (Family != AF_Malloc || !isArgZERO_SIZE_PTR(State, C, ArgVal)) + if (Family.Kind != AF_Malloc || !isArgZERO_SIZE_PTR(State, C, ArgVal)) HandleNonHeapDealloc(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr, Family); return nullptr; @@ -2041,7 +2140,7 @@ MallocChecker::FreeMemAux(CheckerContext &C, const Expr *ArgExpr, if (RsBase) { // Memory returned by alloca() shouldn't be freed. - if (RsBase->getAllocationFamily() == AF_Alloca) { + if (RsBase->getAllocationFamily().Kind == AF_Alloca) { HandleFreeAlloca(C, ArgVal, ArgExpr->getSourceRange()); return nullptr; } @@ -2119,9 +2218,10 @@ MallocChecker::FreeMemAux(CheckerContext &C, const Expr *ArgExpr, std::optional MallocChecker::getCheckIfTracked(AllocationFamily Family, bool IsALeakCheck) const { - switch (Family) { + switch (Family.Kind) { case AF_Malloc: case AF_Alloca: + case AF_Custom: case AF_IfNameIndex: { if (ChecksEnabled[CK_MallocChecker]) return CK_MallocChecker; @@ -2145,10 +2245,12 @@ MallocChecker::getCheckIfTracked(AllocationFamily Family, return std::nullopt; } case AF_None: { - llvm_unreachable("no family"); + assert(false && "no family"); + return std::nullopt; } } - llvm_unreachable("unhandled family"); + assert(false && "unhandled family"); + return std::nullopt; } std::optional @@ -2316,11 +2418,11 @@ void MallocChecker::HandleFreeAlloca(CheckerContext &C, SVal ArgVal, if (ExplodedNode *N = C.generateErrorNode()) { if (!BT_FreeAlloca[*CheckKind]) BT_FreeAlloca[*CheckKind].reset(new BugType( - CheckNames[*CheckKind], "Free alloca()", categories::MemoryError)); + CheckNames[*CheckKind], "Free 'alloca()'", categories::MemoryError)); auto R = std::make_unique( *BT_FreeAlloca[*CheckKind], - "Memory allocated by alloca() should not be deallocated", N); + "Memory allocated by 'alloca()' should not be deallocated", N); R->markInteresting(ArgVal.getAsRegion()); R->addRange(Range); C.emitReport(std::move(R)); @@ -2373,6 +2475,8 @@ void MallocChecker::HandleMismatchedDealloc(CheckerContext &C, if (printMemFnName(DeallocOs, C, DeallocExpr)) os << ", not " << DeallocOs.str(); + + printOwnershipTakesList(os, C, DeallocExpr); } auto R = std::make_unique(*BT_MismatchedDealloc, @@ -2465,7 +2569,7 @@ void MallocChecker::HandleUseAfterFree(CheckerContext &C, SourceRange Range, auto R = std::make_unique( *BT_UseFree[*CheckKind], - AF == AF_InnerBuffer + AF.Kind == AF_InnerBuffer ? "Inner pointer of container used after re/deallocation" : "Use of memory after it is freed", N); @@ -2474,7 +2578,7 @@ void MallocChecker::HandleUseAfterFree(CheckerContext &C, SourceRange Range, R->addRange(Range); R->addVisitor(Sym); - if (AF == AF_InnerBuffer) + if (AF.Kind == AF_InnerBuffer) R->addVisitor(allocation_state::getInnerPointerBRVisitor(Sym)); C.emitReport(std::move(R)); @@ -2733,7 +2837,8 @@ ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, SVal TotalSize = evalMulForBufferSize(C, Call.getArgExpr(0), Call.getArgExpr(1)); - return MallocMemAux(C, Call, TotalSize, zeroVal, State, AF_Malloc); + return MallocMemAux(C, Call, TotalSize, zeroVal, State, + AllocationFamily(AF_Malloc)); } MallocChecker::LeakInfo MallocChecker::getAllocationSite(const ExplodedNode *N, @@ -2788,7 +2893,7 @@ void MallocChecker::HandleLeak(SymbolRef Sym, ExplodedNode *N, assert(RS && "cannot leak an untracked symbol"); AllocationFamily Family = RS->getAllocationFamily(); - if (Family == AF_Alloca) + if (Family.Kind == AF_Alloca) return; std::optional CheckKind = @@ -2915,9 +3020,10 @@ void MallocChecker::checkPreCall(const CallEvent &Call, ProgramStateRef State = C.getState(); bool IsKnownToBeAllocated; - State = FreeMemAux(C, DE->getArgument(), Call, State, - /*Hold*/ false, IsKnownToBeAllocated, - (DE->isArrayForm() ? AF_CXXNewArray : AF_CXXNew)); + State = FreeMemAux( + C, DE->getArgument(), Call, State, + /*Hold*/ false, IsKnownToBeAllocated, + AllocationFamily(DE->isArrayForm() ? AF_CXXNewArray : AF_CXXNew)); C.addTransition(State); return; @@ -3349,8 +3455,8 @@ ProgramStateRef MallocChecker::checkConstPointerEscape(ProgramStateRef State, } static bool checkIfNewOrNewArrayFamily(const RefState *RS) { - return (RS->getAllocationFamily() == AF_CXXNewArray || - RS->getAllocationFamily() == AF_CXXNew); + return (RS->getAllocationFamily().Kind == AF_CXXNewArray || + RS->getAllocationFamily().Kind == AF_CXXNew); } ProgramStateRef MallocChecker::checkPointerEscapeAux( @@ -3431,7 +3537,7 @@ PathDiagnosticPieceRef MallocBugVisitor::VisitNode(const ExplodedNode *N, const Stmt *S = N->getStmtForDiagnostics(); // When dealing with containers, we sometimes want to give a note // even if the statement is missing. - if (!S && (!RSCurr || RSCurr->getAllocationFamily() != AF_InnerBuffer)) + if (!S && (!RSCurr || RSCurr->getAllocationFamily().Kind != AF_InnerBuffer)) return nullptr; const LocationContext *CurrentLC = N->getLocationContext(); @@ -3483,53 +3589,55 @@ PathDiagnosticPieceRef MallocBugVisitor::VisitNode(const ExplodedNode *N, Sym, "Returned allocated memory"); } else if (isReleased(RSCurr, RSPrev, S)) { const auto Family = RSCurr->getAllocationFamily(); - switch (Family) { - case AF_Alloca: - case AF_Malloc: - case AF_CXXNew: - case AF_CXXNewArray: - case AF_IfNameIndex: - Msg = "Memory is released"; + switch (Family.Kind) { + case AF_Alloca: + case AF_Malloc: + case AF_Custom: + case AF_CXXNew: + case AF_CXXNewArray: + case AF_IfNameIndex: + Msg = "Memory is released"; + StackHint = std::make_unique( + Sym, "Returning; memory was released"); + break; + case AF_InnerBuffer: { + const MemRegion *ObjRegion = + allocation_state::getContainerObjRegion(statePrev, Sym); + const auto *TypedRegion = cast(ObjRegion); + QualType ObjTy = TypedRegion->getValueType(); + OS << "Inner buffer of '" << ObjTy << "' "; + + if (N->getLocation().getKind() == ProgramPoint::PostImplicitCallKind) { + OS << "deallocated by call to destructor"; StackHint = std::make_unique( - Sym, "Returning; memory was released"); - break; - case AF_InnerBuffer: { - const MemRegion *ObjRegion = - allocation_state::getContainerObjRegion(statePrev, Sym); - const auto *TypedRegion = cast(ObjRegion); - QualType ObjTy = TypedRegion->getValueType(); - OS << "Inner buffer of '" << ObjTy << "' "; - - if (N->getLocation().getKind() == ProgramPoint::PostImplicitCallKind) { - OS << "deallocated by call to destructor"; - StackHint = std::make_unique( - Sym, "Returning; inner buffer was deallocated"); - } else { - OS << "reallocated by call to '"; - const Stmt *S = RSCurr->getStmt(); - if (const auto *MemCallE = dyn_cast(S)) { - OS << MemCallE->getMethodDecl()->getDeclName(); - } else if (const auto *OpCallE = dyn_cast(S)) { - OS << OpCallE->getDirectCallee()->getDeclName(); - } else if (const auto *CallE = dyn_cast(S)) { - auto &CEMgr = BRC.getStateManager().getCallEventManager(); - CallEventRef<> Call = - CEMgr.getSimpleCall(CallE, state, CurrentLC, {nullptr, 0}); - if (const auto *D = dyn_cast_or_null(Call->getDecl())) - OS << D->getDeclName(); - else - OS << "unknown"; - } - OS << "'"; - StackHint = std::make_unique( - Sym, "Returning; inner buffer was reallocated"); + Sym, "Returning; inner buffer was deallocated"); + } else { + OS << "reallocated by call to '"; + const Stmt *S = RSCurr->getStmt(); + if (const auto *MemCallE = dyn_cast(S)) { + OS << MemCallE->getMethodDecl()->getDeclName(); + } else if (const auto *OpCallE = dyn_cast(S)) { + OS << OpCallE->getDirectCallee()->getDeclName(); + } else if (const auto *CallE = dyn_cast(S)) { + auto &CEMgr = BRC.getStateManager().getCallEventManager(); + CallEventRef<> Call = + CEMgr.getSimpleCall(CallE, state, CurrentLC, {nullptr, 0}); + if (const auto *D = dyn_cast_or_null(Call->getDecl())) + OS << D->getDeclName(); + else + OS << "unknown"; } - Msg = OS.str(); - break; + OS << "'"; + StackHint = std::make_unique( + Sym, "Returning; inner buffer was reallocated"); + } + Msg = OS.str(); + break; } case AF_None: - llvm_unreachable("Unhandled allocation family!"); - } + assert(false && "Unhandled allocation family!"); + return nullptr; + } // See if we're releasing memory while inlining a destructor // (or one of its callees). This turns on various common @@ -3603,7 +3711,7 @@ PathDiagnosticPieceRef MallocBugVisitor::VisitNode(const ExplodedNode *N, // Generate the extra diagnostic. PathDiagnosticLocation Pos; if (!S) { - assert(RSCurr->getAllocationFamily() == AF_InnerBuffer); + assert(RSCurr->getAllocationFamily().Kind == AF_InnerBuffer); auto PostImplCall = N->getLocation().getAs(); if (!PostImplCall) return nullptr; @@ -3650,7 +3758,7 @@ namespace allocation_state { ProgramStateRef markReleased(ProgramStateRef State, SymbolRef Sym, const Expr *Origin) { - AllocationFamily Family = AF_InnerBuffer; + AllocationFamily Family(AF_InnerBuffer); return State->set(Sym, RefState::getReleased(Family, Origin)); } diff --git a/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp index cd1dd1b2fc511..4b8e5216550d9 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp @@ -21,49 +21,56 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h" using namespace clang; using namespace ento; namespace { -class MmapWriteExecChecker : public Checker { +class MmapWriteExecChecker + : public Checker, check::PreCall> { CallDescription MmapFn{CDM::CLibrary, {"mmap"}, 6}; CallDescription MprotectFn{CDM::CLibrary, {"mprotect"}, 3}; - static int ProtWrite; - static int ProtExec; - static int ProtRead; const BugType BT{this, "W^X check fails, Write Exec prot flags set", "Security"}; + // Default values are used if definition of the flags is not found. + mutable int ProtRead = 0x01; + mutable int ProtWrite = 0x02; + mutable int ProtExec = 0x04; + public: + void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager &Mgr, + BugReporter &BR) const; void checkPreCall(const CallEvent &Call, CheckerContext &C) const; - int ProtExecOv; - int ProtReadOv; }; } -int MmapWriteExecChecker::ProtWrite = 0x02; -int MmapWriteExecChecker::ProtExec = 0x04; -int MmapWriteExecChecker::ProtRead = 0x01; +void MmapWriteExecChecker::checkASTDecl(const TranslationUnitDecl *TU, + AnalysisManager &Mgr, + BugReporter &BR) const { + Preprocessor &PP = Mgr.getPreprocessor(); + const std::optional FoundProtRead = tryExpandAsInteger("PROT_READ", PP); + const std::optional FoundProtWrite = + tryExpandAsInteger("PROT_WRITE", PP); + const std::optional FoundProtExec = tryExpandAsInteger("PROT_EXEC", PP); + if (FoundProtRead && FoundProtWrite && FoundProtExec) { + ProtRead = *FoundProtRead; + ProtWrite = *FoundProtWrite; + ProtExec = *FoundProtExec; + } +} void MmapWriteExecChecker::checkPreCall(const CallEvent &Call, - CheckerContext &C) const { + CheckerContext &C) const { if (matchesAny(Call, MmapFn, MprotectFn)) { SVal ProtVal = Call.getArgSVal(2); auto ProtLoc = ProtVal.getAs(); if (!ProtLoc) return; int64_t Prot = ProtLoc->getValue().getSExtValue(); - if (ProtExecOv != ProtExec) - ProtExec = ProtExecOv; - if (ProtReadOv != ProtRead) - ProtRead = ProtReadOv; - - // Wrong settings - if (ProtRead == ProtExec) - return; - if ((Prot & (ProtWrite | ProtExec)) == (ProtWrite | ProtExec)) { + if ((Prot & ProtWrite) && (Prot & ProtExec)) { ExplodedNode *N = C.generateNonFatalErrorNode(); if (!N) return; @@ -80,17 +87,10 @@ void MmapWriteExecChecker::checkPreCall(const CallEvent &Call, } } -void ento::registerMmapWriteExecChecker(CheckerManager &mgr) { - MmapWriteExecChecker *Mwec = - mgr.registerChecker(); - Mwec->ProtExecOv = - mgr.getAnalyzerOptions() - .getCheckerIntegerOption(Mwec, "MmapProtExec"); - Mwec->ProtReadOv = - mgr.getAnalyzerOptions() - .getCheckerIntegerOption(Mwec, "MmapProtRead"); +void ento::registerMmapWriteExecChecker(CheckerManager &Mgr) { + Mgr.registerChecker(); } -bool ento::shouldRegisterMmapWriteExecChecker(const CheckerManager &mgr) { +bool ento::shouldRegisterMmapWriteExecChecker(const CheckerManager &) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp index eea93a41f1384..b856b0edc6151 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp @@ -19,6 +19,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/FormatVariadic.h" using namespace clang; using namespace ento; @@ -40,6 +41,11 @@ class PointerSubChecker "Indexing the address of a variable with other than 1 at this place " "is undefined behavior."; + /// Check that an array is indexed in the allowed range that is 0 to "one + /// after the end". The "array" can be address of a non-array variable. + /// @param E Expression of the pointer subtraction. + /// @param ElemReg An indexed region in the subtraction expression. + /// @param Reg Region of the other side of the expression. bool checkArrayBounds(CheckerContext &C, const Expr *E, const ElementRegion *ElemReg, const MemRegion *Reg) const; @@ -49,12 +55,28 @@ class PointerSubChecker }; } +static bool isArrayVar(const MemRegion *R) { + while (R) { + if (isa(R)) + return true; + if (const auto *ER = dyn_cast(R)) + R = ER->getSuperRegion(); + else + return false; + } + return false; +} + bool PointerSubChecker::checkArrayBounds(CheckerContext &C, const Expr *E, const ElementRegion *ElemReg, const MemRegion *Reg) const { if (!ElemReg) return true; + const MemRegion *SuperReg = ElemReg->getSuperRegion(); + if (!isArrayVar(SuperReg)) + return true; + auto ReportBug = [&](const llvm::StringLiteral &Msg) { if (ExplodedNode *N = C.generateNonFatalErrorNode()) { auto R = std::make_unique(BT, Msg, N); @@ -64,10 +86,10 @@ bool PointerSubChecker::checkArrayBounds(CheckerContext &C, const Expr *E, }; ProgramStateRef State = C.getState(); - const MemRegion *SuperReg = ElemReg->getSuperRegion(); SValBuilder &SVB = C.getSValBuilder(); if (SuperReg == Reg) { + // Case like `(&x + 1) - &x`. Only 1 or 0 is allowed as index. if (const llvm::APSInt *I = SVB.getKnownValue(State, ElemReg->getIndex()); I && (!I->isOne() && !I->isZero())) ReportBug(Msg_BadVarIndex); @@ -121,8 +143,9 @@ void PointerSubChecker::checkPreStmt(const BinaryOperator *B, if (LR == RR) return; - // No warning if one operand is unknown. - if (isa(LR) || isa(RR)) + // No warning if one operand is unknown or resides in a region that could be + // equal to the other. + if (LR->getSymbolicBase() || RR->getSymbolicBase()) return; const auto *ElemLR = dyn_cast(LR); @@ -159,12 +182,16 @@ void PointerSubChecker::checkPreStmt(const BinaryOperator *B, // do_something(&a.array[5] - &b.array[5]); // In this case don't emit notes. if (DiffDeclL != DiffDeclR) { - if (DiffDeclL) - R->addNote("Array at the left-hand side of subtraction", - {DiffDeclL, C.getSourceManager()}); - if (DiffDeclR) - R->addNote("Array at the right-hand side of subtraction", - {DiffDeclR, C.getSourceManager()}); + auto AddNote = [&R, &C](const ValueDecl *D, StringRef SideStr) { + if (D) { + std::string Msg = llvm::formatv( + "{0} at the {1}-hand side of subtraction", + D->getType()->isArrayType() ? "Array" : "Object", SideStr); + R->addNote(Msg, {D, C.getSourceManager()}); + } + }; + AddNote(DiffDeclL, "left"); + AddNote(DiffDeclR, "right"); } C.emitReport(std::move(R)); } diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp index e8d538388e56c..4454f30630e27 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp @@ -254,7 +254,8 @@ inline void assertStreamStateOpened(const StreamState *SS) { } class StreamChecker : public Checker { + check::DeadSymbols, check::PointerEscape, + check::ASTDecl> { BugType BT_FileNull{this, "NULL stream pointer", "Stream handling error"}; BugType BT_UseAfterClose{this, "Closed stream", "Stream handling error"}; BugType BT_UseAfterOpenFailed{this, "Invalid stream", @@ -276,11 +277,21 @@ class StreamChecker : public Checker OptInt = - tryExpandAsInteger("EOF", C.getPreprocessor())) + if (const std::optional OptInt = tryExpandAsInteger("EOF", PP)) EofVal = *OptInt; else EofVal = -1; - if (const std::optional OptInt = - tryExpandAsInteger("SEEK_SET", C.getPreprocessor())) + if (const std::optional OptInt = tryExpandAsInteger("SEEK_SET", PP)) SeekSetVal = *OptInt; - if (const std::optional OptInt = - tryExpandAsInteger("SEEK_END", C.getPreprocessor())) + if (const std::optional OptInt = tryExpandAsInteger("SEEK_END", PP)) SeekEndVal = *OptInt; - if (const std::optional OptInt = - tryExpandAsInteger("SEEK_CUR", C.getPreprocessor())) + if (const std::optional OptInt = tryExpandAsInteger("SEEK_CUR", PP)) SeekCurVal = *OptInt; } - void initVaListType(CheckerContext &C) const { - VaListType = C.getASTContext().getBuiltinVaListType().getCanonicalType(); - } - /// Searches for the ExplodedNode where the file descriptor was acquired for /// StreamSym. static const ExplodedNode *getAcquisitionSite(const ExplodedNode *N, @@ -865,9 +872,6 @@ static ProgramStateRef escapeArgs(ProgramStateRef State, CheckerContext &C, void StreamChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { - initMacroValues(C); - initVaListType(C); - const FnDescription *Desc = lookupFn(Call); if (!Desc || !Desc->PreFn) return; @@ -887,6 +891,30 @@ bool StreamChecker::evalCall(const CallEvent &Call, CheckerContext &C) const { return C.isDifferent(); } +ProgramStateRef StreamChecker::assumeNoAliasingWithStdStreams( + ProgramStateRef State, DefinedSVal RetVal, CheckerContext &C) const { + auto assumeRetNE = [&C, RetVal](ProgramStateRef State, + const VarDecl *Var) -> ProgramStateRef { + if (!Var) + return State; + const auto *LCtx = C.getLocationContext(); + auto &StoreMgr = C.getStoreManager(); + auto &SVB = C.getSValBuilder(); + SVal VarValue = State->getSVal(StoreMgr.getLValueVar(Var, LCtx)); + auto NoAliasState = + SVB.evalBinOp(State, BO_NE, RetVal, VarValue, SVB.getConditionType()) + .castAs(); + return State->assume(NoAliasState, true); + }; + + assert(State); + State = assumeRetNE(State, StdinDecl); + State = assumeRetNE(State, StdoutDecl); + State = assumeRetNE(State, StderrDecl); + assert(State); + return State; +} + void StreamChecker::evalFopen(const FnDescription *Desc, const CallEvent &Call, CheckerContext &C) const { ProgramStateRef State = C.getState(); @@ -911,6 +939,8 @@ void StreamChecker::evalFopen(const FnDescription *Desc, const CallEvent &Call, StateNull = StateNull->set(RetSym, StreamState::getOpenFailed(Desc)); + StateNotNull = assumeNoAliasingWithStdStreams(StateNotNull, RetVal, C); + C.addTransition(StateNotNull, constructLeakNoteTag(C, RetSym, "Stream opened here")); C.addTransition(StateNull); @@ -2017,6 +2047,38 @@ ProgramStateRef StreamChecker::checkPointerEscape( return State; } +static const VarDecl * +getGlobalStreamPointerByName(const TranslationUnitDecl *TU, StringRef VarName) { + ASTContext &Ctx = TU->getASTContext(); + const auto &SM = Ctx.getSourceManager(); + const QualType FileTy = Ctx.getFILEType(); + + if (FileTy.isNull()) + return nullptr; + + const QualType FilePtrTy = Ctx.getPointerType(FileTy).getCanonicalType(); + + auto LookupRes = TU->lookup(&Ctx.Idents.get(VarName)); + for (const Decl *D : LookupRes) { + if (auto *VD = dyn_cast_or_null(D)) { + if (SM.isInSystemHeader(VD->getLocation()) && VD->hasExternalStorage() && + VD->getType().getCanonicalType() == FilePtrTy) { + return VD; + } + } + } + return nullptr; +} + +void StreamChecker::checkASTDecl(const TranslationUnitDecl *TU, + AnalysisManager &Mgr, BugReporter &) const { + StdinDecl = getGlobalStreamPointerByName(TU, "stdin"); + StdoutDecl = getGlobalStreamPointerByName(TU, "stdout"); + StderrDecl = getGlobalStreamPointerByName(TU, "stderr"); + VaListType = TU->getASTContext().getBuiltinVaListType().getCanonicalType(); + initMacroValues(Mgr.getPreprocessor()); +} + //===----------------------------------------------------------------------===// // Checker registration. //===----------------------------------------------------------------------===// diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index e2002bfbe594a..d73dc40cf03fb 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -2198,7 +2198,7 @@ const Decl *PathSensitiveBugReport::getDeclWithIssue() const { void BasicBugReport::Profile(llvm::FoldingSetNodeID& hash) const { hash.AddInteger(static_cast(getKind())); hash.AddPointer(&BT); - hash.AddString(Description); + hash.AddString(getShortDescription()); assert(Location.isValid()); Location.Profile(hash); @@ -2213,7 +2213,7 @@ void BasicBugReport::Profile(llvm::FoldingSetNodeID& hash) const { void PathSensitiveBugReport::Profile(llvm::FoldingSetNodeID &hash) const { hash.AddInteger(static_cast(getKind())); hash.AddPointer(&BT); - hash.AddString(Description); + hash.AddString(getShortDescription()); PathDiagnosticLocation UL = getUniqueingLocation(); if (UL.isValid()) { UL.Profile(hash); diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp index 0e317ec765ec0..eba224b8ec01c 100644 --- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -923,12 +923,31 @@ SVal AnyCXXConstructorCall::getCXXThisVal() const { return UnknownVal(); } +static bool isWithinStdNamespace(const Decl *D) { + const DeclContext *DC = D->getDeclContext(); + while (DC) { + if (const auto *NS = dyn_cast(DC); + NS && NS->isStdNamespace()) + return true; + DC = DC->getParent(); + } + return false; +} + void AnyCXXConstructorCall::getExtraInvalidatedValues(ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const { SVal V = getCXXThisVal(); if (SymbolRef Sym = V.getAsSymbol(true)) ETraits->setTrait(Sym, RegionAndSymbolInvalidationTraits::TK_SuppressEscape); + + // Standard classes don't reinterpret-cast and modify super regions. + const bool IsStdClassCtor = isWithinStdNamespace(getDecl()); + if (const MemRegion *Obj = V.getAsRegion(); Obj && IsStdClassCtor) { + ETraits->setTrait( + Obj, RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion); + } + Values.push_back(V); } diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 33fc4d6f6c9cf..38aacd3b3b02f 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1811,7 +1811,9 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass: case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass: case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: + case Stmt::OMPReverseDirectiveClass: case Stmt::OMPTileDirectiveClass: + case Stmt::OMPInterchangeDirectiveClass: case Stmt::OMPInteropDirectiveClass: case Stmt::OMPDispatchDirectiveClass: case Stmt::OMPMaskedDirectiveClass: diff --git a/clang/lib/Tooling/ArgumentsAdjusters.cpp b/clang/lib/Tooling/ArgumentsAdjusters.cpp index df4c74205b087..d01c57ee69c00 100644 --- a/clang/lib/Tooling/ArgumentsAdjusters.cpp +++ b/clang/lib/Tooling/ArgumentsAdjusters.cpp @@ -49,10 +49,11 @@ ArgumentsAdjuster getClangSyntaxOnlyAdjuster() { })) continue; - if (!Arg.starts_with("-fcolor-diagnostics") && + if (Arg != "-c" && Arg != "-S" && + !Arg.starts_with("-fcolor-diagnostics") && !Arg.starts_with("-fdiagnostics-color")) AdjustedArgs.push_back(Args[i]); - // If we strip a color option, make sure we strip any preceeding `-Xclang` + // If we strip an option, make sure we strip any preceeding `-Xclang` // option as well. // FIXME: This should be added to most argument adjusters! else if (!AdjustedArgs.empty() && AdjustedArgs.back() == "-Xclang") diff --git a/clang/lib/Tooling/DependencyScanning/CMakeLists.txt b/clang/lib/Tooling/DependencyScanning/CMakeLists.txt index bc807e162c919..66795b0be0baa 100644 --- a/clang/lib/Tooling/DependencyScanning/CMakeLists.txt +++ b/clang/lib/Tooling/DependencyScanning/CMakeLists.txt @@ -19,7 +19,6 @@ add_clang_library(clangDependencyScanning LINK_LIBS clangAST clangBasic - clangCodeGen clangDriver clangFrontend clangLex diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index 0f82f22d8b9a8..91842627b001c 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -10,7 +10,6 @@ #include "clang/Basic/DiagnosticDriver.h" #include "clang/Basic/DiagnosticFrontend.h" #include "clang/Basic/DiagnosticSerialization.h" -#include "clang/CodeGen/ObjectFilePCHContainerOperations.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Driver/Job.h" @@ -21,6 +20,7 @@ #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Frontend/Utils.h" #include "clang/Lex/PreprocessorOptions.h" +#include "clang/Serialization/ObjectFilePCHContainerReader.h" #include "clang/Tooling/DependencyScanning/DependencyScanningService.h" #include "clang/Tooling/DependencyScanning/ModuleDepCollector.h" #include "clang/Tooling/Tooling.h" diff --git a/clang/test/APINotes/Inputs/Headers/Methods.apinotes b/clang/test/APINotes/Inputs/Headers/Methods.apinotes new file mode 100644 index 0000000000000..618c2cb14b47f --- /dev/null +++ b/clang/test/APINotes/Inputs/Headers/Methods.apinotes @@ -0,0 +1,32 @@ +--- +Name: Methods +Tags: +- Name: IntWrapper + Methods: + - Name: getIncremented + Availability: none + AvailabilityMsg: "oh no" + - Name: getDecremented + Availability: none + AvailabilityMsg: "this should have no effect" +- Name: Outer + Tags: + - Name: Inner + Methods: + - Name: getDecremented + Availability: none + AvailabilityMsg: "nope" + - Name: getIncremented + Availability: none + AvailabilityMsg: "this should have no effect" + Methods: + - Name: getDecremented + Availability: none + AvailabilityMsg: "this should have no effect" +Functions: +- Name: getIncremented + Availability: none + AvailabilityMsg: "this should have no effect" +- Name: getDecremented + Availability: none + AvailabilityMsg: "this should have no effect" diff --git a/clang/test/APINotes/Inputs/Headers/Methods.h b/clang/test/APINotes/Inputs/Headers/Methods.h new file mode 100644 index 0000000000000..cbb57ccd0afbd --- /dev/null +++ b/clang/test/APINotes/Inputs/Headers/Methods.h @@ -0,0 +1,19 @@ +struct IntWrapper { + int value; + + IntWrapper getIncremented() const { return {value + 1}; } + + IntWrapper operator+(const IntWrapper& RHS) const { return {value + RHS.value}; } +}; + +struct Outer { + struct Inner { + int value; + + Inner getDecremented() const { return {value - 1}; } + + bool operator==(const Inner& RHS) const { + return value == RHS.value; + } + }; +}; diff --git a/clang/test/APINotes/Inputs/Headers/Namespaces.apinotes b/clang/test/APINotes/Inputs/Headers/Namespaces.apinotes index e9da36787b638..b7d962e0efda6 100644 --- a/clang/test/APINotes/Inputs/Headers/Namespaces.apinotes +++ b/clang/test/APINotes/Inputs/Headers/Namespaces.apinotes @@ -38,6 +38,12 @@ Namespaces: Tags: - Name: char_box SwiftName: NestedCharBox + Methods: + - Name: methodInNestedNamespace + SwiftName: swiftMethodInNestedNamespace() + Tags: + - Name: inner_char_box + SwiftName: InnerCharBox Namespaces: - Name: Namespace1 Tags: diff --git a/clang/test/APINotes/Inputs/Headers/Namespaces.h b/clang/test/APINotes/Inputs/Headers/Namespaces.h index 6a79e996be86c..c7a891f205c06 100644 --- a/clang/test/APINotes/Inputs/Headers/Namespaces.h +++ b/clang/test/APINotes/Inputs/Headers/Namespaces.h @@ -9,6 +9,10 @@ namespace Nested1 { void funcInNestedNamespace(int i); struct char_box { char c; + void methodInNestedNamespace(); + struct inner_char_box { + char c; + }; }; } diff --git a/clang/test/APINotes/Inputs/Headers/module.modulemap b/clang/test/APINotes/Inputs/Headers/module.modulemap index d515169184f4f..faf6042c78d57 100644 --- a/clang/test/APINotes/Inputs/Headers/module.modulemap +++ b/clang/test/APINotes/Inputs/Headers/module.modulemap @@ -24,6 +24,10 @@ module BrokenTypes { header "BrokenTypes.h" } +module Methods { + header "Methods.h" +} + module ModuleWithWrongCase { header "ModuleWithWrongCase.h" } diff --git a/clang/test/APINotes/methods.cpp b/clang/test/APINotes/methods.cpp new file mode 100644 index 0000000000000..910565745bea2 --- /dev/null +++ b/clang/test/APINotes/methods.cpp @@ -0,0 +1,17 @@ +// RUN: rm -rf %t && mkdir -p %t +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Methods -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -x c++ +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Methods -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter IntWrapper::getIncremented -x c++ | FileCheck --check-prefix=CHECK-METHOD %s +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Methods -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Outer::Inner::getDecremented -x c++ | FileCheck --check-prefix=CHECK-DEEP-METHOD %s + +#include "Methods.h" + +// CHECK-METHOD: Dumping IntWrapper::getIncremented: +// CHECK-METHOD-NEXT: CXXMethodDecl {{.+}} getIncremented +// CHECK-METHOD: UnavailableAttr {{.+}} <> "oh no" + +// CHECK-DEEP-METHOD: Dumping Outer::Inner::getDecremented: +// CHECK-DEEP-METHOD-NEXT: CXXMethodDecl {{.+}} getDecremented +// CHECK-DEEP-METHOD: UnavailableAttr {{.+}} <> "nope" + +// CHECK-METHOD-NOT: this should have no effect +// CHECK-DEEP-METHOD-NOT: this should have no effect diff --git a/clang/test/APINotes/namespaces.cpp b/clang/test/APINotes/namespaces.cpp index c19eee565c2da..df108b02e6301 100644 --- a/clang/test/APINotes/namespaces.cpp +++ b/clang/test/APINotes/namespaces.cpp @@ -8,7 +8,9 @@ // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested1::varInNestedNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-GLOBAL-IN-NESTED-NAMESPACE %s // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested2::varInNestedNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-ANOTHER-GLOBAL-IN-NESTED-NAMESPACE %s // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested1::char_box -x objective-c++ | FileCheck -check-prefix=CHECK-STRUCT-IN-NESTED-NAMESPACE %s +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested1::char_box::inner_char_box -x objective-c++ | FileCheck -check-prefix=CHECK-STRUCT-IN-STRUCT-IN-NESTED-NAMESPACE %s // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested1::funcInNestedNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-FUNC-IN-NESTED-NAMESPACE %s +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested1::char_box::methodInNestedNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-METHOD-IN-NESTED-NAMESPACE %s // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested1::Namespace1::char_box -x objective-c++ | FileCheck -check-prefix=CHECK-STRUCT-IN-DEEP-NESTED-NAMESPACE %s // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter varInInlineNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-GLOBAL-IN-INLINE-NAMESPACE %s // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter funcInInlineNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-FUNC-IN-INLINE-NAMESPACE %s @@ -55,6 +57,14 @@ // CHECK-STRUCT-IN-NESTED-NAMESPACE-NEXT: CXXRecordDecl {{.+}} imported in Namespaces struct char_box // CHECK-STRUCT-IN-NESTED-NAMESPACE: SwiftNameAttr {{.+}} <> "NestedCharBox" +// CHECK-STRUCT-IN-STRUCT-IN-NESTED-NAMESPACE: Dumping Namespace1::Nested1::char_box::inner_char_box: +// CHECK-STRUCT-IN-STRUCT-IN-NESTED-NAMESPACE-NEXT: CXXRecordDecl {{.+}} imported in Namespaces struct inner_char_box +// CHECK-STRUCT-IN-STRUCT-IN-NESTED-NAMESPACE: SwiftNameAttr {{.+}} <> "InnerCharBox" + +// CHECK-METHOD-IN-NESTED-NAMESPACE: Dumping Namespace1::Nested1::char_box::methodInNestedNamespace: +// CHECK-METHOD-IN-NESTED-NAMESPACE-NEXT: CXXMethodDecl {{.+}} imported in Namespaces methodInNestedNamespace +// CHECK-METHOD-IN-NESTED-NAMESPACE: SwiftNameAttr {{.+}} <> "swiftMethodInNestedNamespace()" + // CHECK-STRUCT-IN-DEEP-NESTED-NAMESPACE: Dumping Namespace1::Nested1::Namespace1::char_box: // CHECK-STRUCT-IN-DEEP-NESTED-NAMESPACE-NEXT: CXXRecordDecl {{.+}} imported in Namespaces struct char_box // CHECK-STRUCT-IN-DEEP-NESTED-NAMESPACE: SwiftNameAttr {{.+}} <> "DeepNestedCharBox" diff --git a/clang/test/AST/Interp/atomic.c b/clang/test/AST/Interp/atomic.c index c5fd9ab222934..c8469d4a938b8 100644 --- a/clang/test/AST/Interp/atomic.c +++ b/clang/test/AST/Interp/atomic.c @@ -58,3 +58,16 @@ _Static_assert(atomic_is_lock_free((atomic_short*)0), ""); _Static_assert(atomic_is_lock_free((atomic_int*)0), ""); _Static_assert(atomic_is_lock_free((atomic_long*)0), ""); _Static_assert(atomic_is_lock_free(0 + (atomic_char*)0), ""); + +_Static_assert(__atomic_always_lock_free(1, (void*)1), ""); +_Static_assert(__atomic_always_lock_free(1, (void*)-1), ""); +_Static_assert(!__atomic_always_lock_free(4, (void*)2), ""); +_Static_assert(!__atomic_always_lock_free(4, (void*)-2), ""); +_Static_assert(__atomic_always_lock_free(4, (void*)4), ""); +_Static_assert(__atomic_always_lock_free(4, (void*)-4), ""); + +_Static_assert(__atomic_always_lock_free(1, "string"), ""); +_Static_assert(!__atomic_always_lock_free(2, "string"), ""); +_Static_assert(__atomic_always_lock_free(2, (int[2]){}), ""); +void dummyfn(); +_Static_assert(__atomic_always_lock_free(2, dummyfn) || 1, ""); diff --git a/clang/test/AST/Interp/builtin-constant-p.cpp b/clang/test/AST/Interp/builtin-constant-p.cpp new file mode 100644 index 0000000000000..0d222d1c96277 --- /dev/null +++ b/clang/test/AST/Interp/builtin-constant-p.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s +// RUN: %clang_cc1 -verify=ref,both %s + + +static_assert(__builtin_constant_p(12), ""); +static_assert(__builtin_constant_p(1.0), ""); + +constexpr int I = 100; +static_assert(__builtin_constant_p(I), ""); +static_assert(__builtin_constant_p(I + 10), ""); +static_assert(__builtin_constant_p(I + 10.0), ""); +static_assert(__builtin_constant_p(nullptr), ""); +static_assert(__builtin_constant_p(&I), ""); // both-error {{failed due to requirement}} +static_assert(__builtin_constant_p((void)I), ""); // both-error {{failed due to requirement}} diff --git a/clang/test/AST/Interp/builtins.cpp b/clang/test/AST/Interp/builtins.cpp index a74b68bb9d89b..9b2b20773be58 100644 --- a/clang/test/AST/Interp/builtins.cpp +++ b/clang/test/AST/Interp/builtins.cpp @@ -31,3 +31,8 @@ constexpr bool assume() { return true; } static_assert(assume(), ""); + +void test_builtin_os_log(void *buf, int i, const char *data) { + constexpr int len = __builtin_os_log_format_buffer_size("%d %{public}s %{private}.16P", i, data, data); + static_assert(len > 0, "Expect len > 0"); +} diff --git a/clang/test/AST/Interp/codegen.cpp b/clang/test/AST/Interp/codegen.cpp new file mode 100644 index 0000000000000..a5583d953d234 --- /dev/null +++ b/clang/test/AST/Interp/codegen.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm -o - %s -fexperimental-new-constant-interpreter | FileCheck %s + + +int arr[2]; +// CHECK: @pastEnd = constant ptr getelementptr (i8, ptr @arr, i64 8) +int &pastEnd = arr[2]; + +// CHECK: @F = constant ptr @arr, align 8 +int &F = arr[0]; + +struct S { + int a; + float c[3]; +}; + +// CHECK: @s = global %struct.S zeroinitializer, align 4 +S s; +// CHECK: @sp = constant ptr getelementptr (i8, ptr @s, i64 16), align 8 +float &sp = s.c[3]; + + +namespace BaseClassOffsets { + struct A { int a; }; + struct B { int b; }; + struct C : A, B { int c; }; + + extern C c; + // CHECK: @_ZN16BaseClassOffsets1aE = global ptr @_ZN16BaseClassOffsets1cE, align 8 + A* a = &c; + // CHECK: @_ZN16BaseClassOffsets1bE = global ptr getelementptr (i8, ptr @_ZN16BaseClassOffsets1cE, i64 4), align 8 + B* b = &c; +} diff --git a/clang/test/AST/Interp/constexpr-subobj-initialization.cpp b/clang/test/AST/Interp/constexpr-subobj-initialization.cpp index 4976b165468bd..1a35994944190 100644 --- a/clang/test/AST/Interp/constexpr-subobj-initialization.cpp +++ b/clang/test/AST/Interp/constexpr-subobj-initialization.cpp @@ -5,8 +5,6 @@ /// Differences: /// 1) The type of the uninitialized base class is printed WITH the namespace, /// i.e. 'baseclass_uninit::DelBase' instead of just 'DelBase'. -/// 2) The location is not the base specifier declaration, but the call site -/// of the constructor. namespace baseclass_uninit { @@ -14,33 +12,29 @@ struct DelBase { constexpr DelBase() = delete; // expected-note {{'DelBase' has been explicitly marked deleted here}} }; -struct Foo : DelBase { +struct Foo : DelBase { // expected-note 2{{constructor of base class 'baseclass_uninit::DelBase' is not called}} constexpr Foo() {}; // expected-error {{call to deleted constructor of 'DelBase'}} }; -constexpr Foo f; // expected-error {{must be initialized by a constant expression}} \ - // expected-note {{constructor of base class 'baseclass_uninit::DelBase' is not called}} +constexpr Foo f; // expected-error {{must be initialized by a constant expression}} struct Bar : Foo { constexpr Bar() {}; }; -constexpr Bar bar; // expected-error {{must be initialized by a constant expression}} \ - // expected-note {{constructor of base class 'baseclass_uninit::DelBase' is not called}} +constexpr Bar bar; // expected-error {{must be initialized by a constant expression}} struct Base {}; -struct A : Base { +struct A : Base { // expected-note {{constructor of base class 'baseclass_uninit::Base' is not called}} constexpr A() : value() {} // expected-error {{member initializer 'value' does not name a non-static data member or base class}} }; -constexpr A a; // expected-error {{must be initialized by a constant expression}} \ - // expected-note {{constructor of base class 'baseclass_uninit::Base' is not called}} +constexpr A a; // expected-error {{must be initialized by a constant expression}} -struct B : Base { +struct B : Base { // expected-note {{constructor of base class 'baseclass_uninit::Base' is not called}} constexpr B() : {} // expected-error {{expected class member or base class name}} }; -constexpr B b; // expected-error {{must be initialized by a constant expression}} \ - // expected-note {{constructor of base class 'baseclass_uninit::Base' is not called}} +constexpr B b; // expected-error {{must be initialized by a constant expression}} } // namespace baseclass_uninit diff --git a/clang/test/AST/Interp/cxx11.cpp b/clang/test/AST/Interp/cxx11.cpp index 82b2727bbadbb..cf2dfba079ef7 100644 --- a/clang/test/AST/Interp/cxx11.cpp +++ b/clang/test/AST/Interp/cxx11.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=both,expected -std=c++11 %s -// RUN: %clang_cc1 -verify=both,ref -std=c++11 %s +// RUN: %clang_cc1 -triple x86_64-linux -fexperimental-new-constant-interpreter -verify=both,expected -std=c++11 %s +// RUN: %clang_cc1 -triple x86_64-linux -verify=both,ref -std=c++11 %s namespace IntOrEnum { const int k = 0; @@ -62,3 +62,101 @@ namespace ReferenceToConst { } }; } + + + +namespace GH50055 { +// Enums without fixed underlying type +enum E1 {e11=-4, e12=4}; +enum E2 {e21=0, e22=4}; +enum E3 {e31=-4, e32=1024}; +enum E4 {e41=0}; +// Empty but as-if it had a single enumerator with value 0 +enum EEmpty {}; + +// Enum with fixed underlying type because the underlying type is explicitly specified +enum EFixed : int {efixed1=-4, efixed2=4}; +// Enum with fixed underlying type because it is scoped +enum class EScoped {escoped1=-4, escoped2=4}; + +enum EMaxInt {emaxint1=-1, emaxint2=__INT_MAX__}; + +enum NumberType {}; + +E2 testDefaultArgForParam(E2 e2Param = (E2)-1) { // ok, not a constant expression context + E2 e2LocalInit = e2Param; // ok, not a constant expression context + return e2LocalInit; +} + +// #include + +void testValueInRangeOfEnumerationValues() { + constexpr E1 x1 = static_cast(-8); + constexpr E1 x2 = static_cast(8); + // both-error@-1 {{integer value 8 is outside the valid range of values [-8, 7] for the enumeration type 'E1'}} + E1 x2b = static_cast(8); // ok, not a constant expression context + + constexpr E2 x3 = static_cast(-8); + // both-error@-1 {{integer value -8 is outside the valid range of values [0, 7] for the enumeration type 'E2'}} + constexpr E2 x4 = static_cast(0); + constexpr E2 x5 = static_cast(8); + // both-error@-1 {{integer value 8 is outside the valid range of values [0, 7] for the enumeration type 'E2'}} + + constexpr E3 x6 = static_cast(-2048); + constexpr E3 x7 = static_cast(-8); + constexpr E3 x8 = static_cast(0); + constexpr E3 x9 = static_cast(8); + constexpr E3 x10 = static_cast(2048); + // both-error@-1 {{integer value 2048 is outside the valid range of values [-2048, 2047] for the enumeration type 'E3'}} + + constexpr E4 x11 = static_cast(0); + constexpr E4 x12 = static_cast(1); + constexpr E4 x13 = static_cast(2); + // both-error@-1 {{integer value 2 is outside the valid range of values [0, 1] for the enumeration type 'E4'}} + + constexpr EEmpty x14 = static_cast(0); + constexpr EEmpty x15 = static_cast(1); + constexpr EEmpty x16 = static_cast(2); + // both-error@-1 {{integer value 2 is outside the valid range of values [0, 1] for the enumeration type 'EEmpty'}} + + constexpr EFixed x17 = static_cast(100); + constexpr EScoped x18 = static_cast(100); + + constexpr EMaxInt x19 = static_cast(__INT_MAX__-1); + constexpr EMaxInt x20 = static_cast((long)__INT_MAX__+1); + // both-error@-1 {{integer value 2147483648 is outside the valid range of values [-2147483648, 2147483647] for the enumeration type 'EMaxInt'}} + + const NumberType neg_one = (NumberType) ((NumberType) 0 - (NumberType) 1); // ok, not a constant expression context +} + +template struct Bitfield { + static constexpr T max = static_cast((1 << size) - 1); // #enum +}; + +void testValueInRangeOfEnumerationValuesViaTemplate() { + Bitfield good; + Bitfield bad; // both-error@#enum {{integer value 15 is outside the valid range of values [0, 7] for the enumeration type 'E2'}} +} + +enum SortOrder { + AscendingOrder, + DescendingOrder +}; + +class A { + static void f(SortOrder order); +}; + +void A::f(SortOrder order) { + if (order == SortOrder(-1)) // ok, not a constant expression context + return; +} +} + +namespace FinalLtorDiags { + template struct A {}; // both-note {{template parameter is declared here}} + int k; + int *q = &k; // both-note {{declared here}} + A c; // both-error {{non-type template argument of type 'int *' is not a constant expression}} \ + // both-note {{read of non-constexpr variable 'q' is not allowed in a constant expression}} +} diff --git a/clang/test/AST/Interp/cxx20.cpp b/clang/test/AST/Interp/cxx20.cpp index 2faacbbf70fd7..da80454b7a820 100644 --- a/clang/test/AST/Interp/cxx20.cpp +++ b/clang/test/AST/Interp/cxx20.cpp @@ -827,3 +827,17 @@ namespace CheckingNullPtrForInitialization { return x; } } + +namespace VariadicCallOperator { + class F { + public: + constexpr void operator()(int a, int b, ...) {} + }; + constexpr int foo() { + F f; + + f(1,2, 3); + return 1; + } + constexpr int A = foo(); +} diff --git a/clang/test/AST/Interp/cxx2a.cpp b/clang/test/AST/Interp/cxx2a.cpp new file mode 100644 index 0000000000000..ad021b30cfd3c --- /dev/null +++ b/clang/test/AST/Interp/cxx2a.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -std=c++2a -fsyntax-only -fcxx-exceptions -verify=ref,both %s +// RUN: %clang_cc1 -std=c++2a -fsyntax-only -fcxx-exceptions -verify=expected,both %s -fexperimental-new-constant-interpreter + +template +struct S { + S() requires (N==1) = default; + S() requires (N==2) {} // both-note {{declared here}} + consteval S() requires (N==3) = default; +}; + +consteval int aConstevalFunction() { // both-error {{consteval function never produces a constant expression}} + S<2> s4; // both-note {{non-constexpr constructor 'S' cannot be used in a constant expression}} + return 0; +} +/// We're NOT calling the above function. The diagnostics should appear anyway. + +namespace Covariant { + struct A { + virtual constexpr char f() const { return 'Z'; } + char a = f(); + }; + + struct D : A {}; + struct Covariant1 { + D d; + virtual const A *f() const; + }; + + struct Covariant3 : Covariant1 { + constexpr virtual const D *f() const { return &this->d; } + }; + + constexpr Covariant3 cb; + constexpr const Covariant1 *cb1 = &cb; + static_assert(cb1->f()->a == 'Z'); +} diff --git a/clang/test/AST/Interp/lifetimes.cpp b/clang/test/AST/Interp/lifetimes.cpp index d47533ab547b3..9fca54fe11120 100644 --- a/clang/test/AST/Interp/lifetimes.cpp +++ b/clang/test/AST/Interp/lifetimes.cpp @@ -33,3 +33,30 @@ struct S { constexpr int k1 = S().t; // both-error {{must be initialized by a constant expression}} \ // ref-note {{in call to}} \ // expected-note {{in call to}} + + +namespace MoveFnWorks { + template constexpr T &&ref(T &&t) { return (T&&)t; } + + struct Buf {}; + + struct A { + constexpr A(Buf &buf) : buf(buf) { } + Buf &buf; + }; + + constexpr bool dtor_calls_dtor() { + struct B { + A &&d; + constexpr B(Buf &buf) : d(ref(A(buf))) {} + }; + + Buf buf; + { + B b(buf); + } + + return true; + } + static_assert(dtor_calls_dtor(), ""); +} diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index 9cd65462a0af3..815fb67b9bbfc 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -1214,6 +1214,10 @@ namespace StmtExprs { return 76; } static_assert(foo() == 76, ""); + + namespace CrossFuncLabelDiff { + constexpr long a(bool x) { return x ? 0 : (intptr_t)&&lbl + (0 && ({lbl: 0;})); } + } } #endif @@ -1303,3 +1307,15 @@ namespace VolatileReads { static_assert(b, ""); // both-error {{not an integral constant expression}} \ // both-note {{read of volatile-qualified type 'const volatile int' is not allowed in a constant expression}} } +#if __cplusplus >= 201703L +namespace { + struct C { + int x; + }; + + template void f() { + const auto &[c] = *p; + &c; // both-warning {{expression result unused}} + } +} +#endif diff --git a/clang/test/AST/Interp/new-delete.cpp b/clang/test/AST/Interp/new-delete.cpp index 04ce3ae5f6637..7a85def784920 100644 --- a/clang/test/AST/Interp/new-delete.cpp +++ b/clang/test/AST/Interp/new-delete.cpp @@ -476,7 +476,80 @@ constexpr Sp ss[] = {Sp{new int{154}}}; // both-error {{must be initialized by a // both-note {{pointer to heap-allocated object}} \ // both-note {{allocation performed here}} +namespace DeleteRunsDtors { + struct InnerFoo { + int *mem; + constexpr ~InnerFoo() { + delete mem; + } + }; + + struct Foo { + int *a; + InnerFoo IF; + + constexpr Foo() { + a = new int(13); + IF.mem = new int(100); + } + constexpr ~Foo() { delete a; } + }; + + constexpr int abc() { + Foo *F = new Foo(); + int n = *F->a; + delete F; + return n; + } + static_assert(abc() == 13); + + constexpr int abc2() { + Foo *f = new Foo[3]; + + delete[] f; + + return 1; + } + static_assert(abc2() == 1); +} + +/// FIXME: There is a slight difference in diagnostics here, because we don't +/// create a new frame when we delete record fields or bases at all. +namespace FaultyDtorCalledByDelete { + struct InnerFoo { + int *mem; + constexpr ~InnerFoo() { + if (mem) { + (void)(1/0); // both-warning {{division by zero is undefined}} \ + // both-note {{division by zero}} + } + delete mem; + } + }; + + struct Foo { + int *a; + InnerFoo IF; + + constexpr Foo() { + a = new int(13); + IF.mem = new int(100); + } + constexpr ~Foo() { delete a; } + }; + + constexpr int abc() { + Foo *F = new Foo(); + int n = *F->a; + delete F; // both-note {{in call to}} \ + // ref-note {{in call to}} + + return n; + } + static_assert(abc() == 13); // both-error {{not an integral constant expression}} \ + // both-note {{in call to 'abc()'}} +} #else @@ -487,4 +560,9 @@ constexpr int a() { // both-error {{never produces a constant expression}} } static_assert(a() == 1, ""); // both-error {{not an integral constant expression}} \ // both-note {{in call to 'a()'}} + + +static_assert(true ? *new int : 4, ""); // both-error {{expression is not an integral constant expression}} \ + // both-note {{read of uninitialized object is not allowed in a constant expression}} + #endif diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 2fc88a0b1df6a..479c0487fecae 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -1537,3 +1537,42 @@ namespace BitSet { Bitset() }; } + +namespace ArrayInitChain { + struct StringLiteral { + const char *S; + }; + + struct CustomOperandVal { + StringLiteral Str; + unsigned Width; + unsigned Mask = Width + 1; + }; + + constexpr CustomOperandVal A[] = { + {}, + {{"depctr_hold_cnt"}, 12, 13}, + }; + static_assert(A[0].Str.S == nullptr, ""); + static_assert(A[0].Width == 0, ""); + static_assert(A[0].Mask == 1, ""); + + static_assert(A[1].Width == 12, ""); + static_assert(A[1].Mask == 13, ""); +} + +#if __cplusplus >= 202002L +namespace ctorOverrider { + // Ensure that we pick the right final overrider during construction. + struct A { + virtual constexpr char f() const { return 'A'; } + char a = f(); + }; + + struct Covariant1 { + A d; + }; + + constexpr Covariant1 cb; +} +#endif diff --git a/clang/test/AST/ast-dump-ctad-alias.cpp b/clang/test/AST/ast-dump-ctad-alias.cpp index a088c0a7b0272..b1631f7822ce0 100644 --- a/clang/test/AST/ast-dump-ctad-alias.cpp +++ b/clang/test/AST/ast-dump-ctad-alias.cpp @@ -32,22 +32,24 @@ Out2::AInner t(1.0); // CHECK-NEXT: | | |-UnresolvedLookupExpr {{.*}} '' lvalue (no ADL) = 'Concept' // CHECK-NEXT: | | | |-TemplateArgument type 'int' // CHECK-NEXT: | | | | `-BuiltinType {{.*}} 'int' -// CHECK-NEXT: | | | `-TemplateArgument type 'type-parameter-1-0' -// CHECK-NEXT: | | | `-TemplateTypeParmType {{.*}} 'type-parameter-1-0' dependent depth 1 index 0 +// CHECK-NEXT: | | | `-TemplateArgument type 'Y':'type-parameter-1-0' +// CHECK-NEXT: | | | `-TemplateTypeParmType {{.*}} 'Y' dependent depth 1 index 0 +// CHECK-NEXT: | | | `-TemplateTypeParm {{.*}} 'Y' // CHECK-NEXT: | | `-TypeTraitExpr {{.*}} 'bool' __is_deducible // CHECK-NEXT: | | |-DeducedTemplateSpecializationType {{.*}} 'Out2::AInner' dependent // CHECK-NEXT: | | | `-name: 'Out2::AInner' // CHECK-NEXT: | | | `-TypeAliasTemplateDecl {{.+}} AInner{{$}} -// CHECK-NEXT: | | `-ElaboratedType {{.*}} 'Inner' sugar dependent -// CHECK-NEXT: | | `-TemplateSpecializationType {{.*}} 'Inner' dependent +// CHECK-NEXT: | | `-ElaboratedType {{.*}} 'Inner' sugar dependent +// CHECK-NEXT: | | `-TemplateSpecializationType {{.*}} 'Inner' dependent // CHECK-NEXT: | | |-name: 'Inner':'Out::Inner' qualified // CHECK-NEXT: | | | `-ClassTemplateDecl {{.+}} Inner{{$}} -// CHECK-NEXT: | | `-TemplateArgument type 'type-parameter-1-0' -// CHECK-NEXT: | | `-SubstTemplateTypeParmType {{.*}} 'type-parameter-1-0' +// CHECK-NEXT: | | `-TemplateArgument type 'Y' +// CHECK-NEXT: | | `-SubstTemplateTypeParmType {{.*}} 'Y' // CHECK-NEXT: | | |-FunctionTemplate {{.*}} '' -// CHECK-NEXT: | | `-TemplateTypeParmType {{.*}} 'type-parameter-1-0' dependent depth 1 index 0 -// CHECK-NEXT: | |-CXXDeductionGuideDecl {{.*}} 'auto (type-parameter-0-0) -> Inner' -// CHECK-NEXT: | | `-ParmVarDecl {{.*}} 'type-parameter-0-0' +// CHECK-NEXT: | | `-TemplateTypeParmType {{.*}} 'Y' dependent depth 1 index 0 +// CHECK-NEXT: | | `-TemplateTypeParm {{.*}} 'Y' +// CHECK-NEXT: | |-CXXDeductionGuideDecl {{.*}} 'auto (Y) -> Inner' +// CHECK-NEXT: | | `-ParmVarDecl {{.*}} 'Y' // CHECK-NEXT: | `-CXXDeductionGuideDecl {{.*}} used 'auto (double) -> Inner' implicit_instantiation // CHECK-NEXT: | |-TemplateArgument type 'double' // CHECK-NEXT: | | `-BuiltinType {{.*}} 'double' @@ -77,8 +79,8 @@ AFoo3 afoo3{0, 1}; // CHECK-NEXT: | |-UnresolvedLookupExpr {{.*}} '' lvalue (no ADL) = 'Concept' // CHECK-NEXT: | | |-TemplateArgument type 'int' // CHECK-NEXT: | | | `-BuiltinType {{.*}} 'int' -// CHECK-NEXT: | | `-TemplateArgument type 'type-parameter-0-1' -// CHECK-NEXT: | | `-TemplateTypeParmType {{.*}} 'type-parameter-0-1' dependent depth 0 index 1 +// CHECK-NEXT: | | `-TemplateArgument type 'V' +// CHECK-NEXT: | | `-TemplateTypeParmType {{.*}} 'V' dependent depth 0 index 1 template struct Foo { @@ -88,16 +90,16 @@ struct Foo { template using AFoo = Foo; AFoo a(1, 2); -// CHECK: |-CXXDeductionGuideDecl {{.*}} implicit 'auto (type-parameter-0-0...) -> Foo' -// CHECK-NEXT: | | `-ParmVarDecl {{.*}} 'type-parameter-0-0...' pack +// CHECK: |-CXXDeductionGuideDecl {{.*}} implicit 'auto (T2...) -> Foo' +// CHECK-NEXT: | | `-ParmVarDecl {{.*}} 'T2...' pack // CHECK-NEXT: | `-CXXDeductionGuideDecl {{.*}} implicit used 'auto (int, int) -> Foo' implicit_instantiation template using BFoo = Foo; BFoo b2(1.0, 2.0); -// CHECK: |-CXXDeductionGuideDecl {{.*}} implicit 'auto (type-parameter-0-0, type-parameter-0-0) -> Foo' -// CHECK-NEXT: | | |-ParmVarDecl {{.*}} 'type-parameter-0-0' -// CHECK-NEXT: | | `-ParmVarDecl {{.*}} 'type-parameter-0-0' +// CHECK: |-CXXDeductionGuideDecl {{.*}} implicit 'auto (T, T) -> Foo' +// CHECK-NEXT: | | |-ParmVarDecl {{.*}} 'T' +// CHECK-NEXT: | | `-ParmVarDecl {{.*}} 'T' // CHECK-NEXT: | `-CXXDeductionGuideDecl {{.*}} implicit used 'auto (double, double) -> Foo' implicit_instantiation namespace GH90209 { diff --git a/clang/test/AST/ast-dump-openmp-for-simd.c b/clang/test/AST/ast-dump-openmp-for-simd.c index 5dcd9175d4998..06ae226ccb17d 100644 --- a/clang/test/AST/ast-dump-openmp-for-simd.c +++ b/clang/test/AST/ast-dump-openmp-for-simd.c @@ -41,7 +41,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | `-CompoundStmt {{.*}} // CHECK-NEXT: | `-OMPForSimdDirective {{.*}} // CHECK-NEXT: | `-CapturedStmt {{.*}} -// CHECK-NEXT: | |-CapturedDecl {{.*}} <> +// CHECK-NEXT: | |-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} // CHECK-NEXT: | | | | `-VarDecl {{.*}} col:12 used i 'int' cinit @@ -65,7 +65,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | `-CompoundStmt {{.*}} // CHECK-NEXT: | `-OMPForSimdDirective {{.*}} // CHECK-NEXT: | `-CapturedStmt {{.*}} -// CHECK-NEXT: | |-CapturedDecl {{.*}} <> +// CHECK-NEXT: | |-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} // CHECK-NEXT: | | | | `-VarDecl {{.*}} col:12 used i 'int' cinit @@ -108,7 +108,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-value: Int 1 // CHECK-NEXT: | | `-IntegerLiteral {{.*}} 'int' 1 // CHECK-NEXT: | `-CapturedStmt {{.*}} -// CHECK-NEXT: | |-CapturedDecl {{.*}} <> +// CHECK-NEXT: | |-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} // CHECK-NEXT: | | | | `-VarDecl {{.*}} col:12 used i 'int' cinit @@ -151,7 +151,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-value: Int 2 // CHECK-NEXT: | | `-IntegerLiteral {{.*}} 'int' 2 // CHECK-NEXT: | `-CapturedStmt {{.*}} -// CHECK-NEXT: | |-CapturedDecl {{.*}} <> +// CHECK-NEXT: | |-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} // CHECK-NEXT: | | | | `-VarDecl {{.*}} col:12 used i 'int' cinit @@ -195,7 +195,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-value: Int 2 // CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 2 // CHECK-NEXT: `-CapturedStmt {{.*}} -// CHECK-NEXT: |-CapturedDecl {{.*}} <> +// CHECK-NEXT: |-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-ForStmt {{.*}} // CHECK-NEXT: | | |-DeclStmt {{.*}} // CHECK-NEXT: | | | `-VarDecl {{.*}} col:12 used i 'int' cinit diff --git a/clang/test/AST/ast-dump-openmp-simd.c b/clang/test/AST/ast-dump-openmp-simd.c index 3ccddd426d741..cffbb9065f1d6 100644 --- a/clang/test/AST/ast-dump-openmp-simd.c +++ b/clang/test/AST/ast-dump-openmp-simd.c @@ -41,7 +41,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | `-CompoundStmt {{.*}} // CHECK-NEXT: | `-OMPSimdDirective {{.*}} // CHECK-NEXT: | `-CapturedStmt {{.*}} -// CHECK-NEXT: | |-CapturedDecl {{.*}} <> +// CHECK-NEXT: | |-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} // CHECK-NEXT: | | | | `-VarDecl {{.*}} col:12 used i 'int' cinit @@ -65,7 +65,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | `-CompoundStmt {{.*}} // CHECK-NEXT: | `-OMPSimdDirective {{.*}} // CHECK-NEXT: | `-CapturedStmt {{.*}} -// CHECK-NEXT: | |-CapturedDecl {{.*}} <> +// CHECK-NEXT: | |-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} // CHECK-NEXT: | | | | `-VarDecl {{.*}} col:12 used i 'int' cinit @@ -108,7 +108,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-value: Int 1 // CHECK-NEXT: | | `-IntegerLiteral {{.*}} 'int' 1 // CHECK-NEXT: | `-CapturedStmt {{.*}} -// CHECK-NEXT: | |-CapturedDecl {{.*}} <> +// CHECK-NEXT: | |-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} // CHECK-NEXT: | | | | `-VarDecl {{.*}} col:12 used i 'int' cinit @@ -151,7 +151,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-value: Int 2 // CHECK-NEXT: | | `-IntegerLiteral {{.*}} 'int' 2 // CHECK-NEXT: | `-CapturedStmt {{.*}} -// CHECK-NEXT: | |-CapturedDecl {{.*}} <> +// CHECK-NEXT: | |-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} // CHECK-NEXT: | | | | `-VarDecl {{.*}} col:12 used i 'int' cinit @@ -195,7 +195,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-value: Int 2 // CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 2 // CHECK-NEXT: `-CapturedStmt {{.*}} -// CHECK-NEXT: |-CapturedDecl {{.*}} <> +// CHECK-NEXT: |-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-ForStmt {{.*}} // CHECK-NEXT: | | |-DeclStmt {{.*}} // CHECK-NEXT: | | | `-VarDecl {{.*}} col:12 used i 'int' cinit diff --git a/clang/test/AST/ast-dump-openmp-taskloop-simd.c b/clang/test/AST/ast-dump-openmp-taskloop-simd.c index 25f9cd30ad1c1..de70ecdefd16a 100644 --- a/clang/test/AST/ast-dump-openmp-taskloop-simd.c +++ b/clang/test/AST/ast-dump-openmp-taskloop-simd.c @@ -43,7 +43,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <> // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'x' 'int' refers_to_enclosing_variable_or_capture // CHECK-NEXT: | `-CapturedStmt {{.*}} -// CHECK-NEXT: | `-CapturedDecl {{.*}} <> +// CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-ForStmt {{.*}} // CHECK-NEXT: | | |-DeclStmt {{.*}} // CHECK-NEXT: | | | `-VarDecl {{.*}} col:12 used i 'int' cinit @@ -80,7 +80,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'x' 'int' refers_to_enclosing_variable_or_capture // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'y' 'int' refers_to_enclosing_variable_or_capture // CHECK-NEXT: | `-CapturedStmt {{.*}} -// CHECK-NEXT: | `-CapturedDecl {{.*}} <> +// CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-ForStmt {{.*}} // CHECK-NEXT: | | |-DeclStmt {{.*}} // CHECK-NEXT: | | | `-VarDecl {{.*}} col:12 used i 'int' cinit @@ -135,7 +135,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'x' 'int' refers_to_enclosing_variable_or_capture // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'y' 'int' refers_to_enclosing_variable_or_capture // CHECK-NEXT: | `-CapturedStmt {{.*}} -// CHECK-NEXT: | `-CapturedDecl {{.*}} <> +// CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-ForStmt {{.*}} // CHECK-NEXT: | | |-DeclStmt {{.*}} // CHECK-NEXT: | | | `-VarDecl {{.*}} col:12 used i 'int' cinit @@ -190,7 +190,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'x' 'int' refers_to_enclosing_variable_or_capture // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'y' 'int' refers_to_enclosing_variable_or_capture // CHECK-NEXT: | `-CapturedStmt {{.*}} -// CHECK-NEXT: | `-CapturedDecl {{.*}} <> +// CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-ForStmt {{.*}} // CHECK-NEXT: | | |-DeclStmt {{.*}} // CHECK-NEXT: | | | `-VarDecl {{.*}} col:12 used i 'int' cinit @@ -247,7 +247,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'y' 'int' refers_to_enclosing_variable_or_capture // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'z' 'int' refers_to_enclosing_variable_or_capture // CHECK-NEXT: `-CapturedStmt {{.*}} -// CHECK-NEXT: `-CapturedDecl {{.*}} <> +// CHECK-NEXT: `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: |-ForStmt {{.*}} // CHECK-NEXT: | |-DeclStmt {{.*}} // CHECK-NEXT: | | `-VarDecl {{.*}} col:12 used i 'int' cinit diff --git a/clang/test/AST/ast-dump-ptrauth-json.cpp b/clang/test/AST/ast-dump-ptrauth-json.cpp new file mode 100644 index 0000000000000..125cda0cff53a --- /dev/null +++ b/clang/test/AST/ast-dump-ptrauth-json.cpp @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -std=c++11 -ast-dump=json %s | FileCheck %s + +// CHECK: "name": "__builtin_ptrauth_type_discriminator", + +int d = __builtin_ptrauth_type_discriminator(int()); diff --git a/clang/test/AST/attr-print-emit.cpp b/clang/test/AST/attr-print-emit.cpp index 8c8a2b2080599..d8e62ed5f6cd1 100644 --- a/clang/test/AST/attr-print-emit.cpp +++ b/clang/test/AST/attr-print-emit.cpp @@ -32,8 +32,8 @@ int *aa(int i) __attribute__((alloc_align(1))); void ownt(int *, int *) __attribute__((ownership_takes(foo, 1, 2))); // CHECK: void ownh(int *, int *) __attribute__((ownership_holds(foo, 1, 2))); void ownh(int *, int *) __attribute__((ownership_holds(foo, 1, 2))); -// CHECK: void ownr(int) __attribute__((ownership_returns(foo, 1))); -void ownr(int) __attribute__((ownership_returns(foo, 1))); +// CHECK: void *ownr(int) __attribute__((ownership_returns(foo, 1))); +void *ownr(int) __attribute__((ownership_returns(foo, 1))); // CHECK: void awtt(int, int, ...) __attribute__((argument_with_type_tag(foo, 3, 2))); void awtt(int, int, ...) __attribute__((argument_with_type_tag(foo, 3, 2))); @@ -65,8 +65,8 @@ class C { void ownt(int *, int *) __attribute__((ownership_takes(foo, 2, 3))); // CHECK: void ownh(int *, int *) __attribute__((ownership_holds(foo, 2, 3))); void ownh(int *, int *) __attribute__((ownership_holds(foo, 2, 3))); - // CHECK: void ownr(int) __attribute__((ownership_returns(foo, 2))); - void ownr(int) __attribute__((ownership_returns(foo, 2))); + // CHECK: void *ownr(int) __attribute__((ownership_returns(foo, 2))); + void *ownr(int) __attribute__((ownership_returns(foo, 2))); // CHECK: void awtt(int, int, ...) __attribute__((argument_with_type_tag(foo, 4, 3))); void awtt(int, int, ...) __attribute__((argument_with_type_tag(foo, 4, 3))); diff --git a/clang/test/AST/explicit-base-class-move-cntr.cpp b/clang/test/AST/explicit-base-class-move-cntr.cpp new file mode 100644 index 0000000000000..808af2fc94336 --- /dev/null +++ b/clang/test/AST/explicit-base-class-move-cntr.cpp @@ -0,0 +1,171 @@ +// RUN: %clang_cc1 -ast-dump=json %s | FileCheck -strict-whitespace %s + +struct ExplicitBase { + explicit ExplicitBase(const char *) { } + ExplicitBase(const ExplicitBase &) {} + ExplicitBase(ExplicitBase &&) {} + ExplicitBase &operator=(const ExplicitBase &) { return *this; } + ExplicitBase &operator=(ExplicitBase &&) { return *this; } + ~ExplicitBase() { } +}; + +struct Derived1 : ExplicitBase {}; + +Derived1 makeDerived1() { +// CHECK: "kind": "FunctionDecl", +// CHECK: "name": "makeDerived1", + +// CHECK: "kind": "CompoundStmt", + +// CHECK: "kind": "ReturnStmt", +// CHECK: "kind": "ExprWithCleanups", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "Derived1" +// CHECK-NEXT: }, + +// CHECK: "kind": "CXXFunctionalCastExpr", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "Derived1" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "prvalue", +// CHECK-NEXT: "castKind": "NoOp", + +// CHECK: "kind": "CXXBindTemporaryExpr", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "Derived1" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "prvalue", + +// CHECK: "kind": "InitListExpr", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "Derived1" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "prvalue", + +// CHECK: "kind": "CXXConstructExpr", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "ExplicitBase" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "prvalue", +// CHECK-NEXT: "ctorType": { +// CHECK-NEXT: "qualType": "void (ExplicitBase &&)" +// CHECK-NEXT: }, +// CHECK-NEXT: "hadMultipleCandidates": true, +// CHECK-NEXT: "constructionKind": "non-virtual base", + +// CHECK: "kind": "MaterializeTemporaryExpr", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "ExplicitBase" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "xvalue", +// CHECK-NEXT: "storageDuration": "full expression", + +// CHECK: "kind": "CXXBindTemporaryExpr", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "ExplicitBase" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "prvalue", + +// CHECK: "kind": "CXXTemporaryObjectExpr", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "ExplicitBase" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "prvalue", +// CHECK-NEXT: "ctorType": { +// CHECK-NEXT: "qualType": "void (const char *)" +// CHECK-NEXT: }, +// CHECK-NEXT: "list": true, +// CHECK-NEXT: "hadMultipleCandidates": true, +// CHECK-NEXT: "constructionKind": "complete", + +// CHECK: "kind": "ImplicitCastExpr", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "const char *" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "prvalue", +// CHECK-NEXT: "castKind": "ArrayToPointerDecay", + +// CHECK: "kind": "StringLiteral", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "const char[10]" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "lvalue", +// CHECK-NEXT: "value": "\"Move Ctor\"" + return Derived1{ExplicitBase{"Move Ctor"}}; +} + +struct ImplicitBase { + ImplicitBase(const char *) { } + ImplicitBase(const ImplicitBase &) {} + ImplicitBase(ImplicitBase &&) {} + ImplicitBase &operator=(const ImplicitBase &) { return *this; } + ImplicitBase &operator=(ImplicitBase &&) { return *this; } + ~ImplicitBase() { } +}; + +struct Derived2 : ImplicitBase {}; + +Derived2 makeDerived2() { +// CHECK: "kind": "FunctionDecl", +// CHECK: "name": "makeDerived2", + +// CHECK: "kind": "CompoundStmt", + +// CHECK: "kind": "ReturnStmt", + +// CHECK: "kind": "ExprWithCleanups", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "Derived2" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "prvalue", +// CHECK-NEXT: "cleanupsHaveSideEffects": true, + +// CHECK: "kind": "CXXFunctionalCastExpr", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "Derived2" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "prvalue", +// CHECK-NEXT: "castKind": "NoOp", + +// CHECK: "kind": "CXXBindTemporaryExpr", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "Derived2" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "prvalue", + +// CHECK: "kind": "InitListExpr", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "Derived2" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "prvalue", + +// CHECK: "kind": "CXXConstructExpr", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "ImplicitBase" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "prvalue", +// CHECK-NEXT: "ctorType": { +// CHECK-NEXT: "qualType": "void (const char *)" +// CHECK-NEXT: }, +// CHECK-NEXT: "list": true, +// CHECK-NEXT: "hadMultipleCandidates": true, +// CHECK-NEXT: "constructionKind": "non-virtual base", + +// CHECK: "kind": "ImplicitCastExpr", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "const char *" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "prvalue", +// CHECK-NEXT: "castKind": "ArrayToPointerDecay", + +// CHECK: "kind": "StringLiteral", +// CHECK: "type": { +// CHECK-NEXT: "qualType": "const char[8]" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "lvalue", +// CHECK-NEXT: "value": "\"No Ctor\"" + return Derived2{{"No Ctor"}}; +} + +// NOTE: CHECK lines have been autogenerated by gen_ast_dump_json_test.py +// using --filters=FunctionDecl,CompoundStmt,ReturnStmt,MaterializeTemporaryExpr,CXXBindTemporaryExpr,CXXTemporaryObjectExpr,ImplicitCastExpr,StringLiteralStringLiteral diff --git a/clang/test/Analysis/Inputs/expected-plists/plist-macros.cpp.plist b/clang/test/Analysis/Inputs/expected-plists/plist-macros.cpp.plist index 9981fc6a1f517..13645d47f8cdc 100644 --- a/clang/test/Analysis/Inputs/expected-plists/plist-macros.cpp.plist +++ b/clang/test/Analysis/Inputs/expected-plists/plist-macros.cpp.plist @@ -130,12 +130,12 @@ depth0 extended_message - Memory allocated by malloc() should be deallocated by free(), not 'delete' + Memory allocated by 'malloc()' should be deallocated by 'free()', not 'delete' message - Memory allocated by malloc() should be deallocated by free(), not 'delete' + Memory allocated by 'malloc()' should be deallocated by 'free()', not 'delete' - descriptionMemory allocated by malloc() should be deallocated by free(), not 'delete' + descriptionMemory allocated by 'malloc()' should be deallocated by 'free()', not 'delete' categoryMemory error typeBad deallocator check_nameunix.MismatchedDeallocator diff --git a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h index 29326ec1f9280..a379a47515668 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h +++ b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h @@ -263,11 +263,13 @@ namespace std { template< class T > struct remove_reference {typedef T type;}; template< class T > struct remove_reference {typedef T type;}; - template - typename remove_reference::type&& move(T&& a) { - typedef typename remove_reference::type&& RvalRef; - return static_cast(a); - } + template typename remove_reference::type&& move(T&& a); + template T *__addressof(T &x); + template T *addressof(T &x); + template const T& as_const(T& x); + template T&& forward(T&& x); + // FIXME: Declare forward_like + // FIXME: Declare move_if_noexcept template< class T > using remove_reference_t = typename remove_reference::type; @@ -754,7 +756,7 @@ namespace std { template OutputIter __copy(InputIter II, InputIter IE, OutputIter OI) { while (II != IE) - *OI++ = *II++; + *OI++ = *II++; // #system_header_simulator_cxx_std_copy_impl_loop return OI; } diff --git a/clang/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp b/clang/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp index b5e47b3355da3..6c20b4ba53dae 100644 --- a/clang/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp +++ b/clang/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp @@ -24,12 +24,12 @@ void testMallocUseAfterFree() { void testMallocBadFree() { int i; - free(&i); // expected-warning{{Argument to free() is the address of the local variable 'i', which is not memory allocated by malloc()}} + free(&i); // expected-warning{{Argument to 'free()' is the address of the local variable 'i', which is not memory allocated by 'malloc()'}} } void testMallocOffsetFree() { int *p = (int *)malloc(sizeof(int)); - free(++p); // expected-warning{{Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()}} + free(++p); // expected-warning{{Argument to 'free()' is offset by 4 bytes from the start of memory allocated by 'malloc()'}} } //----------------------------------------------------------------- @@ -37,7 +37,7 @@ void testMallocOffsetFree() { //----------------------------------------------------------------- void testMismatchedDeallocator() { int *x = (int *)malloc(sizeof(int)); - delete x; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}} + delete x; // expected-warning{{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'delete'}} } //---------------------------------------------------------------- @@ -69,7 +69,7 @@ void testNewBadFree() { void testNewOffsetFree() { int *p = new int; - operator delete(++p); // expected-warning{{Argument to operator delete is offset by 4 bytes from the start of memory allocated by 'new'}} + operator delete(++p); // expected-warning{{Argument to 'operator delete' is offset by 4 bytes from the start of memory allocated by 'new'}} } //---------------------------------------------------------------- @@ -88,7 +88,7 @@ void testMismatchedChangePtrThroughCall() { void testMismatchedChangePointeeThroughCall() { int *p = (int*)malloc(sizeof(int)*4); changePointee(p); - delete p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}} + delete p; // expected-warning{{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'delete'}} } void testShouldReportDoubleFreeNotMismatched() { diff --git a/clang/test/Analysis/MismatchedDeallocator-checker-test.mm b/clang/test/Analysis/MismatchedDeallocator-checker-test.mm index 013d677e515cf..ef8b24ba8de32 100644 --- a/clang/test/Analysis/MismatchedDeallocator-checker-test.mm +++ b/clang/test/Analysis/MismatchedDeallocator-checker-test.mm @@ -14,6 +14,19 @@ void free(void *); void __attribute((ownership_takes(malloc, 1))) my_free(void *); +void __attribute((ownership_returns(malloc1))) *my_malloc1(size_t); +void __attribute((ownership_takes(malloc1, 1))) my_free1(void *); + +void __attribute((ownership_returns(malloc2))) *my_malloc2(size_t); + +// The order of these declarations are important to verify that analisys still works even +// if there are less specific declarations of the same functions +void __attribute((ownership_returns(malloc3))) *my_malloc3(size_t); +void *my_malloc3(size_t); + +void *my_malloc4(size_t); +void __attribute((ownership_returns(malloc4))) *my_malloc4(size_t); + //--------------------------------------------------------------- // Test if an allocation function matches deallocation function //--------------------------------------------------------------- @@ -21,79 +34,114 @@ //--------------- test malloc family void testMalloc1() { int *p = (int *)malloc(sizeof(int)); - delete p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}} + delete p; // expected-warning{{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'delete'}} } void testMalloc2() { int *p = (int *)malloc(8); int *q = (int *)realloc(p, 16); - delete q; // expected-warning{{Memory allocated by realloc() should be deallocated by free(), not 'delete'}} + delete q; // expected-warning{{Memory allocated by 'realloc()' should be deallocated by 'free()', not 'delete'}} } void testMalloc3() { int *p = (int *)calloc(1, sizeof(int)); - delete p; // expected-warning{{Memory allocated by calloc() should be deallocated by free(), not 'delete'}} + delete p; // expected-warning{{Memory allocated by 'calloc()' should be deallocated by 'free()', not 'delete'}} } void testMalloc4(const char *s) { char *p = strdup(s); - delete p; // expected-warning{{Memory allocated by strdup() should be deallocated by free(), not 'delete'}} + delete p; // expected-warning{{Memory allocated by 'strdup()' should be deallocated by 'free()', not 'delete'}} } void testMalloc5() { int *p = (int *)my_malloc(sizeof(int)); - delete p; // expected-warning{{Memory allocated by my_malloc() should be deallocated by free(), not 'delete'}} + delete p; // expected-warning{{Memory allocated by 'my_malloc()' should be deallocated by 'free()', not 'delete'}} } void testMalloc6() { int *p = (int *)malloc(sizeof(int)); - operator delete(p); // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not operator delete}} + operator delete(p); // expected-warning{{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'operator delete'}} } void testMalloc7() { int *p = (int *)malloc(sizeof(int)); - delete[] p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete[]'}} + delete[] p; // expected-warning{{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'delete[]'}} } void testMalloc8() { int *p = (int *)malloc(sizeof(int)); - operator delete[](p); // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not operator delete[]}} + operator delete[](p); // expected-warning{{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'operator delete[]'}} +} + +void testMalloc9() { + int *p = (int *)my_malloc(sizeof(int)); + my_free(p); // no warning +} + +void testMalloc10() { + int *p = (int *)my_malloc1(sizeof(int)); + my_free1(p); // no warning +} + +void testMalloc11() { + int *p = (int *)my_malloc1(sizeof(int)); + my_free(p); // expected-warning{{Memory allocated by 'my_malloc1()' should be deallocated by function that takes ownership of 'malloc1', not 'my_free()', which takes ownership of 'malloc'}} +} + +void testMalloc12() { + int *p = (int *)my_malloc2(sizeof(int)); + my_free1(p); // expected-warning{{Memory allocated by 'my_malloc2()' should be deallocated by function that takes ownership of 'malloc2', not 'my_free1()', which takes ownership of 'malloc1'}} +} + +void testMalloc13() { + int *p = (int *)my_malloc1(sizeof(int)); + free(p); // expected-warning{{Memory allocated by 'my_malloc1()' should be deallocated by function that takes ownership of 'malloc1', not 'free()'}} +} + +void testMalloc14() { + int *p = (int *)my_malloc3(sizeof(int)); + free(p); // expected-warning{{Memory allocated by 'my_malloc3()' should be deallocated by function that takes ownership of 'malloc3', not 'free()'}} +} + +void testMalloc15() { + int *p = (int *)my_malloc4(sizeof(int)); + free(p); // expected-warning{{Memory allocated by 'my_malloc4()' should be deallocated by function that takes ownership of 'malloc4', not 'free()'}} } void testAlloca() { int *p = (int *)__builtin_alloca(sizeof(int)); - delete p; // expected-warning{{Memory allocated by alloca() should not be deallocated}} + delete p; // expected-warning{{Memory allocated by 'alloca()' should not be deallocated}} } //--------------- test new family void testNew1() { int *p = new int; - free(p); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not free()}} + free(p); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'free()'}} } void testNew2() { int *p = (int *)operator new(0); - free(p); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not free()}} + free(p); // expected-warning{{Memory allocated by 'operator new' should be deallocated by 'delete', not 'free()'}} } void testNew3() { int *p = new int[1]; - free(p); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not free()}} + free(p); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'free()'}} } void testNew4() { int *p = new int; - realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not realloc()}} + realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'realloc()'}} } void testNew5() { int *p = (int *)operator new(0); - realloc(p, sizeof(long)); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not realloc()}} + realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'operator new' should be deallocated by 'delete', not 'realloc()'}} } void testNew6() { int *p = new int[1]; - realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not realloc()}} + realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'realloc()'}} } int *allocInt() { @@ -106,7 +154,7 @@ void testNew7() { void testNew8() { int *p = (int *)operator new(0); - delete[] p; // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not 'delete[]'}} + delete[] p; // expected-warning{{Memory allocated by 'operator new' should be deallocated by 'delete', not 'delete[]'}} } int *allocIntArray(unsigned c) { @@ -120,7 +168,7 @@ void testNew9() { void testNew10() { int *p = (int *)operator new[](0); - delete p; // expected-warning{{Memory allocated by operator new[] should be deallocated by 'delete[]', not 'delete'}} + delete p; // expected-warning{{Memory allocated by 'operator new[]' should be deallocated by 'delete[]', not 'delete'}} } void testNew11(NSUInteger dataLength) { @@ -208,7 +256,7 @@ explicit SimpleSmartPointer(T *p = 0) : ptr(p) {} ~SimpleSmartPointer() { delete ptr; // expected-warning@-1 {{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}} - // expected-warning@-2 {{Memory allocated by malloc() should be deallocated by free(), not 'delete'}} + // expected-warning@-2 {{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'delete'}} } }; diff --git a/clang/test/Analysis/NewDelete-intersections.mm b/clang/test/Analysis/NewDelete-intersections.mm index 6f81034ee349f..9ac471600e8b9 100644 --- a/clang/test/Analysis/NewDelete-intersections.mm +++ b/clang/test/Analysis/NewDelete-intersections.mm @@ -44,7 +44,7 @@ void testMallocFreeNoWarn() { void testDeleteMalloced() { int *p1 = (int *)malloc(sizeof(int)); delete p1; - // mismatch-warning@-1{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}} + // mismatch-warning@-1{{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'delete'}} int *p2 = (int *)__builtin_alloca(sizeof(int)); delete p2; // no warn @@ -59,13 +59,13 @@ void testUseZeroAllocatedMalloced() { void testFreeOpNew() { void *p = operator new(0); free(p); - // mismatch-warning@-1{{Memory allocated by operator new should be deallocated by 'delete', not free()}} + // mismatch-warning@-1{{Memory allocated by 'operator new' should be deallocated by 'delete', not 'free()'}} } void testFreeNewExpr() { int *p = new int; free(p); - // mismatch-warning@-1{{Memory allocated by 'new' should be deallocated by 'delete', not free()}} + // mismatch-warning@-1{{Memory allocated by 'new' should be deallocated by 'delete', not 'free()'}} free(p); } diff --git a/clang/test/Analysis/analyzer-config.c b/clang/test/Analysis/analyzer-config.c index 2a4c40005a4dc..b8dbcdd7e55af 100644 --- a/clang/test/Analysis/analyzer-config.c +++ b/clang/test/Analysis/analyzer-config.c @@ -9,8 +9,6 @@ // CHECK-NEXT: alpha.clone.CloneChecker:ReportNormalClones = true // CHECK-NEXT: alpha.cplusplus.STLAlgorithmModeling:AggressiveStdFindModeling = false // CHECK-NEXT: alpha.osx.cocoa.DirectIvarAssignment:AnnotatedFunctions = false -// CHECK-NEXT: alpha.security.MmapWriteExec:MmapProtExec = 0x04 -// CHECK-NEXT: alpha.security.MmapWriteExec:MmapProtRead = 0x01 // CHECK-NEXT: alpha.security.taint.TaintPropagation:Config = "" // CHECK-NEXT: apply-fixits = false // CHECK-NEXT: assume-controlled-environment = false diff --git a/clang/test/Analysis/builtin-functions.cpp b/clang/test/Analysis/builtin-functions.cpp index 8719193e405c4..f7bafabd23cbc 100644 --- a/clang/test/Analysis/builtin-functions.cpp +++ b/clang/test/Analysis/builtin-functions.cpp @@ -1,6 +1,16 @@ // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,debug.ExprInspection %s -std=c++11 -verify // RUN: %clang_analyze_cc1 -triple x86_64-pc-windows-msvc19.11.0 -fms-extensions -analyzer-checker=core,debug.ExprInspection %s -std=c++11 -verify +#include "Inputs/system-header-simulator-cxx.h" + +namespace std { +// Intentionally not using an "auto" return type here, as such must also have a definition. +template constexpr int&& forward_like(U&& x) noexcept; +template const T& move_if_noexcept(T& x) noexcept; +} // namespace std + +template void clang_analyzer_dump_ref(T&&); +template void clang_analyzer_dump_ptr(T*); void clang_analyzer_eval(bool); void clang_analyzer_warnIfReached(); @@ -8,6 +18,16 @@ void testAddressof(int x) { clang_analyzer_eval(&x == __builtin_addressof(x)); // expected-warning{{TRUE}} } +void testStdBuiltinLikeFunctions(int x) { + clang_analyzer_dump_ptr(std::addressof(x)); // expected-warning{{&x}} + clang_analyzer_dump_ptr(std::__addressof(x)); // expected-warning{{&x}} + clang_analyzer_dump_ref(std::as_const(x)); // expected-warning{{&x}} + clang_analyzer_dump_ref(std::forward(x)); // expected-warning{{&x}} + clang_analyzer_dump_ref(std::forward_like(x)); // expected-warning{{&x}} + clang_analyzer_dump_ref(std::move(x)); // expected-warning{{&x}} + clang_analyzer_dump_ref(std::move_if_noexcept(x)); // expected-warning{{&x}} +} + void testSize() { struct { int x; diff --git a/clang/test/Analysis/call-invalidation.cpp b/clang/test/Analysis/call-invalidation.cpp index 727217f228b05..fb2b892b31a1f 100644 --- a/clang/test/Analysis/call-invalidation.cpp +++ b/clang/test/Analysis/call-invalidation.cpp @@ -1,5 +1,6 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s +template void clang_analyzer_dump(T); void clang_analyzer_eval(bool); void usePointer(int * const *); @@ -165,3 +166,117 @@ void testMixedConstNonConstCalls() { useFirstNonConstSecondConst(&(s2.x), &(s2.y)); clang_analyzer_eval(s2.y == 1); // expected-warning{{UNKNOWN}} } + +namespace std { +class Opaque { +public: + Opaque(); + int nested_member; +}; +} // namespace std + +struct StdWrappingOpaque { + std::Opaque o; // first member + int uninit; +}; +struct StdWrappingOpaqueSwapped { + int uninit; // first member + std::Opaque o; +}; + +int testStdCtorDoesNotInvalidateParentObject() { + StdWrappingOpaque obj; + int x = obj.o.nested_member; // no-garbage: std::Opaque::ctor might initialized this + int y = obj.uninit; // FIXME: We should have a garbage read here. Read the details. + // As the first member ("obj.o") is invalidated, a conjured default binding is bound + // to the offset 0 within cluster "obj", and this masks every uninitialized fields + // that follows. We need a better store with extents to fix this. + return x + y; +} + +int testStdCtorDoesNotInvalidateParentObjectSwapped() { + StdWrappingOpaqueSwapped obj; + int x = obj.o.nested_member; // no-garbage: std::Opaque::ctor might initialized this + int y = obj.uninit; // expected-warning {{Assigned value is garbage or undefined}} + return x + y; +} + +class UserProvidedOpaque { +public: + UserProvidedOpaque(); // might reinterpret_cast(this) + int nested_member; +}; + +struct WrappingUserProvidedOpaque { + UserProvidedOpaque o; // first member + int uninit; +}; +struct WrappingUserProvidedOpaqueSwapped { + int uninit; // first member + UserProvidedOpaque o; +}; + +int testUserProvidedCtorInvalidatesParentObject() { + WrappingUserProvidedOpaque obj; + int x = obj.o.nested_member; // no-garbage: UserProvidedOpaque::ctor might initialized this + int y = obj.uninit; // no-garbage: UserProvidedOpaque::ctor might reinterpret_cast(this) and write to the "uninit" member. + return x + y; +} + +int testUserProvidedCtorInvalidatesParentObjectSwapped() { + WrappingUserProvidedOpaqueSwapped obj; + int x = obj.o.nested_member; // no-garbage: same as above + int y = obj.uninit; // no-garbage: same as above + return x + y; +} + +struct WrappingStdWrappingOpaqueOuterInits { + int first = 1; + std::Opaque second; + int third = 3; + WrappingStdWrappingOpaqueOuterInits() { + clang_analyzer_dump(first); // expected-warning {{1 S32b}} + clang_analyzer_dump(second.nested_member); // expected-warning {{derived_}} + clang_analyzer_dump(third); // expected-warning {{3 S32b}} + } +}; + +struct WrappingUserProvidedOpaqueOuterInits { + int first = 1; // Potentially overwritten by UserProvidedOpaque::ctor + UserProvidedOpaque second; // Invalidates the object so far. + int third = 3; // Happens after UserProvidedOpaque::ctor, thus preserved! + WrappingUserProvidedOpaqueOuterInits() { + clang_analyzer_dump(first); // expected-warning {{derived_}} + clang_analyzer_dump(second.nested_member); // expected-warning {{derived_}} + clang_analyzer_dump(third); // expected-warning {{3 S32b}} + } +}; + +extern "C++" { +namespace std { +inline namespace v1 { +namespace custom_ranges { +struct Fancy { +struct iterator { +struct Opaque { + Opaque(); + int nested_member; +}; // struct Opaque +}; // struct iterator +}; // struct Fancy +} // namespace custom_ranges +} // namespace v1 +} // namespace std +} // extern "C++" + +struct StdWrappingFancyOpaque { + int uninit; + std::custom_ranges::Fancy::iterator::Opaque o; +}; + +int testNestedStdNamespacesAndRecords() { + StdWrappingFancyOpaque obj; + int x = obj.o.nested_member; // no-garbage: ctor + int y = obj.uninit; // expected-warning {{Assigned value is garbage or undefined}} + return x + y; +} diff --git a/clang/test/Analysis/ctor-array.cpp b/clang/test/Analysis/ctor-array.cpp index 053669cc2aada..49412ee5a68c7 100644 --- a/clang/test/Analysis/ctor-array.cpp +++ b/clang/test/Analysis/ctor-array.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-disable-checker=cplusplus -analyzer-config c++-inlining=constructors -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=constructors -verify %s #include "Inputs/system-header-simulator-cxx.h" @@ -119,16 +119,6 @@ struct s5 { }; void g1(void) { - // FIXME: This test requires -analyzer-disable-checker=cplusplus, - // because of the checker's weird behaviour in case of arrays. - // E.g.: - // s3 *arr = new s3[4]; - // s3 *arr2 = new (arr + 1) s3[1]; - // ^~~~~~~~~~~~~~~~~~~ - // warning: 12 bytes is possibly not enough - // for array allocation which requires - // 4 bytes. - s5::c = 0; s5 *arr = new s5[4]; new (arr + 1) s5[3]; diff --git a/clang/test/Analysis/ctor.mm b/clang/test/Analysis/ctor.mm index fb385833df9c7..6ac9050fc29f7 100644 --- a/clang/test/Analysis/ctor.mm +++ b/clang/test/Analysis/ctor.mm @@ -56,8 +56,6 @@ void testNonPODCopyConstructor() { namespace ConstructorVirtualCalls { class A { public: - int *out1, *out2, *out3; - virtual int get() { return 1; } A(int *out1) { diff --git a/clang/test/Analysis/diagnostics/explicit-suppression.cpp b/clang/test/Analysis/diagnostics/explicit-suppression.cpp index 24586e37fe207..3a904dac1c0fe 100644 --- a/clang/test/Analysis/diagnostics/explicit-suppression.cpp +++ b/clang/test/Analysis/diagnostics/explicit-suppression.cpp @@ -19,6 +19,6 @@ class C { void testCopyNull(C *I, C *E) { std::copy(I, E, (C *)0); #ifndef SUPPRESSED - // expected-warning@../Inputs/system-header-simulator-cxx.h:757 {{Called C++ object pointer is null}} + // expected-warning@#system_header_simulator_cxx_std_copy_impl_loop {{Called C++ object pointer is null}} #endif } diff --git a/clang/test/Analysis/free.c b/clang/test/Analysis/free.c index 50c1efdfb1309..5fd956a4ce110 100644 --- a/clang/test/Analysis/free.c +++ b/clang/test/Analysis/free.c @@ -13,21 +13,21 @@ void *alloca(size_t); void t1 (void) { int a[] = { 1 }; free(a); - // expected-warning@-1{{Argument to free() is the address of the local variable 'a', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the local variable 'a', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object 'a'}} } void t2 (void) { int a = 1; free(&a); - // expected-warning@-1{{Argument to free() is the address of the local variable 'a', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the local variable 'a', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object 'a'}} } void t3 (void) { static int a[] = { 1 }; free(a); - // expected-warning@-1{{Argument to free() is the address of the static variable 'a', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the static variable 'a', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object 'a'}} } @@ -42,7 +42,7 @@ void t5 (void) { void t6 (void) { free((void*)1000); - // expected-warning@-1{{Argument to free() is a constant address (1000), which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is a constant address (1000), which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object '(void *)1000'}} } @@ -58,42 +58,42 @@ void t8 (char **x) { void t9 (void) { label: free(&&label); - // expected-warning@-1{{Argument to free() is the address of the label 'label', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the label 'label', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object 'label'}} } void t10 (void) { free((void*)&t10); - // expected-warning@-1{{Argument to free() is the address of the function 't10', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the function 't10', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object 't10'}} } void t11 (void) { char *p = (char*)alloca(2); - free(p); // expected-warning {{Memory allocated by alloca() should not be deallocated}} + free(p); // expected-warning {{Memory allocated by 'alloca()' should not be deallocated}} } void t12 (void) { char *p = (char*)__builtin_alloca(2); - free(p); // expected-warning {{Memory allocated by alloca() should not be deallocated}} + free(p); // expected-warning {{Memory allocated by 'alloca()' should not be deallocated}} } void t13 (void) { free(^{return;}); - // expected-warning@-1{{Argument to free() is a block, which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is a block, which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object: block expression}} } void t14 (char a) { free(&a); - // expected-warning@-1{{Argument to free() is the address of the parameter 'a', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the parameter 'a', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object 'a'}} } static int someGlobal[2]; void t15 (void) { free(someGlobal); - // expected-warning@-1{{Argument to free() is the address of the global variable 'someGlobal', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the global variable 'someGlobal', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object 'someGlobal'}} } @@ -105,7 +105,7 @@ void t16 (char **x, int offset) { int *iptr(void); void t17(void) { free(iptr); // Oops, forgot to call iptr(). - // expected-warning@-1{{Argument to free() is the address of the function 'iptr', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the function 'iptr', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object 'iptr'}} } diff --git a/clang/test/Analysis/free.cpp b/clang/test/Analysis/free.cpp index a812a22c47d39..b7f2e49855cf1 100644 --- a/clang/test/Analysis/free.cpp +++ b/clang/test/Analysis/free.cpp @@ -17,42 +17,42 @@ extern "C" void *alloca(std::size_t); void t1a () { int a[] = { 1 }; free(a); - // expected-warning@-1{{Argument to free() is the address of the local variable 'a', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the local variable 'a', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object 'a'}} } void t1b () { int a[] = { 1 }; std::free(a); - // expected-warning@-1{{Argument to free() is the address of the local variable 'a', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the local variable 'a', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call std::free on non-heap object 'a'}} } void t2a () { int a = 1; free(&a); - // expected-warning@-1{{Argument to free() is the address of the local variable 'a', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the local variable 'a', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object 'a'}} } void t2b () { int a = 1; std::free(&a); - // expected-warning@-1{{Argument to free() is the address of the local variable 'a', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the local variable 'a', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call std::free on non-heap object 'a'}} } void t3a () { static int a[] = { 1 }; free(a); - // expected-warning@-1{{Argument to free() is the address of the static variable 'a', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the static variable 'a', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object 'a'}} } void t3b () { static int a[] = { 1 }; std::free(a); - // expected-warning@-1{{Argument to free() is the address of the static variable 'a', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the static variable 'a', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call std::free on non-heap object 'a'}} } @@ -76,13 +76,13 @@ void t5b () { void t6a () { free((void*)1000); - // expected-warning@-1{{Argument to free() is a constant address (1000), which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is a constant address (1000), which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object '(void *)1000'}} } void t6b () { std::free((void*)1000); - // expected-warning@-1{{Argument to free() is a constant address (1000), which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is a constant address (1000), which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call std::free on non-heap object '(void *)1000'}} } @@ -107,95 +107,95 @@ void t8b (char **x) { void t9a () { label: free(&&label); - // expected-warning@-1{{Argument to free() is the address of the label 'label', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the label 'label', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object 'label'}} } void t9b () { label: std::free(&&label); - // expected-warning@-1{{Argument to free() is the address of the label 'label', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the label 'label', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call std::free on non-heap object 'label'}} } void t10a () { free((void*)&t10a); - // expected-warning@-1{{Argument to free() is the address of the function 't10a', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the function 't10a', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object 't10a'}} } void t10b () { std::free((void*)&t10b); - // expected-warning@-1{{Argument to free() is the address of the function 't10b', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the function 't10b', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call std::free on non-heap object 't10b'}} } void t11a () { char *p = (char*)alloca(2); - free(p); // expected-warning {{Memory allocated by alloca() should not be deallocated}} + free(p); // expected-warning {{Memory allocated by 'alloca()' should not be deallocated}} } void t11b () { char *p = (char*)alloca(2); - std::free(p); // expected-warning {{Memory allocated by alloca() should not be deallocated}} + std::free(p); // expected-warning {{Memory allocated by 'alloca()' should not be deallocated}} } void t12a () { char *p = (char*)__builtin_alloca(2); - free(p); // expected-warning {{Memory allocated by alloca() should not be deallocated}} + free(p); // expected-warning {{Memory allocated by 'alloca()' should not be deallocated}} } void t12b () { char *p = (char*)__builtin_alloca(2); - std::free(p); // expected-warning {{Memory allocated by alloca() should not be deallocated}} + std::free(p); // expected-warning {{Memory allocated by 'alloca()' should not be deallocated}} } void t13a () { free(^{return;}); - // expected-warning@-1{{Argument to free() is a block, which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is a block, which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object: block expression}} } void t13b () { std::free(^{return;}); - // expected-warning@-1{{Argument to free() is a block, which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is a block, which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call std::free on non-heap object: block expression}} } void t14a () { free((void *)+[]{ return; }); - // expected-warning@-1{{Argument to free() is the address of the function '__invoke', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the function '__invoke', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object: lambda-to-function-pointer conversion}} } void t14b () { std::free((void *)+[]{ return; }); - // expected-warning@-1{{Argument to free() is the address of the function '__invoke', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the function '__invoke', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call std::free on non-heap object: lambda-to-function-pointer conversion}} } void t15a (char a) { free(&a); - // expected-warning@-1{{Argument to free() is the address of the parameter 'a', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the parameter 'a', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object 'a'}} } void t15b (char a) { std::free(&a); - // expected-warning@-1{{Argument to free() is the address of the parameter 'a', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the parameter 'a', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call std::free on non-heap object 'a'}} } static int someGlobal[2]; void t16a () { free(someGlobal); - // expected-warning@-1{{Argument to free() is the address of the global variable 'someGlobal', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the global variable 'someGlobal', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object 'someGlobal'}} } void t16b () { std::free(someGlobal); - // expected-warning@-1{{Argument to free() is the address of the global variable 'someGlobal', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the global variable 'someGlobal', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call std::free on non-heap object 'someGlobal'}} } diff --git a/clang/test/Analysis/getline-alloc.c b/clang/test/Analysis/getline-alloc.c index 5b5c716cb605a..74a40a11b9782 100644 --- a/clang/test/Analysis/getline-alloc.c +++ b/clang/test/Analysis/getline-alloc.c @@ -40,7 +40,7 @@ void test_getline_alloca() { return; size_t n = 10; char *buffer = alloca(n); - getline(&buffer, &n, F1); // expected-warning {{Memory allocated by alloca() should not be deallocated}} + getline(&buffer, &n, F1); // expected-warning {{Memory allocated by 'alloca()' should not be deallocated}} fclose(F1); } @@ -50,7 +50,7 @@ void test_getline_invalid_ptr() { return; size_t n = 10; char *buffer = (char*)test_getline_invalid_ptr; - getline(&buffer, &n, F1); // expected-warning {{Argument to getline() is the address of the function 'test_getline_invalid_ptr', which is not memory allocated by malloc()}} + getline(&buffer, &n, F1); // expected-warning {{Argument to 'getline()' is the address of the function 'test_getline_invalid_ptr', which is not memory allocated by 'malloc()'}} fclose(F1); } @@ -79,7 +79,7 @@ void test_getline_stack() { if (!F1) return; - getline(&ptr, &n, F1); // expected-warning {{Argument to getline() is the address of the local variable 'buffer', which is not memory allocated by malloc()}} + getline(&ptr, &n, F1); // expected-warning {{Argument to 'getline()' is the address of the local variable 'buffer', which is not memory allocated by 'malloc()'}} } void test_getline_static() { @@ -91,5 +91,5 @@ void test_getline_static() { if (!F1) return; - getline(&ptr, &n, F1); // expected-warning {{Argument to getline() is the address of the static variable 'buffer', which is not memory allocated by malloc()}} + getline(&ptr, &n, F1); // expected-warning {{Argument to 'getline()' is the address of the static variable 'buffer', which is not memory allocated by 'malloc()'}} } diff --git a/clang/test/Analysis/issue-94193.cpp b/clang/test/Analysis/issue-94193.cpp new file mode 100644 index 0000000000000..97acfdd8685be --- /dev/null +++ b/clang/test/Analysis/issue-94193.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_analyze_cc1 %s -verify -analyzer-checker=core + +#include "Inputs/system-header-simulator-cxx.h" + + +namespace GH94193 { +template class optional { + union { + char x; + T uvalue; + }; + bool holds_value = false; +public: + optional() = default; + optional(const optional&) = delete; + optional(optional&&) = delete; + template explicit optional(U&& value) : holds_value(true) { + new (static_cast(std::addressof(uvalue))) T(std::forward(value)); + } + optional& operator=(const optional&) = delete; + optional& operator=(optional&&) = delete; + explicit operator bool() const { + return holds_value; + } + T& unwrap() & { + return uvalue; // no-warning: returns a valid value + } +}; + +int top1(int x) { + optional opt{x}; // note: Ctor was inlined. + return opt.unwrap(); // no-warning: returns a valid value +} + +std::string *top2() { + std::string a = "123"; + // expected-warning@+2 {{address of stack memory associated with local variable 'a' returned}} diagnosed by -Wreturn-stack-address + // expected-warning@+1 {{Address of stack memory associated with local variable 'a' returned to caller [core.StackAddressEscape]}} + return std::addressof(a); +} +} // namespace GH94193 diff --git a/clang/test/Analysis/kmalloc-linux.c b/clang/test/Analysis/kmalloc-linux.c index af1af24126b6a..0114c4ef000e2 100644 --- a/clang/test/Analysis/kmalloc-linux.c +++ b/clang/test/Analysis/kmalloc-linux.c @@ -133,5 +133,5 @@ void test_kfree_ZERO_SIZE_PTR(void) { void test_kfree_other_constant_value(void) { void *ptr = (void *)1; - kfree(ptr); // expected-warning{{Argument to kfree() is a constant address (1)}} + kfree(ptr); // expected-warning{{Argument to 'kfree()' is a constant address (1)}} } diff --git a/clang/test/Analysis/live-stmts.cpp b/clang/test/Analysis/live-stmts.cpp index 16954f30129f7..c60f522588e39 100644 --- a/clang/test/Analysis/live-stmts.cpp +++ b/clang/test/Analysis/live-stmts.cpp @@ -193,3 +193,112 @@ void test_lambda_refcapture() { // CHECK-NEXT: [ B2 (live expressions at block exit) ] // CHECK-EMPTY: // CHECK-EMPTY: + +int logicalOpInTernary(bool b) { + return (b || b) ? 0 : 1; +} + +// [B6 (ENTRY)] +// | +// V +// [B5 (b || ...)] +// | \ +// | | +// V V +// [B4 (b||b)] ? [B2 (0)] : [B3 (1)] +// \ / +// ---|---- +// V +// [B1] --> [B0 (EXIT)] +// return + +// CHECK: [ B0 (live expressions at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B1 (live expressions at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B2 (live expressions at block exit) ] +// CHECK-EMPTY: +// CHECK: ImplicitCastExpr {{.*}} '_Bool' +// CHECK: `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK-EMPTY: +// CHECK: ImplicitCastExpr {{.*}} '_Bool' +// CHECK: `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK-EMPTY: +// CHECK: BinaryOperator {{.*}} '_Bool' '||' +// CHECK: |-ImplicitCastExpr {{.*}} '_Bool' +// CHECK: | `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK: `-ImplicitCastExpr {{.*}} '_Bool' +// CHECK: `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK-EMPTY: +// CHECK: IntegerLiteral {{.*}} 'int' 0 +// CHECK-EMPTY: +// CHECK: IntegerLiteral {{.*}} 'int' 1 +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B3 (live expressions at block exit) ] +// CHECK-EMPTY: +// CHECK: ImplicitCastExpr {{.*}} '_Bool' +// CHECK: `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK-EMPTY: +// CHECK: ImplicitCastExpr {{.*}} '_Bool' +// CHECK: `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK-EMPTY: +// CHECK: BinaryOperator {{.*}} '_Bool' '||' +// CHECK: |-ImplicitCastExpr {{.*}} '_Bool' +// CHECK: | `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK: `-ImplicitCastExpr {{.*}} '_Bool' +// CHECK: `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK-EMPTY: +// CHECK: IntegerLiteral {{.*}} 'int' 0 +// CHECK-EMPTY: +// CHECK: IntegerLiteral {{.*}} 'int' 1 +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B4 (live expressions at block exit) ] +// CHECK-EMPTY: +// CHECK: ImplicitCastExpr {{.*}} '_Bool' +// CHECK: `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK-EMPTY: +// CHECK: ImplicitCastExpr {{.*}} '_Bool' +// CHECK: `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK-EMPTY: +// CHECK: BinaryOperator {{.*}} '_Bool' '||' +// CHECK: |-ImplicitCastExpr {{.*}} '_Bool' +// CHECK: | `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK: `-ImplicitCastExpr {{.*}} '_Bool' +// CHECK: `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK-EMPTY: +// CHECK: IntegerLiteral {{.*}} 'int' 0 +// CHECK-EMPTY: +// CHECK: IntegerLiteral {{.*}} 'int' 1 +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B5 (live expressions at block exit) ] +// CHECK-EMPTY: +// CHECK: ImplicitCastExpr {{.*}} '_Bool' +// CHECK: `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK-EMPTY: +// CHECK: ImplicitCastExpr {{.*}} '_Bool' +// CHECK: `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK-EMPTY: +// CHECK: BinaryOperator {{.*}} '_Bool' '||' +// CHECK: |-ImplicitCastExpr {{.*}} '_Bool' +// CHECK: | `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK: `-ImplicitCastExpr {{.*}} '_Bool' +// CHECK: `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK-EMPTY: +// CHECK: IntegerLiteral {{.*}} 'int' 0 +// CHECK-EMPTY: +// CHECK: IntegerLiteral {{.*}} 'int' 1 +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B6 (live expressions at block exit) ] +// CHECK-EMPTY: +// CHECK: ImplicitCastExpr {{.*}} '_Bool' +// CHECK: `-DeclRefExpr {{.*}} '_Bool' lvalue ParmVar {{.*}} 'b' '_Bool' +// CHECK-EMPTY: +// CHECK: IntegerLiteral {{.*}} 'int' 0 +// CHECK-EMPTY: +// CHECK: IntegerLiteral {{.*}} 'int' 1 diff --git a/clang/test/Analysis/malloc-fnptr-plist.c b/clang/test/Analysis/malloc-fnptr-plist.c index e3482980dfbf6..9e82406459234 100644 --- a/clang/test/Analysis/malloc-fnptr-plist.c +++ b/clang/test/Analysis/malloc-fnptr-plist.c @@ -5,7 +5,7 @@ void free(void *); void (*fnptr)(int); void foo(void) { free((void *)fnptr); - // expected-warning@-1{{Argument to free() is a function pointer}} + // expected-warning@-1{{Argument to 'free()' is a function pointer}} // expected-warning@-2{{attempt to call free on non-heap object '(void *)fnptr'}} } diff --git a/clang/test/Analysis/malloc-std-namespace.cpp b/clang/test/Analysis/malloc-std-namespace.cpp index d4e397bb812aa..21566ad617920 100644 --- a/clang/test/Analysis/malloc-std-namespace.cpp +++ b/clang/test/Analysis/malloc-std-namespace.cpp @@ -18,7 +18,7 @@ void no_leak() { void invalid_free() { int i; int *p = &i; - //expected-note@+2{{Argument to free() is the address of the local variable 'i', which is not memory allocated by malloc()}} - //expected-warning@+1{{Argument to free() is the address of the local variable 'i', which is not memory allocated by malloc()}} + //expected-note@+2{{Argument to 'free()' is the address of the local variable 'i', which is not memory allocated by 'malloc()'}} + //expected-warning@+1{{Argument to 'free()' is the address of the local variable 'i', which is not memory allocated by 'malloc()'}} std::free(p); } diff --git a/clang/test/Analysis/malloc.c b/clang/test/Analysis/malloc.c index 8ee29aeb324f7..9c7ca43bfbc5a 100644 --- a/clang/test/Analysis/malloc.c +++ b/clang/test/Analysis/malloc.c @@ -732,7 +732,7 @@ void mallocCastToFP(void) { free(p); } -// This tests that malloc() buffers are undefined by default +// This tests that 'malloc()' buffers are undefined by default char mallocGarbage (void) { char *buf = malloc(2); char result = buf[1]; // expected-warning{{undefined}} @@ -778,17 +778,17 @@ void paramFree(int *p) { void allocaFree(void) { int *p = alloca(sizeof(int)); - free(p); // expected-warning {{Memory allocated by alloca() should not be deallocated}} + free(p); // expected-warning {{Memory allocated by 'alloca()' should not be deallocated}} } void allocaFreeBuiltin(void) { int *p = __builtin_alloca(sizeof(int)); - free(p); // expected-warning {{Memory allocated by alloca() should not be deallocated}} + free(p); // expected-warning {{Memory allocated by 'alloca()' should not be deallocated}} } void allocaFreeBuiltinAlign(void) { int *p = __builtin_alloca_with_align(sizeof(int), 64); - free(p); // expected-warning {{Memory allocated by alloca() should not be deallocated}} + free(p); // expected-warning {{Memory allocated by 'alloca()' should not be deallocated}} } @@ -1327,7 +1327,7 @@ void radar10978247_positive(int myValueSize) { else return; // expected-warning {{leak}} } -// Previously this triggered a false positive because malloc() is known to +// Previously this triggered a false positive because 'malloc()' is known to // return uninitialized memory and the binding of 'o' to 'p->n' was not getting // propertly handled. Now we report a leak. struct rdar11269741_a_t { @@ -1656,26 +1656,26 @@ void testOffsetDeallocate(int *memoryBlock) { void testOffsetOfRegionFreed(void) { __int64_t * array = malloc(sizeof(__int64_t)*2); array += 1; - free(&array[0]); // expected-warning{{Argument to free() is offset by 8 bytes from the start of memory allocated by malloc()}} + free(&array[0]); // expected-warning{{Argument to 'free()' is offset by 8 bytes from the start of memory allocated by 'malloc()'}} } void testOffsetOfRegionFreed2(void) { __int64_t *p = malloc(sizeof(__int64_t)*2); p += 1; - free(p); // expected-warning{{Argument to free() is offset by 8 bytes from the start of memory allocated by malloc()}} + free(p); // expected-warning{{Argument to 'free()' is offset by 8 bytes from the start of memory allocated by 'malloc()'}} } void testOffsetOfRegionFreed3(void) { char *r = malloc(sizeof(char)); r = r - 10; - free(r); // expected-warning {{Argument to free() is offset by -10 bytes from the start of memory allocated by malloc()}} + free(r); // expected-warning {{Argument to 'free()' is offset by -10 bytes from the start of memory allocated by 'malloc()'}} } void testOffsetOfRegionFreedAfterFunctionCall(void) { int *p = malloc(sizeof(int)*2); p += 1; myfoo(p); - free(p); // expected-warning{{Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()}} + free(p); // expected-warning{{Argument to 'free()' is offset by 4 bytes from the start of memory allocated by 'malloc()'}} } void testFixManipulatedPointerBeforeFree(void) { @@ -1695,7 +1695,7 @@ void freeOffsetPointerPassedToFunction(void) { p[1] = 0; p += 1; myfooint(*p); // not passing the pointer, only a value pointed by pointer - free(p); // expected-warning {{Argument to free() is offset by 8 bytes from the start of memory allocated by malloc()}} + free(p); // expected-warning {{Argument to 'free()' is offset by 8 bytes from the start of memory allocated by 'malloc()'}} } int arbitraryInt(void); @@ -1709,13 +1709,13 @@ void testFreeNonMallocPointerWithNoOffset(void) { char c; char *r = &c; r = r + 10; - free(r-10); // expected-warning {{Argument to free() is the address of the local variable 'c', which is not memory allocated by malloc()}} + free(r-10); // expected-warning {{Argument to 'free()' is the address of the local variable 'c', which is not memory allocated by 'malloc()'}} } void testFreeNonMallocPointerWithOffset(void) { char c; char *r = &c; - free(r+1); // expected-warning {{Argument to free() is the address of the local variable 'c', which is not memory allocated by malloc()}} + free(r+1); // expected-warning {{Argument to 'free()' is the address of the local variable 'c', which is not memory allocated by 'malloc()'}} } void testOffsetZeroDoubleFree(void) { @@ -1735,14 +1735,14 @@ void testOffsetPassedToStrlenThenFree(void) { char * string = malloc(sizeof(char)*10); string += 1; int length = strlen(string); - free(string); // expected-warning {{Argument to free() is offset by 1 byte from the start of memory allocated by malloc()}} + free(string); // expected-warning {{Argument to 'free()' is offset by 1 byte from the start of memory allocated by 'malloc()'}} } void testOffsetPassedAsConst(void) { char * string = malloc(sizeof(char)*10); string += 1; passConstPtr(string); - free(string); // expected-warning {{Argument to free() is offset by 1 byte from the start of memory allocated by malloc()}} + free(string); // expected-warning {{Argument to 'free()' is offset by 1 byte from the start of memory allocated by 'malloc()'}} } char **_vectorSegments; @@ -1842,12 +1842,12 @@ int testNoCheckerDataPropogationFromLogicalOpOperandToOpResult(void) { void (*fnptr)(int); void freeIndirectFunctionPtr(void) { void *p = (void *)fnptr; - free(p); // expected-warning {{Argument to free() is a function pointer}} + free(p); // expected-warning {{Argument to 'free()' is a function pointer}} } void freeFunctionPtr(void) { free((void *)fnptr); - // expected-warning@-1{{Argument to free() is a function pointer}} + // expected-warning@-1{{Argument to 'free()' is a function pointer}} // expected-warning@-2{{attempt to call free on non-heap object '(void *)fnptr'}} } @@ -1905,8 +1905,8 @@ enum { BUFSIZE = 256 }; void MEM34_C(void) { char buf[BUFSIZE]; char *p = (char *)realloc(buf, 2 * BUFSIZE); - // expected-warning@-1{{Argument to realloc() is the address of the local \ -variable 'buf', which is not memory allocated by malloc() [unix.Malloc]}} + // expected-warning@-1{{Argument to 'realloc()' is the address of the local \ +variable 'buf', which is not memory allocated by 'malloc()' [unix.Malloc]}} if (p == NULL) { /* Handle error */ } diff --git a/clang/test/Analysis/malloc.mm b/clang/test/Analysis/malloc.mm index 94a46d731090b..5b816a1524aec 100644 --- a/clang/test/Analysis/malloc.mm +++ b/clang/test/Analysis/malloc.mm @@ -89,7 +89,7 @@ void testNSStringFreeWhenDoneNO2(NSUInteger dataLength) { void testOffsetFree() { int *p = (int *)malloc(sizeof(int)); - NSData *nsdata = [NSData dataWithBytesNoCopy:++p length:sizeof(int) freeWhenDone:1]; // expected-warning{{Argument to +dataWithBytesNoCopy:length:freeWhenDone: is offset by 4 bytes from the start of memory allocated by malloc()}} + NSData *nsdata = [NSData dataWithBytesNoCopy:++p length:sizeof(int) freeWhenDone:1]; // expected-warning{{Argument to +dataWithBytesNoCopy:length:freeWhenDone: is offset by 4 bytes from the start of memory allocated by 'malloc()'}} } void testRelinquished1() { diff --git a/clang/test/Analysis/mmap-writeexec.c b/clang/test/Analysis/mmap-writeexec.c index 8fd86ceb9d2a2..579cc75069eec 100644 --- a/clang/test/Analysis/mmap-writeexec.c +++ b/clang/test/Analysis/mmap-writeexec.c @@ -1,13 +1,14 @@ -// RUN: %clang_analyze_cc1 -triple i686-unknown-linux -analyzer-checker=alpha.security.MmapWriteExec -analyzer-config alpha.security.MmapWriteExec:MmapProtExec=1 -analyzer-config alpha.security.MmapWriteExec:MmapProtRead=4 -DUSE_ALTERNATIVE_PROT_EXEC_DEFINITION -verify %s +// RUN: %clang_analyze_cc1 -triple i686-unknown-linux -analyzer-checker=alpha.security.MmapWriteExec -DUSE_ALTERNATIVE_PROT_EXEC_DEFINITION -verify %s // RUN: %clang_analyze_cc1 -triple x86_64-unknown-apple-darwin10 -analyzer-checker=alpha.security.MmapWriteExec -verify %s -#define PROT_WRITE 0x02 #ifndef USE_ALTERNATIVE_PROT_EXEC_DEFINITION -#define PROT_EXEC 0x04 -#define PROT_READ 0x01 -#else #define PROT_EXEC 0x01 +#define PROT_WRITE 0x02 #define PROT_READ 0x04 +#else +#define PROT_EXEC 0x08 +#define PROT_WRITE 0x04 +#define PROT_READ 0x02 #endif #define MAP_PRIVATE 0x0002 #define MAP_ANON 0x1000 diff --git a/clang/test/Analysis/out-of-bounds-diagnostics.c b/clang/test/Analysis/out-of-bounds-diagnostics.c index 92f983d8b1561..de70e483add1c 100644 --- a/clang/test/Analysis/out-of-bounds-diagnostics.c +++ b/clang/test/Analysis/out-of-bounds-diagnostics.c @@ -17,6 +17,27 @@ int underflowWithDeref(void) { // expected-note@-2 {{Access of 'TenElements' at negative byte offset -4}} } +int rng(void); +int getIndex(void) { + switch (rng()) { + case 1: return -152; + case 2: return -160; + case 3: return -168; + default: return -172; + } +} + +void gh86959(void) { + // Previously code like this produced many almost-identical bug reports that + // only differed in the offset value. Verify that now we only see one report. + + // expected-note@+1 {{Entering loop body}} + while (rng()) + TenElements[getIndex()] = 10; + // expected-warning@-1 {{Out of bound access to memory preceding 'TenElements'}} + // expected-note@-2 {{Access of 'TenElements' at negative byte offset -688}} +} + int scanf(const char *restrict fmt, ...); void taintedIndex(void) { diff --git a/clang/test/Analysis/plist-macros.cpp b/clang/test/Analysis/plist-macros.cpp index 94f8e514c8b39..d7b3c7cc1c86f 100644 --- a/clang/test/Analysis/plist-macros.cpp +++ b/clang/test/Analysis/plist-macros.cpp @@ -13,7 +13,7 @@ void noteOnMacro(int y) { mallocmemory y++; y++; - delete x; // expected-warning {{Memory allocated by malloc() should be deallocated by free(), not 'delete'}} + delete x; // expected-warning {{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'delete'}} } void macroIsFirstInFunction(int y) { diff --git a/clang/test/Analysis/pointer-sub.c b/clang/test/Analysis/pointer-sub.c index 88e6dec2d172f..194c891889952 100644 --- a/clang/test/Analysis/pointer-sub.c +++ b/clang/test/Analysis/pointer-sub.c @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.PointerSub -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.PointerSub -analyzer-output=text-minimal -verify %s void f1(void) { int x, y, z[10]; @@ -73,15 +73,15 @@ void f4(void) { d = a[2] - a[1]; // expected-warning{{Subtraction of two pointers that}} } -typedef struct { +struct S { int a; int b; int c[10]; // expected-note2{{Array at the right-hand side of subtraction}} int d[10]; // expected-note2{{Array at the left-hand side of subtraction}} -} S; +}; void f5(void) { - S s; + struct S s; int y; int d; @@ -92,18 +92,18 @@ void f5(void) { d = &s.d[3] - &s.c[2]; // expected-warning{{Subtraction of two pointers that}} d = s.d - s.c; // expected-warning{{Subtraction of two pointers that}} - S sa[10]; + struct S sa[10]; d = &sa[2] - &sa[1]; d = &sa[2].a - &sa[1].b; // expected-warning{{Subtraction of two pointers that}} } void f6(void) { - long long l; + long long l = 2; char *a1 = (char *)&l; int d = a1[3] - l; - long long la1[3]; // expected-note{{Array at the right-hand side of subtraction}} - long long la2[3]; // expected-note{{Array at the left-hand side of subtraction}} + long long la1[3] = {1}; // expected-note{{Array at the right-hand side of subtraction}} + long long la2[3] = {1}; // expected-note{{Array at the left-hand side of subtraction}} char *pla1 = (char *)la1; char *pla2 = (char *)la2; d = pla1[1] - pla1[0]; @@ -117,6 +117,40 @@ void f7(int *p) { } void f8(int n) { - int a[10]; - int d = a[n] - a[0]; + int a[10] = {1}; + int d = a[n] - a[0]; // no-warning +} + +int f9(const char *p1) { + const char *p2 = p1; + --p1; + ++p2; + return p1 - p2; // no-warning +} + +int f10(struct S *p1, struct S *p2) { + return &p1->c[5] - &p2->c[5]; // no-warning +} + +struct S1 { + int a; + int b; // expected-note{{Object at the right-hand side of subtraction}} +}; + +int f11() { + struct S1 s; // expected-note{{Object at the left-hand side of subtraction}} + return (char *)&s - (char *)&s.b; // expected-warning{{Subtraction of two pointers that}} +} + +struct S2 { + char *p1; + char *p2; +}; + +void init_S2(struct S2 *); + +int f12() { + struct S2 s; + init_S2(&s); + return s.p1 - s.p2; // no-warning (pointers are unknown) } diff --git a/clang/test/Analysis/short-circuiting-eval.cpp b/clang/test/Analysis/short-circuiting-eval.cpp new file mode 100644 index 0000000000000..d0f29a849ab1c --- /dev/null +++ b/clang/test/Analysis/short-circuiting-eval.cpp @@ -0,0 +1,39 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core.DivideZero -verify %s + +int div0LogicalOpInTernary(bool b1) { + int y = (b1 || b1) ? 0 : 1; + return 1 / y; // expected-warning {{Division by zero}} +} + +int div0LogicalAndArith(bool b1, int x) { + int y = (b1 || (x < 3)) ? 0 : 1; + return 1 / y; // expected-warning {{Division by zero}} +} + +int div0NestedLogicalOp(bool b1) { + int y = (b1 && b1 || b1 && b1) ? 0 : 1; + return 1 / y; // expected-warning {{Division by zero}} +} + +int div0TernaryInTernary(bool b) { + int y = ((b || b) ? false : true) ? 0 : 1; + return 1 / y; // expected-warning {{Division by zero}} +} + +int div0LogicalOpParensInTernary(bool b1) { + int y = ((((b1)) || ((b1)))) ? 0 : 1; + return 1 / y; // expected-warning {{Division by zero}} +} + +int div0LogicalOpInsideStExpr(bool b1) { + int y = ({1; (b1 || b1);}) ? 0 : 1; + // expected-warning@-1 {{expression result unused}} + return 1 / y; // expected-warning {{Division by zero}} +} + +int div0StExprInsideLogicalOp(bool b1) { + int y = (({1; b1;}) || ({1; b1;})) ? 0 : 1; + // expected-warning@-1 {{expression result unused}} + // expected-warning@-2 {{expression result unused}} + return 1 / y; // expected-warning {{Division by zero}} +} diff --git a/clang/test/Analysis/stream.c b/clang/test/Analysis/stream.c index c924cbd36f759..b9a5b1ba8cd49 100644 --- a/clang/test/Analysis/stream.c +++ b/clang/test/Analysis/stream.c @@ -1,11 +1,11 @@ // RUN: %clang_analyze_cc1 -triple=x86_64-pc-linux-gnu -analyzer-checker=core,unix.Stream,debug.ExprInspection \ -// RUN: -analyzer-config unix.Stream:Pedantic=true -verify %s +// RUN: -analyzer-config eagerly-assume=false,unix.Stream:Pedantic=true -verify %s // RUN: %clang_analyze_cc1 -triple=armv8-none-linux-eabi -analyzer-checker=core,unix.Stream,debug.ExprInspection \ -// RUN: -analyzer-config unix.Stream:Pedantic=true -verify %s +// RUN: -analyzer-config eagerly-assume=false,unix.Stream:Pedantic=true -verify %s // RUN: %clang_analyze_cc1 -triple=aarch64-linux-gnu -analyzer-checker=core,unix.Stream,debug.ExprInspection \ -// RUN: -analyzer-config unix.Stream:Pedantic=true -verify %s +// RUN: -analyzer-config eagerly-assume=false,unix.Stream:Pedantic=true -verify %s // RUN: %clang_analyze_cc1 -triple=hexagon -analyzer-checker=core,unix.Stream,debug.ExprInspection \ -// RUN: -analyzer-config unix.Stream:Pedantic=true -verify %s +// RUN: -analyzer-config eagerly-assume=false,unix.Stream:Pedantic=true -verify %s #include "Inputs/system-header-simulator.h" #include "Inputs/system-header-simulator-for-malloc.h" @@ -498,3 +498,35 @@ void gh_93408_regression_ZeroSized(struct ZeroSized *buffer) { fread(buffer, 1, 1, f); // expected-warning {{Stream pointer might be NULL}} no-crash fclose(f); } + +extern FILE *non_standard_stream_ptr; +void test_fopen_does_not_alias_with_standard_streams(void) { + FILE *f = fopen("file", "r"); + if (!f) return; + clang_analyzer_eval(f == stdin); // expected-warning {{FALSE}} no-TRUE + clang_analyzer_eval(f == stdout); // expected-warning {{FALSE}} no-TRUE + clang_analyzer_eval(f == stderr); // expected-warning {{FALSE}} no-TRUE + clang_analyzer_eval(f == non_standard_stream_ptr); // expected-warning {{UNKNOWN}} + if (f != stdout) { + fclose(f); + } +} // no-leak: 'fclose()' is always called because 'f' cannot be 'stdout'. + +void reopen_std_stream(void) { + FILE *oldStdout = stdout; + fclose(stdout); + FILE *fp = fopen("blah", "w"); + if (!fp) return; + + stdout = fp; // Let's make them alias. + clang_analyzer_eval(fp == oldStdout); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(fp == stdout); // expected-warning {{TRUE}} no-FALSE + clang_analyzer_eval(oldStdout == stdout); // expected-warning {{UNKNOWN}} +} + +void only_success_path_does_not_alias_with_stdout(void) { + if (stdout) return; + FILE *f = fopen("/tmp/foof", "r"); // no-crash + if (!f) return; + fclose(f); +} diff --git a/clang/test/Analysis/use-after-move.cpp b/clang/test/Analysis/use-after-move.cpp index 33980e6ea2b8b..24d5dd8a8b3d2 100644 --- a/clang/test/Analysis/use-after-move.cpp +++ b/clang/test/Analysis/use-after-move.cpp @@ -570,13 +570,8 @@ void differentBranchesTest(int i) { { A a; a.foo() > 0 ? a.foo() : A(std::move(a)).foo(); -#ifdef DFS - // peaceful-note@-2 {{Assuming the condition is false}} - // peaceful-note@-3 {{'?' condition is false}} -#else - // peaceful-note@-5 {{Assuming the condition is true}} - // peaceful-note@-6 {{'?' condition is true}} -#endif + // peaceful-note@-1 {{Assuming the condition is true}} + // peaceful-note@-2 {{'?' condition is true}} } // Same thing, but with a switch statement. { diff --git a/clang/test/Analysis/weak-functions.c b/clang/test/Analysis/weak-functions.c index 26cbfb3523a92..5bdb411fcbf4f 100644 --- a/clang/test/Analysis/weak-functions.c +++ b/clang/test/Analysis/weak-functions.c @@ -72,7 +72,7 @@ void free(void *) __attribute__((weak_import)); void t10 (void) { free((void*)&t10); - // expected-warning@-1{{Argument to free() is the address of the function 't10', which is not memory allocated by malloc()}} + // expected-warning@-1{{Argument to 'free()' is the address of the function 't10', which is not memory allocated by 'malloc()'}} // expected-warning@-2{{attempt to call free on non-heap object 't10'}} } diff --git a/clang/test/C/C23/n3018.c b/clang/test/C/C23/n3018.c index 0d54d53b7499f..4ad2fffbfde80 100644 --- a/clang/test/C/C23/n3018.c +++ b/clang/test/C/C23/n3018.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -std=c23 -verify -triple x86_64 -pedantic -Wno-conversion -Wno-constant-conversion %s +// RUN: %clang_cc1 -std=c23 -verify -triple x86_64 -pedantic -Wno-conversion -Wno-constant-conversion -fexperimental-new-constant-interpreter %s /* WG14 N3018: Full * The constexpr specifier for object definitions diff --git a/clang/test/C/C2y/n3254.c b/clang/test/C/C2y/n3254.c index e08659cf377aa..60d068cf9980b 100644 --- a/clang/test/C/C2y/n3254.c +++ b/clang/test/C/C2y/n3254.c @@ -21,9 +21,9 @@ struct S { // CHECK-LABEL: define dso_local i32 @foo( // CHECK-SAME: ) #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[BUFFER:%.*]] = alloca [12 x i8], align 1 +// CHECK-NEXT: [[BUFFER:%.*]] = alloca [12 x i8], align 4 // CHECK-NEXT: [[S_PTR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[BUFFER]], i8 0, i64 12, i1 false) +// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[BUFFER]], i8 0, i64 12, i1 false) // CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0 // CHECK-NEXT: store ptr [[ARRAYDECAY]], ptr [[S_PTR]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_PTR]], align 8 @@ -40,13 +40,13 @@ int foo() { // CHECK-LABEL: define dso_local signext i8 @bar( // CHECK-SAME: ) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[BUFFER:%.*]] = alloca [12 x i8], align 1 +// CHECK-NEXT: [[BUFFER:%.*]] = alloca [12 x i8], align 4 // CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0 // CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 1 -// CHECK-NEXT: store i8 97, ptr [[C]], align 1 +// CHECK-NEXT: store i8 97, ptr [[C]], align 4 // CHECK-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0 // CHECK-NEXT: [[C2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYDECAY1]], i32 0, i32 1 -// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[C2]], align 1 +// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[C2]], align 4 // CHECK-NEXT: ret i8 [[TMP0]] // char bar() { @@ -58,13 +58,13 @@ char bar() { // CHECK-LABEL: define dso_local float @baz( // CHECK-SAME: ) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[BUFFER:%.*]] = alloca [12 x i8], align 1 +// CHECK-NEXT: [[BUFFER:%.*]] = alloca [12 x i8], align 4 // CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0 // CHECK-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 2 -// CHECK-NEXT: store float 3.000000e+00, ptr [[F]], align 1 +// CHECK-NEXT: store float 3.000000e+00, ptr [[F]], align 4 // CHECK-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0 // CHECK-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYDECAY1]], i32 0, i32 2 -// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F2]], align 1 +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F2]], align 4 // CHECK-NEXT: ret float [[TMP0]] // float baz() { @@ -80,9 +80,9 @@ struct T { // CHECK-LABEL: define dso_local signext i8 @quux( // CHECK-SAME: ) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[T:%.*]] = alloca [[STRUCT_T:%.*]], align 1 +// CHECK-NEXT: [[T:%.*]] = alloca [[STRUCT_T:%.*]], align 4 // CHECK-NEXT: [[S_PTR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[T]], i8 0, i64 12, i1 false) +// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[T]], i8 0, i64 12, i1 false) // CHECK-NEXT: [[BUFFER:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[T]], i32 0, i32 0 // CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0 // CHECK-NEXT: store ptr [[ARRAYDECAY]], ptr [[S_PTR]], align 8 @@ -100,10 +100,10 @@ char quux() { // CHECK-LABEL: define dso_local float @quibble( // CHECK-SAME: ) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[BUFFER:%.*]] = alloca [12 x i8], align 1 +// CHECK-NEXT: [[BUFFER:%.*]] = alloca [12 x i8], align 4 // CHECK-NEXT: [[T_PTR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: [[S_PTR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[BUFFER]], i8 0, i64 12, i1 false) +// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[BUFFER]], i8 0, i64 12, i1 false) // CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0 // CHECK-NEXT: store ptr [[ARRAYDECAY]], ptr [[T_PTR]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[T_PTR]], align 8 @@ -125,13 +125,13 @@ float quibble() { // CHECK-LABEL: define dso_local i32 @quorble( // CHECK-SAME: ) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[BUFFER:%.*]] = alloca [12 x i8], align 1 +// CHECK-NEXT: [[BUFFER:%.*]] = alloca [12 x i8], align 4 // CHECK-NEXT: [[S_PTR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0 // CHECK-NEXT: [[BUFFER1:%.*]] = getelementptr inbounds [[STRUCT_T:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 0 // CHECK-NEXT: [[ARRAYDECAY2:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER1]], i64 0, i64 0 // CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[ARRAYDECAY2]], i32 0, i32 0 -// CHECK-NEXT: store i32 12, ptr [[X]], align 1 +// CHECK-NEXT: store i32 12, ptr [[X]], align 4 // CHECK-NEXT: [[ARRAYDECAY3:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0 // CHECK-NEXT: [[BUFFER4:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[ARRAYDECAY3]], i32 0, i32 0 // CHECK-NEXT: [[ARRAYDECAY5:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER4]], i64 0, i64 0 diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt index 1c397f277d3c4..6832b5adcdea3 100644 --- a/clang/test/CMakeLists.txt +++ b/clang/test/CMakeLists.txt @@ -80,6 +80,7 @@ list(APPEND CLANG_TEST_DEPS clang-installapi clang-scan-deps clang-linker-wrapper + clang-nvlink-wrapper clang-offload-bundler clang-offload-packager diagtool diff --git a/clang/test/CXX/basic/basic.types/p10.cpp b/clang/test/CXX/basic/basic.types/p10.cpp index a543f248e5371..92d6da0035ea5 100644 --- a/clang/test/CXX/basic/basic.types/p10.cpp +++ b/clang/test/CXX/basic/basic.types/p10.cpp @@ -142,7 +142,7 @@ constexpr int arb(int n) { // expected-note {{declared here}} expected-note {{function parameter 'n' with unknown value cannot be used in a constant expression}} } constexpr long Overflow[(1 << 30) << 2]{}; // expected-warning {{requires 34 bits to represent}} \ - expected-warning {{variable length array folded to constant array as an extension}} \ + expected-error {{variable length array declaration not allowed at file scope}} \ expected-warning {{variable length arrays in C++ are a Clang extension}} \ expected-note {{signed left shift discards bits}} diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p2.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p2.cpp new file mode 100644 index 0000000000000..a06b107755596 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p2.cpp @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template +struct A0 { + struct B0; + + template + struct C0 { + struct D0; + + template + struct E0; + }; +}; + +template +int A0::B0::* f0(); + +template +int A0::B1::* f1(); + +template +int A0::C0::* f2(); // expected-error {{expected unqualified-id}} + +template +int A0::C1::* f3(); // expected-error {{no member named 'C1' in 'A0'}} + // expected-error@-1 {{expected ';' after top level declarator}} + +template +int A0::template C2::* f4(); + +template +int A0::template C0::D0::* f5(); + +template +int A0::template C2::D1::* f6(); + +template +int A0::template C0::E0::* f7(); // expected-error {{use 'template' keyword to treat 'E0' as a dependent template name}} + // expected-error@-1 {{expected unqualified-id}} + +template +int A0::template C2::E1::* f8(); // expected-error {{no member named 'C2' in 'A0'}} + +template +int A0::template C0::template E0::* f9(); + +template +int A0::template C2::template E1::* f10(); + +namespace TypoCorrection { + template + struct A { + template + struct Typo; // expected-note {{'Typo' declared here}} + }; + + template + int A::template typo::* f(); + + template + int A::typo::* g(); // expected-error {{no template named 'typo' in 'A'; did you mean 'Typo'?}} + // expected-error@-1 {{expected unqualified-id}} +} diff --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp index 323e56f9c5278..adfdb738e81c9 100644 --- a/clang/test/CXX/drs/cwg18xx.cpp +++ b/clang/test/CXX/drs/cwg18xx.cpp @@ -3,8 +3,8 @@ // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,cxx98-14,cxx11-17,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,cxx11-17,since-cxx11,since-cxx14,cxx17 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx23,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx23,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors #if __cplusplus == 199711L #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) @@ -480,8 +480,12 @@ namespace cwg1872 { // cwg1872: 9 static_assert(y == 0); #endif constexpr int z = A().f(); - // since-cxx11-error@-1 {{constexpr variable 'z' must be initialized by a constant expression}} - // since-cxx11-note@-2 {{non-literal type 'A' cannot be used in a constant expression}} + // since-cxx11-error@-1 {{constexpr variable 'z' must be initialized by a constant expression}}a +#if __cplusplus < 202302L + // since-cxx11-note@-3 {{non-literal type 'A' cannot be used in a constant expression}} +#else + // since-cxx23-note@-5 {{cannot construct object of type 'A' with virtual base class in a constant expression}} +#endif #endif } diff --git a/clang/test/CXX/drs/cwg24xx.cpp b/clang/test/CXX/drs/cwg24xx.cpp index 16b8ec07fc50f..00b6bb5a865df 100644 --- a/clang/test/CXX/drs/cwg24xx.cpp +++ b/clang/test/CXX/drs/cwg24xx.cpp @@ -82,6 +82,15 @@ auto h() -> C auto { C auto foo = T(); // expected-warning@-1 {{'C' is deprecated}} // expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} + C auto *bar = T(); + // expected-warning@-1 {{'C' is deprecated}} + // expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} + C auto &baz = T(); + // expected-warning@-1 {{'C' is deprecated}} + // expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} + C auto &&quux = T(); + // expected-warning@-1 {{'C' is deprecated}} + // expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} return foo; } #endif diff --git a/clang/test/CXX/drs/cwg25xx.cpp b/clang/test/CXX/drs/cwg25xx.cpp index 0934f0cc19c6a..1c0d32fe3fdfc 100644 --- a/clang/test/CXX/drs/cwg25xx.cpp +++ b/clang/test/CXX/drs/cwg25xx.cpp @@ -139,7 +139,7 @@ struct D3 : B { #endif #if __cplusplus >= 202302L -namespace cwg2561 { // cwg2561: no tentatively ready 2024-03-18 +namespace cwg2561 { // cwg2561: no struct C { constexpr C(auto) { } }; diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp index c77bd433d8e21..9796607a790ce 100644 --- a/clang/test/CXX/drs/cwg28xx.cpp +++ b/clang/test/CXX/drs/cwg28xx.cpp @@ -30,7 +30,7 @@ using U2 = decltype(&main); #endif } // namespace cwg2811 -namespace cwg2819 { // cwg2819: 19 tentatively ready 2023-12-01 +namespace cwg2819 { // cwg2819: 19 #if __cpp_constexpr >= 202306L constexpr void* p = nullptr; constexpr int* q = static_cast(p); @@ -111,7 +111,7 @@ struct D : N::B { #endif } // namespace cwg2857 -namespace cwg2858 { // cwg2858: 19 tentatively ready 2024-04-05 +namespace cwg2858 { // cwg2858: 19 #if __cplusplus > 202302L @@ -134,23 +134,23 @@ struct A { } // namespace cwg2858 -namespace cwg2877 { // cwg2877: 19 tentatively ready 2024-05-31 +namespace cwg2877 { // cwg2877: 19 #if __cplusplus >= 202002L enum E { x }; void f() { int E; - using enum E; // OK, names ::E + using enum E; // OK } using F = E; -using enum F; // OK, designates ::E +using enum F; // OK template using EE = T; void g() { - using enum EE; // OK, designates ::E + using enum EE; // OK } #endif } // namespace cwg2877 -namespace cwg2881 { // cwg2881: 19 tentatively ready 2024-04-19 +namespace cwg2881 { // cwg2881: 19 #if __cplusplus >= 202302L @@ -216,11 +216,61 @@ void f() { o.decltype(L2)::operator()(); } +void f2() { + int x = 0; + auto lambda = [x] (this auto self) { return x; }; + using Lambda = decltype(lambda); + struct D : private Lambda { // expected-note {{declared private here}} + D(Lambda l) : Lambda(l) {} + using Lambda::operator(); + friend Lambda; + } d(lambda); + d(); // expected-error {{must derive publicly from the lambda}} +} + +template +struct Private : private L { + using L::operator(); + Private(L l) : L(l) {} +}; + +template +struct Indirect : T { + using T::operator(); +}; + +template +struct Ambiguous : Indirect, T { // expected-warning {{is inaccessible due to ambiguity}} + using Indirect::operator(); +}; + +template +constexpr auto f3(L l) -> decltype(Private{l}()) { return l(); } +// expected-note@-1 {{must derive publicly from the lambda}} + +template +constexpr auto f4(L l) -> decltype(Ambiguous{{l}, l}()) { return l(); } +// expected-note@-1 {{is inaccessible due to ambiguity}} +// expected-note@-2 {{in instantiation of template class}} + +template +concept is_callable = requires(T t) { { t() }; }; + +void g() { + int x = 0; + auto lambda = [x](this auto self) {}; + f3(lambda); // expected-error {{no matching function for call to 'f3'}} + f4(lambda); // expected-error {{no matching function for call to 'f4'}} + // expected-note@-1 {{while substituting deduced template arguments into function template 'f4'}} + static_assert(!is_callable>); + static_assert(!is_callable>); +} + #endif } // namespace cwg2881 -namespace cwg2882 { // cwg2882: 2.7 tentatively ready 2024-05-31 +namespace cwg2882 { // cwg2882: 2.7 struct C { operator void() = delete; // expected-warning@-1 {{conversion function converting 'cwg2882::C' to 'void' will never be used}} @@ -232,7 +282,7 @@ void f(C c) { } } // namespace cwg2882 -namespace cwg2883 { // cwg2883: no tentatively ready 2024-05-31 +namespace cwg2883 { // cwg2883: no #if __cplusplus >= 201103L void f() { int x; @@ -257,7 +307,7 @@ void g() { #endif } // namespace cwg2883 -namespace cwg2885 { // cwg2885: 16 tentatively ready 2024-05-31 +namespace cwg2885 { // cwg2885: 16 review 2024-05-31 #if __cplusplus >= 202002L template struct A { @@ -271,7 +321,7 @@ static_assert(!__is_trivially_constructible(B)); #endif } // namespace cwg2885 -namespace cwg2886 { // cwg2886: 9 tentatively ready 2024-05-31 +namespace cwg2886 { // cwg2886: 9 #if __cplusplus >= 201103L struct C { C() = default; diff --git a/clang/test/CXX/drs/cwg6xx.cpp b/clang/test/CXX/drs/cwg6xx.cpp index 069102d9c5975..1c56dd3907152 100644 --- a/clang/test/CXX/drs/cwg6xx.cpp +++ b/clang/test/CXX/drs/cwg6xx.cpp @@ -1265,7 +1265,7 @@ namespace cwg687 { // cwg687 (9 c++20, but the issue is still considered open) // This is not. template g(a); - // expected-error@-1 {{expected expression}} + // expected-error@-1 {{expected '<' after 'template'}} } } diff --git a/clang/test/CXX/drs/cwg8xx.cpp b/clang/test/CXX/drs/cwg8xx.cpp index c8cbdfcee3f4d..38bff3adf262a 100644 --- a/clang/test/CXX/drs/cwg8xx.cpp +++ b/clang/test/CXX/drs/cwg8xx.cpp @@ -30,3 +30,9 @@ void g(int i) { } #endif } // namespace cwg873 + +// cwg882: 3.5 +#if __cplusplus >= 201103L +int main() = delete; +// since-cxx11-error@-1 {{'main' is not allowed to be deleted}} +#endif 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 162d59439d08e..170ca0a3f1c6b 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 @@ -43,18 +43,36 @@ namespace test2 { } namespace GH40906 { - struct A { - int val; - void func() {} - }; +struct S { + int x; + void func(); + static_assert(__is_same_as(decltype((S::x)), int&), ""); + static_assert(__is_same_as(decltype(&(S::x)), int*), ""); - void test() { - decltype(&(A::val)) ptr1; // expected-error {{cannot form pointer to member from a parenthesized expression; did you mean to remove the parentheses?}} - int A::* ptr2 = &(A::val); // expected-error {{invalid use of non-static data member 'val'}} + // FIXME: provide better error messages + static_assert(__is_same_as(decltype((S::func)), int&), ""); // expected-error {{call to non-static member function without an object argument}} + static_assert(__is_same_as(decltype(&(S::func)), int*), ""); // expected-error {{call to non-static member function without an object argument}} +}; +static_assert(__is_same_as(decltype((S::x)), int&), ""); +static_assert(__is_same_as(decltype(&(S::x)), int*), ""); +static_assert(__is_same_as(decltype((S::func)), int&), ""); // expected-error {{call to non-static member function without an object argument}} +static_assert(__is_same_as(decltype(&(S::func)), int*), ""); // expected-error {{call to non-static member function without an object argument}} + +struct A { int x;}; + +char q(int *); +short q(int A::*); + +template +constexpr int f(char (*)[sizeof(q(&T::x))]) { return 1; } + +template +constexpr int f(char (*)[sizeof(q(&(T::x)))]) { return 2; } + +constexpr int g(char (*p)[sizeof(char)] = 0) { return f(p); } +constexpr int h(char (*p)[sizeof(short)] = 0) { return f(p); } + +static_assert(g() == 2); +static_assert(h() == 1); - // FIXME: Error messages in these cases are less than clear, we can do - // better. - int size = sizeof(&(A::func)); // expected-error {{call to non-static member function without an object argument}} - void (A::* ptr3)() = &(A::func); // expected-error {{call to non-static member function without an object argument}} - } } diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp index 51489c5eac5ad..19793fe826372 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp @@ -38,3 +38,13 @@ X1 inst_x1a; X1 inst_x1b; X1 inst_x1c; X1 inst_x1d; // expected-error{{template template argument has different template parameters than its corresponding template template paramete}} + +template class X2; // expected-note{{template is declared here}} \ + // expected-note{{template is declared here}} +class X3 : X2<1> {}; // expected-error{{implicit instantiation of undefined template 'X2<1>'}} + +template class X4 : X3 { + struct { + X2<1> e; // expected-error{{implicit instantiation of undefined template 'X2<1>'}} + } f; +}; diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp index ed445360c4fdd..b9ff26a7620db 100644 --- a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp @@ -78,7 +78,7 @@ namespace std_example { template struct A { // expected-note {{candidate}} expected-note {{implicit deduction guide}} template A(T &&, U &&, int *); // expected-note {{[with T = int, U = int] not viable: expects an rvalue}} \ - // expected-note {{implicit deduction guide declared as 'template A(T &&, type-parameter-0-1 &&, int *) -> A'}} + // expected-note {{implicit deduction guide declared as 'template A(T &&, U &&, int *) -> A'}} A(T &&, int *); // expected-note {{requires 2}} \ // expected-note {{implicit deduction guide declared as 'template A(T &&, int *) -> A'}} }; diff --git a/clang/test/CXX/temp/temp.res/p3.cpp b/clang/test/CXX/temp/temp.res/p3.cpp index 37ab93559e369..1eda967523a59 100644 --- a/clang/test/CXX/temp/temp.res/p3.cpp +++ b/clang/test/CXX/temp/temp.res/p3.cpp @@ -2,7 +2,7 @@ template struct A { template struct B; - template using C = U; // expected-note {{here}} + template using C = U; }; struct X { @@ -20,12 +20,10 @@ template A::C f2(); // expected-warning {{missing 'typename'}} template A::C::X(T) {} template A::C::X::Y::Y(T) {} -// FIXME: This is ill-formed -template int A::B::*f3() {} -template int A::C::*f4() {} +template int A::B::*f3() {} // expected-error {{expected unqualified-id}} +template int A::C::*f4() {} // expected-error {{expected unqualified-id}} -// FIXME: This is valid -template int A::template C::*f5() {} // expected-error {{has no members}} +template int A::template C::*f5() {} template template struct A::B { friend A::C f6(); // ok, same as 'friend T f6();' diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p2-20.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p2-20.cpp index 7a261fef27361..935dd360847bc 100644 --- a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p2-20.cpp +++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p2-20.cpp @@ -56,7 +56,7 @@ struct B { static int y; template - int z; // expected-error {{member 'z' declared as a template}} + int z; // expected-error {{non-static data member 'z' cannot be declared as a template}} template static int x; @@ -65,7 +65,7 @@ struct B { static int y; template - int x; // expected-error {{member 'x' declared as a template}} + int x; // expected-error {{non-static data member 'x' cannot be declared as a template}} template<> int x; @@ -169,7 +169,7 @@ struct D { static int y; template - int z; // expected-error {{member 'z' declared as a template}} + int z; // expected-error {{non-static data member 'z' cannot be declared as a template}} template static int x; @@ -178,7 +178,7 @@ struct D { static int y; template - int x; // expected-error {{member 'x' declared as a template}} + int x; // expected-error {{non-static data member 'x' cannot be declared as a template}} template<> int x; diff --git a/clang/test/CodeGen/AMDGPU/amdgpu-atomic-float.c b/clang/test/CodeGen/AMDGPU/amdgpu-atomic-float.c new file mode 100644 index 0000000000000..6deff1116e1d8 --- /dev/null +++ b/clang/test/CodeGen/AMDGPU/amdgpu-atomic-float.c @@ -0,0 +1,316 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -fnative-half-arguments-and-returns -triple amdgcn-amd-amdhsa-gnu -target-cpu gfx900 -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,SAFE %s +// RUN: %clang_cc1 -fnative-half-arguments-and-returns -triple amdgcn-amd-amdhsa-gnu -target-cpu gfx900 -emit-llvm -munsafe-fp-atomics -o - %s | FileCheck -check-prefixes=CHECK,UNSAFE %s + +// SAFE-LABEL: define dso_local float @test_float_post_inc( +// SAFE-SAME: ) #[[ATTR0:[0-9]+]] { +// SAFE-NEXT: [[ENTRY:.*:]] +// SAFE-NEXT: [[RETVAL:%.*]] = alloca float, align 4, addrspace(5) +// SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test_float_post_inc.n to ptr), float 1.000000e+00 seq_cst, align 4 +// SAFE-NEXT: ret float [[TMP0]] +// +// UNSAFE-LABEL: define dso_local float @test_float_post_inc( +// UNSAFE-SAME: ) #[[ATTR0:[0-9]+]] { +// UNSAFE-NEXT: [[ENTRY:.*:]] +// UNSAFE-NEXT: [[RETVAL:%.*]] = alloca float, align 4, addrspace(5) +// UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test_float_post_inc.n to ptr), float 1.000000e+00 seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META3:![0-9]+]], !amdgpu.ignore.denormal.mode [[META3]] +// UNSAFE-NEXT: ret float [[TMP0]] +// +float test_float_post_inc() +{ + static _Atomic float n; + return n++; +} + +// SAFE-LABEL: define dso_local float @test_float_post_dc( +// SAFE-SAME: ) #[[ATTR0]] { +// SAFE-NEXT: [[ENTRY:.*:]] +// SAFE-NEXT: [[RETVAL:%.*]] = alloca float, align 4, addrspace(5) +// SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test_float_post_dc.n to ptr), float 1.000000e+00 seq_cst, align 4 +// SAFE-NEXT: ret float [[TMP0]] +// +// UNSAFE-LABEL: define dso_local float @test_float_post_dc( +// UNSAFE-SAME: ) #[[ATTR0]] { +// UNSAFE-NEXT: [[ENTRY:.*:]] +// UNSAFE-NEXT: [[RETVAL:%.*]] = alloca float, align 4, addrspace(5) +// UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test_float_post_dc.n to ptr), float 1.000000e+00 seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META3]] +// UNSAFE-NEXT: ret float [[TMP0]] +// +float test_float_post_dc() +{ + static _Atomic float n; + return n--; +} + +// SAFE-LABEL: define dso_local float @test_float_pre_dc( +// SAFE-SAME: ) #[[ATTR0]] { +// SAFE-NEXT: [[ENTRY:.*:]] +// SAFE-NEXT: [[RETVAL:%.*]] = alloca float, align 4, addrspace(5) +// SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test_float_pre_dc.n to ptr), float 1.000000e+00 seq_cst, align 4 +// SAFE-NEXT: [[TMP1:%.*]] = fsub float [[TMP0]], 1.000000e+00 +// SAFE-NEXT: ret float [[TMP1]] +// +// UNSAFE-LABEL: define dso_local float @test_float_pre_dc( +// UNSAFE-SAME: ) #[[ATTR0]] { +// UNSAFE-NEXT: [[ENTRY:.*:]] +// UNSAFE-NEXT: [[RETVAL:%.*]] = alloca float, align 4, addrspace(5) +// UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test_float_pre_dc.n to ptr), float 1.000000e+00 seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META3]] +// UNSAFE-NEXT: [[TMP1:%.*]] = fsub float [[TMP0]], 1.000000e+00 +// UNSAFE-NEXT: ret float [[TMP1]] +// +float test_float_pre_dc() +{ + static _Atomic float n; + return --n; +} + +// SAFE-LABEL: define dso_local float @test_float_pre_inc( +// SAFE-SAME: ) #[[ATTR0]] { +// SAFE-NEXT: [[ENTRY:.*:]] +// SAFE-NEXT: [[RETVAL:%.*]] = alloca float, align 4, addrspace(5) +// SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test_float_pre_inc.n to ptr), float 1.000000e+00 seq_cst, align 4 +// SAFE-NEXT: [[TMP1:%.*]] = fadd float [[TMP0]], 1.000000e+00 +// SAFE-NEXT: ret float [[TMP1]] +// +// UNSAFE-LABEL: define dso_local float @test_float_pre_inc( +// UNSAFE-SAME: ) #[[ATTR0]] { +// UNSAFE-NEXT: [[ENTRY:.*:]] +// UNSAFE-NEXT: [[RETVAL:%.*]] = alloca float, align 4, addrspace(5) +// UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test_float_pre_inc.n to ptr), float 1.000000e+00 seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META3]], !amdgpu.ignore.denormal.mode [[META3]] +// UNSAFE-NEXT: [[TMP1:%.*]] = fadd float [[TMP0]], 1.000000e+00 +// UNSAFE-NEXT: ret float [[TMP1]] +// +float test_float_pre_inc() +{ + static _Atomic float n; + return ++n; +} + +// SAFE-LABEL: define dso_local double @test_double_post_inc( +// SAFE-SAME: ) #[[ATTR0]] { +// SAFE-NEXT: [[ENTRY:.*:]] +// SAFE-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5) +// SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test_double_post_inc.n to ptr), float 1.000000e+00 seq_cst, align 8 +// SAFE-NEXT: store float [[TMP0]], ptr [[RETVAL_ASCAST]], align 8 +// SAFE-NEXT: [[TMP1:%.*]] = load double, ptr [[RETVAL_ASCAST]], align 8 +// SAFE-NEXT: ret double [[TMP1]] +// +// UNSAFE-LABEL: define dso_local double @test_double_post_inc( +// UNSAFE-SAME: ) #[[ATTR0]] { +// UNSAFE-NEXT: [[ENTRY:.*:]] +// UNSAFE-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5) +// UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test_double_post_inc.n to ptr), float 1.000000e+00 seq_cst, align 8, !amdgpu.no.fine.grained.memory [[META3]], !amdgpu.ignore.denormal.mode [[META3]] +// UNSAFE-NEXT: store float [[TMP0]], ptr [[RETVAL_ASCAST]], align 8 +// UNSAFE-NEXT: [[TMP1:%.*]] = load double, ptr [[RETVAL_ASCAST]], align 8 +// UNSAFE-NEXT: ret double [[TMP1]] +// +double test_double_post_inc() +{ + static _Atomic double n; + return n++; +} + +// SAFE-LABEL: define dso_local double @test_double_post_dc( +// SAFE-SAME: ) #[[ATTR0]] { +// SAFE-NEXT: [[ENTRY:.*:]] +// SAFE-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5) +// SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test_double_post_dc.n to ptr), float 1.000000e+00 seq_cst, align 8 +// SAFE-NEXT: store float [[TMP0]], ptr [[RETVAL_ASCAST]], align 8 +// SAFE-NEXT: [[TMP1:%.*]] = load double, ptr [[RETVAL_ASCAST]], align 8 +// SAFE-NEXT: ret double [[TMP1]] +// +// UNSAFE-LABEL: define dso_local double @test_double_post_dc( +// UNSAFE-SAME: ) #[[ATTR0]] { +// UNSAFE-NEXT: [[ENTRY:.*:]] +// UNSAFE-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5) +// UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test_double_post_dc.n to ptr), float 1.000000e+00 seq_cst, align 8, !amdgpu.no.fine.grained.memory [[META3]] +// UNSAFE-NEXT: store float [[TMP0]], ptr [[RETVAL_ASCAST]], align 8 +// UNSAFE-NEXT: [[TMP1:%.*]] = load double, ptr [[RETVAL_ASCAST]], align 8 +// UNSAFE-NEXT: ret double [[TMP1]] +// +double test_double_post_dc() +{ + static _Atomic double n; + return n--; +} + +// SAFE-LABEL: define dso_local double @test_double_pre_dc( +// SAFE-SAME: ) #[[ATTR0]] { +// SAFE-NEXT: [[ENTRY:.*:]] +// SAFE-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5) +// SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test_double_pre_dc.n to ptr), float 1.000000e+00 seq_cst, align 8 +// SAFE-NEXT: [[TMP1:%.*]] = fsub float [[TMP0]], 1.000000e+00 +// SAFE-NEXT: store float [[TMP1]], ptr [[RETVAL_ASCAST]], align 8 +// SAFE-NEXT: [[TMP2:%.*]] = load double, ptr [[RETVAL_ASCAST]], align 8 +// SAFE-NEXT: ret double [[TMP2]] +// +// UNSAFE-LABEL: define dso_local double @test_double_pre_dc( +// UNSAFE-SAME: ) #[[ATTR0]] { +// UNSAFE-NEXT: [[ENTRY:.*:]] +// UNSAFE-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5) +// UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test_double_pre_dc.n to ptr), float 1.000000e+00 seq_cst, align 8, !amdgpu.no.fine.grained.memory [[META3]] +// UNSAFE-NEXT: [[TMP1:%.*]] = fsub float [[TMP0]], 1.000000e+00 +// UNSAFE-NEXT: store float [[TMP1]], ptr [[RETVAL_ASCAST]], align 8 +// UNSAFE-NEXT: [[TMP2:%.*]] = load double, ptr [[RETVAL_ASCAST]], align 8 +// UNSAFE-NEXT: ret double [[TMP2]] +// +double test_double_pre_dc() +{ + static _Atomic double n; + return --n; +} + +// SAFE-LABEL: define dso_local double @test_double_pre_inc( +// SAFE-SAME: ) #[[ATTR0]] { +// SAFE-NEXT: [[ENTRY:.*:]] +// SAFE-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5) +// SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test_double_pre_inc.n to ptr), float 1.000000e+00 seq_cst, align 8 +// SAFE-NEXT: [[TMP1:%.*]] = fadd float [[TMP0]], 1.000000e+00 +// SAFE-NEXT: store float [[TMP1]], ptr [[RETVAL_ASCAST]], align 8 +// SAFE-NEXT: [[TMP2:%.*]] = load double, ptr [[RETVAL_ASCAST]], align 8 +// SAFE-NEXT: ret double [[TMP2]] +// +// UNSAFE-LABEL: define dso_local double @test_double_pre_inc( +// UNSAFE-SAME: ) #[[ATTR0]] { +// UNSAFE-NEXT: [[ENTRY:.*:]] +// UNSAFE-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5) +// UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test_double_pre_inc.n to ptr), float 1.000000e+00 seq_cst, align 8, !amdgpu.no.fine.grained.memory [[META3]], !amdgpu.ignore.denormal.mode [[META3]] +// UNSAFE-NEXT: [[TMP1:%.*]] = fadd float [[TMP0]], 1.000000e+00 +// UNSAFE-NEXT: store float [[TMP1]], ptr [[RETVAL_ASCAST]], align 8 +// UNSAFE-NEXT: [[TMP2:%.*]] = load double, ptr [[RETVAL_ASCAST]], align 8 +// UNSAFE-NEXT: ret double [[TMP2]] +// +double test_double_pre_inc() +{ + static _Atomic double n; + return ++n; +} + +// SAFE-LABEL: define dso_local half @test__Float16_post_inc( +// SAFE-SAME: ) #[[ATTR0]] { +// SAFE-NEXT: [[ENTRY:.*:]] +// SAFE-NEXT: [[RETVAL:%.*]] = alloca half, align 2, addrspace(5) +// SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test__Float16_post_inc.n to ptr), float 1.000000e+00 seq_cst, align 2 +// SAFE-NEXT: store float [[TMP0]], ptr [[RETVAL_ASCAST]], align 2 +// SAFE-NEXT: [[TMP1:%.*]] = load half, ptr [[RETVAL_ASCAST]], align 2 +// SAFE-NEXT: ret half [[TMP1]] +// +// UNSAFE-LABEL: define dso_local half @test__Float16_post_inc( +// UNSAFE-SAME: ) #[[ATTR0]] { +// UNSAFE-NEXT: [[ENTRY:.*:]] +// UNSAFE-NEXT: [[RETVAL:%.*]] = alloca half, align 2, addrspace(5) +// UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test__Float16_post_inc.n to ptr), float 1.000000e+00 seq_cst, align 2, !amdgpu.no.fine.grained.memory [[META3]], !amdgpu.ignore.denormal.mode [[META3]] +// UNSAFE-NEXT: store float [[TMP0]], ptr [[RETVAL_ASCAST]], align 2 +// UNSAFE-NEXT: [[TMP1:%.*]] = load half, ptr [[RETVAL_ASCAST]], align 2 +// UNSAFE-NEXT: ret half [[TMP1]] +// +_Float16 test__Float16_post_inc() +{ + static _Atomic _Float16 n; + return n++; +} + +// SAFE-LABEL: define dso_local half @test__Float16_post_dc( +// SAFE-SAME: ) #[[ATTR0]] { +// SAFE-NEXT: [[ENTRY:.*:]] +// SAFE-NEXT: [[RETVAL:%.*]] = alloca half, align 2, addrspace(5) +// SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test__Float16_post_dc.n to ptr), float 1.000000e+00 seq_cst, align 2 +// SAFE-NEXT: store float [[TMP0]], ptr [[RETVAL_ASCAST]], align 2 +// SAFE-NEXT: [[TMP1:%.*]] = load half, ptr [[RETVAL_ASCAST]], align 2 +// SAFE-NEXT: ret half [[TMP1]] +// +// UNSAFE-LABEL: define dso_local half @test__Float16_post_dc( +// UNSAFE-SAME: ) #[[ATTR0]] { +// UNSAFE-NEXT: [[ENTRY:.*:]] +// UNSAFE-NEXT: [[RETVAL:%.*]] = alloca half, align 2, addrspace(5) +// UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test__Float16_post_dc.n to ptr), float 1.000000e+00 seq_cst, align 2, !amdgpu.no.fine.grained.memory [[META3]] +// UNSAFE-NEXT: store float [[TMP0]], ptr [[RETVAL_ASCAST]], align 2 +// UNSAFE-NEXT: [[TMP1:%.*]] = load half, ptr [[RETVAL_ASCAST]], align 2 +// UNSAFE-NEXT: ret half [[TMP1]] +// +_Float16 test__Float16_post_dc() +{ + static _Atomic _Float16 n; + return n--; +} + +// SAFE-LABEL: define dso_local half @test__Float16_pre_dc( +// SAFE-SAME: ) #[[ATTR0]] { +// SAFE-NEXT: [[ENTRY:.*:]] +// SAFE-NEXT: [[RETVAL:%.*]] = alloca half, align 2, addrspace(5) +// SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test__Float16_pre_dc.n to ptr), float 1.000000e+00 seq_cst, align 2 +// SAFE-NEXT: [[TMP1:%.*]] = fsub float [[TMP0]], 1.000000e+00 +// SAFE-NEXT: store float [[TMP1]], ptr [[RETVAL_ASCAST]], align 2 +// SAFE-NEXT: [[TMP2:%.*]] = load half, ptr [[RETVAL_ASCAST]], align 2 +// SAFE-NEXT: ret half [[TMP2]] +// +// UNSAFE-LABEL: define dso_local half @test__Float16_pre_dc( +// UNSAFE-SAME: ) #[[ATTR0]] { +// UNSAFE-NEXT: [[ENTRY:.*:]] +// UNSAFE-NEXT: [[RETVAL:%.*]] = alloca half, align 2, addrspace(5) +// UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspacecast (ptr addrspace(1) @test__Float16_pre_dc.n to ptr), float 1.000000e+00 seq_cst, align 2, !amdgpu.no.fine.grained.memory [[META3]] +// UNSAFE-NEXT: [[TMP1:%.*]] = fsub float [[TMP0]], 1.000000e+00 +// UNSAFE-NEXT: store float [[TMP1]], ptr [[RETVAL_ASCAST]], align 2 +// UNSAFE-NEXT: [[TMP2:%.*]] = load half, ptr [[RETVAL_ASCAST]], align 2 +// UNSAFE-NEXT: ret half [[TMP2]] +// +_Float16 test__Float16_pre_dc() +{ + static _Atomic _Float16 n; + return --n; +} + +// SAFE-LABEL: define dso_local half @test__Float16_pre_inc( +// SAFE-SAME: ) #[[ATTR0]] { +// SAFE-NEXT: [[ENTRY:.*:]] +// SAFE-NEXT: [[RETVAL:%.*]] = alloca half, align 2, addrspace(5) +// SAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// SAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test__Float16_pre_inc.n to ptr), float 1.000000e+00 seq_cst, align 2 +// SAFE-NEXT: [[TMP1:%.*]] = fadd float [[TMP0]], 1.000000e+00 +// SAFE-NEXT: store float [[TMP1]], ptr [[RETVAL_ASCAST]], align 2 +// SAFE-NEXT: [[TMP2:%.*]] = load half, ptr [[RETVAL_ASCAST]], align 2 +// SAFE-NEXT: ret half [[TMP2]] +// +// UNSAFE-LABEL: define dso_local half @test__Float16_pre_inc( +// UNSAFE-SAME: ) #[[ATTR0]] { +// UNSAFE-NEXT: [[ENTRY:.*:]] +// UNSAFE-NEXT: [[RETVAL:%.*]] = alloca half, align 2, addrspace(5) +// UNSAFE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// UNSAFE-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @test__Float16_pre_inc.n to ptr), float 1.000000e+00 seq_cst, align 2, !amdgpu.no.fine.grained.memory [[META3]], !amdgpu.ignore.denormal.mode [[META3]] +// UNSAFE-NEXT: [[TMP1:%.*]] = fadd float [[TMP0]], 1.000000e+00 +// UNSAFE-NEXT: store float [[TMP1]], ptr [[RETVAL_ASCAST]], align 2 +// UNSAFE-NEXT: [[TMP2:%.*]] = load half, ptr [[RETVAL_ASCAST]], align 2 +// UNSAFE-NEXT: ret half [[TMP2]] +// +_Float16 test__Float16_pre_inc() +{ + static _Atomic _Float16 n; + return ++n; +} +//. +// UNSAFE: [[META3]] = !{} +//. +//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +// CHECK: {{.*}} diff --git a/clang/test/CodeGen/LoongArch/align.c b/clang/test/CodeGen/LoongArch/align.c new file mode 100644 index 0000000000000..1b171b74529d1 --- /dev/null +++ b/clang/test/CodeGen/LoongArch/align.c @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -triple loongarch32 -target-feature +lsx -target-feature \ +// RUN: +lasx -emit-llvm %s -o - | FileCheck %s --check-prefix=LA32 +// RUN: %clang_cc1 -triple loongarch64 -target-feature +lsx -target-feature \ +// RUN: +lasx -emit-llvm %s -o - | FileCheck %s --check-prefix=LA64 + +#include +#include + +char *s1 = "1234"; +// LA32: @.str{{.*}} ={{.*}} constant [5 x i8] c"1234\00", align 1 +// LA64: @.str{{.*}} ={{.*}} constant [5 x i8] c"1234\00", align 1 + +char *s2 = "12345678abcd"; +// LA32: @.str{{.*}} ={{.*}} constant [13 x i8] c"12345678abcd\00", align 1 +// LA64: @.str{{.*}} ={{.*}} constant [13 x i8] c"12345678abcd\00", align 1 + +char *s3 = "123456789012345678901234567890ab"; +// LA32: @.str{{.*}} ={{.*}} constant [33 x i8] c"1234{{.*}}ab\00", align 1 +// LA64: @.str{{.*}} ={{.*}} constant [33 x i8] c"1234{{.*}}ab\00", align 1 + +char *s4 = "123456789012345678901234567890123456789012345678901234567890abcdef"; +// LA32: @.str{{.*}} ={{.*}} constant [67 x i8] c"1234{{.*}}cdef\00", align 1 +// LA64: @.str{{.*}} ={{.*}} constant [67 x i8] c"1234{{.*}}cdef\00", align 1 + +int8_t a; +// LA32: @a ={{.*}} global i8 0, align 1 +// LA64: @a ={{.*}} global i8 0, align 1 + +int16_t b; +// LA32: @b ={{.*}} global i16 0, align 2 +// LA64: @b ={{.*}} global i16 0, align 2 + +int32_t c; +// LA32: @c ={{.*}} global i32 0, align 4 +// LA64: @c ={{.*}} global i32 0, align 4 + +int64_t d; +// LA32: @d ={{.*}} global i64 0, align 8 +// LA64: @d ={{.*}} global i64 0, align 8 + +intptr_t e; +// LA32: @e ={{.*}} global i32 0, align 4 +// LA64: @e ={{.*}} global i64 0, align 8 + +float f; +// LA32: @f ={{.*}} global float 0.000000e+00, align 4 +// LA64: @f ={{.*}} global float 0.000000e+00, align 4 + +double g; +// LA32: @g ={{.*}} global double 0.000000e+00, align 8 +// LA64: @g ={{.*}} global double 0.000000e+00, align 8 + +struct H { + int8_t a; +}; +struct H h; +// LA32: @h ={{.*}} global %struct.H zeroinitializer, align 1 +// LA64: @h ={{.*}} global %struct.H zeroinitializer, align 1 diff --git a/clang/test/CodeGen/PowerPC/save-reg-params.c b/clang/test/CodeGen/PowerPC/save-reg-params.c new file mode 100644 index 0000000000000..d34c97a8fc45f --- /dev/null +++ b/clang/test/CodeGen/PowerPC/save-reg-params.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple powerpc64-ibm-aix -emit-llvm -o - %s -msave-reg-params | FileCheck -check-prefix=SAVE %s +// RUN: %clang_cc1 -triple powerpc-ibm-aix -emit-llvm -o - %s -msave-reg-params | FileCheck -check-prefix=SAVE %s +// RUN: %clang_cc1 -triple powerpc64-ibm-aix -emit-llvm -o - %s | FileCheck -check-prefix=NOSAVE %s +// RUN: %clang_cc1 -triple powerpc-ibm-aix -emit-llvm -o - %s | FileCheck -check-prefix=NOSAVE %s + +void bar(int); +void foo(int x) { bar(x); } + +// SAVE: attributes #{{[0-9]+}} = { {{.+}} "save-reg-params" {{.+}} } +// NOSAVE-NOT: "save-reg-params" diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vfncvt.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vfncvt.c index dcdfb7be46ad6..ba164258552fe 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vfncvt.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vfncvt.c @@ -327,55 +327,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4(vuint32m8_t src, size_t vl) { return __riscv_vfncvt_f_xu_w_f16m4(src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f16.nxv1f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4(vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf4(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f16.nxv2f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2(vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf2(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1(vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m1(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f16.nxv8f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2(vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m2(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv16f16.nxv16f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4(vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m4(src, vl); -} // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2 // CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { @@ -537,46 +488,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4(vuint64m8_t src, size_t vl) { return __riscv_vfncvt_f_xu_w_f32m4(src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f32.nxv1f64.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2(vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32mf2(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f32.nxv2f64.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1(vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m1(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f32.nxv4f64.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2(vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m2(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f32.nxv8f64.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4(vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m4(src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_m // CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -897,56 +808,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_m(vbool4_t mask, vuint32m8_t src, size_t v return __riscv_vfncvt_f_xu_w_f16m4_m(mask, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_m(vbool64_t mask, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf4_m(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_m(vbool32_t mask, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf2_m(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_m(vbool16_t mask, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m1_m(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_m(vbool8_t mask, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m2_m(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_m(vbool4_t mask, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m4_m(mask, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_m // CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1107,46 +968,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_m(vbool8_t mask, vuint64m8_t src, size_t v return __riscv_vfncvt_f_xu_w_f32m4_m(mask, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_m(vbool64_t mask, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32mf2_m(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_m(vbool32_t mask, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m1_m(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_m(vbool16_t mask, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m2_m(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_m(vbool8_t mask, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m4_m(mask, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_rm // CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1467,56 +1288,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_rm(vuint32m8_t src, size_t vl) { return __riscv_vfncvt_f_xu_w_f16m4_rm(src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f16.nxv1f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm(vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf4_rm(src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f16.nxv2f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm(vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf2_rm(src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm(vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m1_rm(src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f16.nxv8f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm(vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m2_rm(src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv16f16.nxv16f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm(vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m4_rm(src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_rm // CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1677,46 +1448,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_rm(vuint64m8_t src, size_t vl) { return __riscv_vfncvt_f_xu_w_f32m4_rm(src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f32.nxv1f64.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm(vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32mf2_rm(src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f32.nxv2f64.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm(vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m1_rm(src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f32.nxv4f64.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm(vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m2_rm(src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f32.nxv8f64.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm(vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m4_rm(src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_rm_m // CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -2037,56 +1768,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_rm_m(vbool4_t mask, vuint32m8_t src, size_ return __riscv_vfncvt_f_xu_w_f16m4_rm_m(mask, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_m(vbool64_t mask, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf4_rm_m(mask, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_m(vbool32_t mask, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf2_rm_m(mask, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_m(vbool16_t mask, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m1_rm_m(mask, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_m(vbool8_t mask, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m2_rm_m(mask, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_m(vbool4_t mask, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m4_rm_m(mask, src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_rm_m // CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -2247,43 +1928,3 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_rm_m(vbool8_t mask, vuint64m8_t src, size_ return __riscv_vfncvt_f_xu_w_f32m4_rm_m(mask, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_m(vbool64_t mask, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32mf2_rm_m(mask, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_m(vbool32_t mask, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m1_rm_m(mask, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_m(vbool16_t mask, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m2_rm_m(mask, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_m(vbool8_t mask, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m4_rm_m(mask, src, __RISCV_FRM_RNE, vl); -} - diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vfncvt_f_f.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vfncvt_f_f.c new file mode 100644 index 0000000000000..414e2bddedb6c --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vfncvt_f_f.c @@ -0,0 +1,369 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f16.nxv1f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4(vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf4(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f16.nxv2f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2(vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf2(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1(vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m1(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f16.nxv8f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2(vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m2(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv16f16.nxv16f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4(vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m4(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f32.nxv1f64.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2(vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32mf2(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f32.nxv2f64.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1(vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m1(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f32.nxv4f64.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2(vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m2(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f32.nxv8f64.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4(vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m4(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_m(vbool64_t mask, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf4_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_m(vbool32_t mask, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf2_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_m(vbool16_t mask, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m1_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_m(vbool8_t mask, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m2_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_m(vbool4_t mask, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m4_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_m(vbool64_t mask, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32mf2_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_m(vbool32_t mask, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m1_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_m(vbool16_t mask, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m2_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_m(vbool8_t mask, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m4_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f16.nxv1f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm(vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf4_rm(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f16.nxv2f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm(vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf2_rm(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm(vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m1_rm(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f16.nxv8f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm(vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m2_rm(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv16f16.nxv16f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm(vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m4_rm(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f32.nxv1f64.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm(vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32mf2_rm(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f32.nxv2f64.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm(vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m1_rm(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f32.nxv4f64.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm(vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m2_rm(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f32.nxv8f64.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm(vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m4_rm(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_m(vbool64_t mask, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf4_rm_m(mask, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_m(vbool32_t mask, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf2_rm_m(mask, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_m(vbool16_t mask, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m1_rm_m(mask, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_m(vbool8_t mask, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m2_rm_m(mask, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_m(vbool4_t mask, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m4_rm_m(mask, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_m(vbool64_t mask, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32mf2_rm_m(mask, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_m(vbool32_t mask, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m1_rm_m(mask, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_m(vbool16_t mask, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m2_rm_m(mask, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_m(vbool8_t mask, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m4_rm_m(mask, src, __RISCV_FRM_RNE, vl); +} + diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vfwcvt.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vfwcvt.c index 39e4e70edfaa8..98bdcc5fa030b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vfwcvt.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vfwcvt.c @@ -327,56 +327,6 @@ vfloat32m8_t test_vfwcvt_f_xu_v_f32m8(vuint16m4_t src, size_t vl) { return __riscv_vfwcvt_f_xu_v_f32m8(src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv1f32.nxv1f16.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2(vfloat16mf4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32mf2(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv2f32.nxv2f16.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfwcvt_f_f_v_f32m1(vfloat16mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m1(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f32.nxv4f16.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfwcvt_f_f_v_f32m2(vfloat16m1_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m2(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv8f32.nxv8f16.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfwcvt_f_f_v_f32m4(vfloat16m2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m4(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv16f32.nxv16f16.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m8_t test_vfwcvt_f_f_v_f32m8(vfloat16m4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m8(src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_x_f_v_i64m1 // CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -537,46 +487,6 @@ vfloat64m8_t test_vfwcvt_f_xu_v_f64m8(vuint32m4_t src, size_t vl) { return __riscv_vfwcvt_f_xu_v_f64m8(src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv1f64.nxv1f32.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m1_t test_vfwcvt_f_f_v_f64m1(vfloat32mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m1(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv2f64.nxv2f32.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m2_t test_vfwcvt_f_f_v_f64m2(vfloat32m1_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m2(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f64.nxv4f32.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m4_t test_vfwcvt_f_f_v_f64m4(vfloat32m2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m4(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv8f64.nxv8f32.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m8_t test_vfwcvt_f_f_v_f64m8(vfloat32m4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m8(src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_x_v_f16mf4_m // CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -897,56 +807,6 @@ vfloat32m8_t test_vfwcvt_f_xu_v_f32m8_m(vbool4_t mask, vuint16m4_t src, size_t v return __riscv_vfwcvt_f_xu_v_f32m8_m(mask, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f32.nxv1f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_m(vbool64_t mask, vfloat16mf4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32mf2_m(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f32.nxv2f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfwcvt_f_f_v_f32m1_m(vbool32_t mask, vfloat16mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m1_m(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f32.nxv4f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfwcvt_f_f_v_f32m2_m(vbool16_t mask, vfloat16m1_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m2_m(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f32.nxv8f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfwcvt_f_f_v_f32m4_m(vbool8_t mask, vfloat16m2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m4_m(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv16f32.nxv16f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m8_t test_vfwcvt_f_f_v_f32m8_m(vbool4_t mask, vfloat16m4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m8_m(mask, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_x_f_v_i64m1_m // CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1107,46 +967,6 @@ vfloat64m8_t test_vfwcvt_f_xu_v_f64m8_m(vbool8_t mask, vuint32m4_t src, size_t v return __riscv_vfwcvt_f_xu_v_f64m8_m(mask, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f64.nxv1f32.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m1_t test_vfwcvt_f_f_v_f64m1_m(vbool64_t mask, vfloat32mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m1_m(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f64.nxv2f32.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m2_t test_vfwcvt_f_f_v_f64m2_m(vbool32_t mask, vfloat32m1_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m2_m(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f64.nxv4f32.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m4_t test_vfwcvt_f_f_v_f64m4_m(vbool16_t mask, vfloat32m2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m4_m(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f64.nxv8f32.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m8_t test_vfwcvt_f_f_v_f64m8_m(vbool8_t mask, vfloat32m4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m8_m(mask, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_x_f_v_i32mf2_rm // CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vfwcvt_f_f.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vfwcvt_f_f.c new file mode 100644 index 0000000000000..5bff79780d926 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vfwcvt_f_f.c @@ -0,0 +1,188 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv1f32.nxv1f16.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2(vfloat16mf4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32mf2(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv2f32.nxv2f16.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfwcvt_f_f_v_f32m1(vfloat16mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m1(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f32.nxv4f16.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfwcvt_f_f_v_f32m2(vfloat16m1_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m2(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv8f32.nxv8f16.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfwcvt_f_f_v_f32m4(vfloat16m2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m4(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv16f32.nxv16f16.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfwcvt_f_f_v_f32m8(vfloat16m4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m8(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv1f64.nxv1f32.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfwcvt_f_f_v_f64m1(vfloat32mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m1(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv2f64.nxv2f32.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfwcvt_f_f_v_f64m2(vfloat32m1_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m2(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f64.nxv4f32.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfwcvt_f_f_v_f64m4(vfloat32m2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m4(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv8f64.nxv8f32.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfwcvt_f_f_v_f64m8(vfloat32m4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m8(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f32.nxv1f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_m(vbool64_t mask, vfloat16mf4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32mf2_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f32.nxv2f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfwcvt_f_f_v_f32m1_m(vbool32_t mask, vfloat16mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m1_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f32.nxv4f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfwcvt_f_f_v_f32m2_m(vbool16_t mask, vfloat16m1_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m2_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f32.nxv8f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfwcvt_f_f_v_f32m4_m(vbool8_t mask, vfloat16m2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m4_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv16f32.nxv16f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfwcvt_f_f_v_f32m8_m(vbool4_t mask, vfloat16m4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m8_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f64.nxv1f32.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfwcvt_f_f_v_f64m1_m(vbool64_t mask, vfloat32mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m1_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f64.nxv2f32.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfwcvt_f_f_v_f64m2_m(vbool32_t mask, vfloat32m1_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m2_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f64.nxv4f32.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfwcvt_f_f_v_f64m4_m(vbool16_t mask, vfloat32m2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m4_m(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f64.nxv8f32.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfwcvt_f_f_v_f64m8_m(vbool8_t mask, vfloat32m4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m8_m(mask, src, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vle16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vle16.c index d7abbd756b732..5fa1d8ccd2665 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vle16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vle16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vle16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vle16ff.c index 76b615ee0c04e..e72305a058d6f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vle16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vle16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxei16.c index 7c75172584e3d..7b19d8b8cfebf 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxei32.c index 87d241e0f4db2..fd018ceb27e91 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxei64.c index 288c4a6ba0ff6..fe0209c9112d0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxei8.c index ef40b006d9ffa..1517f44f3d46b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg2ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg2ei16.c index e28fe15b3e732..cb6e295971432 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg2ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg2ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg2ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg2ei32.c index ba04a70594012..07c906d7198ef 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg2ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg2ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg2ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg2ei64.c index 6852385f63cbb..4e258ce5625d5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg2ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg2ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg2ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg2ei8.c index e3fe02c416f04..98e33f136a1da 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg2ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg2ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg3ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg3ei16.c index 32c988dffa113..89a9bb51d9fbc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg3ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg3ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg3ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg3ei32.c index 43e430b83e8af..9346bd01e7956 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg3ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg3ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg3ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg3ei64.c index 23897e99620d7..0aa85eaf1f060 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg3ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg3ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg3ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg3ei8.c index 74bac5c5ccceb..fee229eb57599 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg3ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg3ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg4ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg4ei16.c index 68471decdceab..495b6a53a15d3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg4ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg4ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg4ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg4ei32.c index 974c3b1e2c2c1..a45577ececeb7 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg4ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg4ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg4ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg4ei64.c index 36434dac4e48b..a55a911046ec0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg4ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg4ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg4ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg4ei8.c index c965f450dcb90..492b4dbd572e9 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg4ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg4ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg5ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg5ei16.c index bb58f183afb48..4ae47c980f336 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg5ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg5ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg5ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg5ei32.c index 6c2ad98934b68..cee8f91a61187 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg5ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg5ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg5ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg5ei64.c index 5c39c277d446a..ed5a6971f0bc1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg5ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg5ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg5ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg5ei8.c index 044bc21bbffbc..acfdeae83af33 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg5ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg5ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg6ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg6ei16.c index 1e7b515423234..f3b173e97cf6e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg6ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg6ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg6ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg6ei32.c index 739a09830ac46..3cb1f7cda90f8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg6ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg6ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg6ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg6ei64.c index 9cb708221fca8..cc2a6e0f46dbf 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg6ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg6ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg6ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg6ei8.c index 0bdc3f486a9cf..91398673a642a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg6ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg6ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg7ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg7ei16.c index 1e89aefeadbb1..cb6e74a3510f3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg7ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg7ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg7ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg7ei32.c index 0545d6e4d81c0..8a8d02ef71627 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg7ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg7ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg7ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg7ei64.c index 804ab4eaa959e..fb1104ec684f5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg7ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg7ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg7ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg7ei8.c index bf35d15d22fd6..55888b21b15c4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg7ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg7ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg8ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg8ei16.c index a6c3abe09788a..aafe70020e095 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg8ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg8ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg8ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg8ei32.c index 9c289773fe239..8d22079a9f1f3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg8ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg8ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg8ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg8ei64.c index 1d1622b6314ad..52cc01095e4b9 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg8ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg8ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg8ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg8ei8.c index 314ea7021d517..f79da9ac5008b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg8ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vloxseg8ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlse16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlse16.c index 4df96f31fd211..10ecf902d414c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlse16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlse16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e16.c index 285d9981a65ce..0bc9ffe892437 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e16ff.c index 3bc95e0364362..c211aec2da58d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e32.c index f7e4999f8feb6..1905edc5e451e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e32ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e32ff.c index 822aec3394772..610d89e0785bd 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e32ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e32ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e64.c index 243d7458c3810..5db107d5ac8fa 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e64ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e64ff.c index 18c0a997503f1..672b74623cb7d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e64ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg2e64ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg3e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg3e16.c index 3083a75e28d6f..6b6ea48ac8987 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg3e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg3e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg3e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg3e16ff.c index b76598f0ba8b7..183ed065936f4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg3e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg3e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg4e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg4e16.c index 54e34a7291606..7dc4dc29cbc53 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg4e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg4e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg4e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg4e16ff.c index d4cc8767a2ec3..223513ef6d041 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg4e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg4e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg4e32ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg4e32ff.c index 17f8ecc876e64..2b2d578dbddae 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg4e32ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg4e32ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg5e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg5e16.c index ddeac49b5fac7..6c2a1300802b3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg5e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg5e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg5e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg5e16ff.c index 3eb6d2a623672..9a6e218270ec7 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg5e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg5e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg6e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg6e16.c index 2dccc5dcdca41..ae7141b522440 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg6e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg6e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg6e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg6e16ff.c index ba4c2ff12b8bb..3cf099ed8156c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg6e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg6e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg7e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg7e16.c index e793ae1fad418..d47291d956cb2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg7e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg7e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg7e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg7e16ff.c index e6d99bb2d40e1..5499c85228316 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg7e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg7e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg8e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg8e16.c index eeca3596a928d..f145ec75c1ef9 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg8e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg8e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg8e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg8e16ff.c index 3fa816e8c4754..6be6749b32c21 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg8e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlseg8e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg2e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg2e16.c index c05d1d3e06584..465e546f241d6 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg2e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg2e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg3e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg3e16.c index 02f55e960bd01..808271bc598ba 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg3e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg3e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg4e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg4e16.c index b8843db070310..75604bd2fab38 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg4e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg4e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg5e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg5e16.c index ec65b79092a33..81bc04cb5fc44 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg5e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg5e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg6e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg6e16.c index 1dea6fa39ee9e..3ddcba0de3c75 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg6e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg6e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg7e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg7e16.c index 9bf73d4b71ba5..b997240af861a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg7e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg7e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg8e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg8e16.c index 9d9ff88ef1945..ef40369807a0f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg8e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vlsseg8e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxei16.c index a426aa39d1094..8419892183de8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxei32.c index 7cc93d1a4dcc8..da42d627f7814 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxei64.c index 304a8837efa88..91bd6b3b8c8a9 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxei8.c index b279cd3018e2c..529a1124e9399 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg2ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg2ei16.c index 062db9ef80274..4e0413418e4eb 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg2ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg2ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg2ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg2ei32.c index af0f75c4a9362..79f5999130ae8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg2ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg2ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg2ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg2ei64.c index 64d0599ff9f65..155452e397699 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg2ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg2ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg2ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg2ei8.c index 5a33217ef34b2..bcfe6076afbc0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg2ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg2ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg3ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg3ei16.c index c985dd6456aac..70eb73aebb379 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg3ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg3ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg3ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg3ei32.c index f58be50bee18c..9b30ed74232fd 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg3ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg3ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg3ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg3ei64.c index e9fcd9638c0c0..083dc211f2fb4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg3ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg3ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg3ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg3ei8.c index 4d24b3e1dbaba..74a4f25b33b20 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg3ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg3ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg4ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg4ei16.c index 2c8f4013a4008..8f0d0763cac22 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg4ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg4ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg4ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg4ei32.c index 0b593f9f78312..3546a1462d911 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg4ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg4ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg4ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg4ei64.c index 03b2cee43b6e8..9a5ec01f8409f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg4ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg4ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg4ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg4ei8.c index 0428eb7bda333..1cae1cc1f50c0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg4ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg4ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg5ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg5ei16.c index eb5d743bca3c3..65b4782532c34 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg5ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg5ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg5ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg5ei32.c index c3329e1a150e3..a30f8931fbb07 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg5ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg5ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg5ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg5ei64.c index 16aedc6566138..26e385377beaa 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg5ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg5ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg5ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg5ei8.c index 1856a1044fb30..d46a3340d8767 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg5ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg5ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg6ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg6ei16.c index 7e2e8d631ccd3..a1d644c7c7160 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg6ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg6ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg6ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg6ei32.c index 1bb269900fbb2..1b25720c8e3e0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg6ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg6ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg6ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg6ei64.c index c98083af14403..ebb5cc36e380d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg6ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg6ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg6ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg6ei8.c index 8d5b3c08669bd..0295a956d14e4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg6ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg6ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg7ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg7ei16.c index d169faf7f12ad..219ee239cb22d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg7ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg7ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg7ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg7ei32.c index 0514e317680d7..a0595eddfbd71 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg7ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg7ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg7ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg7ei64.c index ac6660b5be089..56de99c4aa348 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg7ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg7ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg7ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg7ei8.c index 1d470393be971..87a5a07f34f25 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg7ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg7ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg8ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg8ei16.c index 2c4e1fd23dd47..0a6b6d11ed75e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg8ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg8ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg8ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg8ei32.c index fededc60f1680..cb882d3468898 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg8ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg8ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg8ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg8ei64.c index bd071394a216b..b0e7cfa57d5ea 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg8ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg8ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg8ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg8ei8.c index ebebfdd7eb3de..32a8d73f12084 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg8ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vluxseg8ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vmerge.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vmerge.c index c52402424a81b..fb41a07cccec0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vmerge.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vmerge.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vmv.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vmv.c index be668d8c5db90..c25719a80d4fb 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vmv.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vmv.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vreinterpret.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vreinterpret.c index d141adb8337b3..31c6d11af6712 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vreinterpret.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vreinterpret.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vse16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vse16.c index 738e8a9148035..ea4efc5f726cf 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vse16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vse16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxei16.c index 857df5bef7f59..4e19c562d99d0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxei32.c index 2aab1ef35c714..ec0c718684d6f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxei64.c index ce3dba93db6f9..a1874ca82db74 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxei8.c index e09a61edb38d2..bc152e6040360 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg2ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg2ei16.c index be3cf941d5822..f63c698f063bd 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg2ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg2ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg2ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg2ei32.c index 5e710a2fa3e7a..3e766f8535ad7 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg2ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg2ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg2ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg2ei64.c index 9444d32f8e8ca..a0f0c01596157 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg2ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg2ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg2ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg2ei8.c index eb10c05443ed1..79f5b2406ccb7 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg2ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg2ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg3ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg3ei16.c index dd23c3222605e..bacfb5fd74a26 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg3ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg3ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg3ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg3ei32.c index e2ecf97081aae..0de8d95294567 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg3ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg3ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg3ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg3ei64.c index ec42accf3555e..fe92e2e40780a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg3ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg3ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg3ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg3ei8.c index 2a7ca507e7b33..f09b7e376fcd8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg3ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg3ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg4ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg4ei16.c index 8fa5968a05360..66911b61480e6 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg4ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg4ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg4ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg4ei32.c index c5543eae848c8..08f6edbb08814 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg4ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg4ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg4ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg4ei64.c index 4618d9714b39f..9af14464edae2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg4ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg4ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg4ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg4ei8.c index c6caf517cbfbc..869b895a985c4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg4ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg4ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg5ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg5ei16.c index 3a56bae880c49..b6a7c654bf0e0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg5ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg5ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg5ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg5ei32.c index 1f7e4a268b235..284e57fcff355 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg5ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg5ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg5ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg5ei64.c index 224d32e156e96..bad29fc2482d1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg5ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg5ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg5ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg5ei8.c index c65e2aae8806a..224fd13603fb6 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg5ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg5ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg6ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg6ei16.c index 6785a1ce404db..1c014eef1dc17 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg6ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg6ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg6ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg6ei32.c index e7ca9997bdd21..dffed80c778e1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg6ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg6ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg6ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg6ei64.c index 6cdcd393e51c3..eba5fb2b152bd 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg6ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg6ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg6ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg6ei8.c index 56ae39a0ced73..68cb43a5af71d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg6ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg6ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg7ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg7ei16.c index 1ca056390d7b2..3a4dcc66ec93f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg7ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg7ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg7ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg7ei32.c index e9d93241baa0d..4b189864554ce 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg7ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg7ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg7ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg7ei64.c index 14b8537f9bbd7..d2ce965c8f193 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg7ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg7ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg7ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg7ei8.c index e9e25f61fa3e5..d4790b89a2085 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg7ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg7ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg8ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg8ei16.c index c1766d023d107..99ec694780004 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg8ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg8ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg8ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg8ei32.c index 69b69ea4fffab..8b0f21ec75ba2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg8ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg8ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg8ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg8ei64.c index abc4b8c9fc0ad..2d7aaf5930f4a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg8ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg8ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg8ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg8ei8.c index 63246b34ef375..cad9326b85319 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg8ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsoxseg8ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsse16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsse16.c index aa72848727211..72acf08cefa16 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsse16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsse16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg2e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg2e16.c index aa50433411cf2..a46fb29388366 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg2e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg2e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg3e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg3e16.c index 2bb662dcf0094..7810857321814 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg3e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg3e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg4e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg4e16.c index 64e2970bb7f85..d7ad5fe0795e3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg4e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg4e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg5e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg5e16.c index 5d9e05e721ad3..369729fef0251 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg5e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg5e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg6e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg6e16.c index 24f0a257aee01..cf4e6b2733f7d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg6e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg6e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg7e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg7e16.c index bbec658271543..c876fa50b25ca 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg7e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg7e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg8e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg8e16.c index dd14f3bf56f2e..a00514e87deab 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg8e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg8e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg2e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg2e16.c index 51840657fd62b..dd664ac51d0af 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg2e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg2e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg3e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg3e16.c index be91941218884..cc2622ecd5bf3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg3e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg3e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg4e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg4e16.c index 8943ab92113bd..c53efec7dfcd2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg4e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg4e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg5e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg5e16.c index 6d8c9d38e567a..5d37ba071baf4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg5e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg5e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg6e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg6e16.c index 71cc5d70e9fe8..cf5565c280a8f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg6e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg6e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg7e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg7e16.c index a5f0df94b00fa..f39e422693775 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg7e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg7e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg8e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg8e16.c index d13667b9dcf2e..d691d64fbcfd7 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg8e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vssseg8e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxei16.c index 27d0068dabacf..32c0fab691a2f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxei32.c index 502ea760d215a..b046612a2896c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxei64.c index dba856e29ec63..1a4ac1850a314 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxei8.c index 23fa635db59ee..92737c1fa4c6c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg2ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg2ei16.c index c0706dabf158b..fa283f8a6357b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg2ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg2ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg2ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg2ei32.c index 93c47d1eff81e..c5bef275632f1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg2ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg2ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg2ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg2ei64.c index 765b78b7aef0c..7da29bbc3ef8d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg2ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg2ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg2ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg2ei8.c index ef4a611335251..3ea283b974135 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg2ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg2ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg3ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg3ei16.c index 631d4f1700134..307b66473cd27 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg3ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg3ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg3ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg3ei32.c index 711ea8cc8362d..a402734ff7849 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg3ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg3ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg3ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg3ei64.c index c87cf5c2e27f8..5771a4aab78ff 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg3ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg3ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg3ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg3ei8.c index c6710598d3cff..ffd6405c09fec 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg3ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg3ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg4ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg4ei16.c index e4725f291adf2..f1ddac3211bde 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg4ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg4ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg4ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg4ei32.c index dc569b840941b..58e32a6f30601 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg4ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg4ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg4ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg4ei64.c index e0a9f4569c5df..74b2b929d50c7 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg4ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg4ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg4ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg4ei8.c index 93f5ab1998088..ef4f4ef0ffb29 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg4ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg4ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg5ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg5ei16.c index 4574e1cf354a1..44cb1e9a9a812 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg5ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg5ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg5ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg5ei32.c index 6244a4f0c3832..e689873bf43f9 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg5ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg5ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg5ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg5ei64.c index 3a92dcfc577c7..c5d0dd1b76bc2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg5ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg5ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg5ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg5ei8.c index 0980a91d69021..3bad6de8b12fb 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg5ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg5ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg6ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg6ei16.c index abd8be607ff6b..cda0d96d04b82 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg6ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg6ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg6ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg6ei32.c index e58d76a46c0b4..f84d6e46f7e3d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg6ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg6ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg6ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg6ei64.c index 125be14dab509..e3b07df9bfc51 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg6ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg6ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg6ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg6ei8.c index a401f305d6cdc..c24145ac7be67 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg6ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg6ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg7ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg7ei16.c index 8df81d192619e..f452ce75de724 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg7ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg7ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg7ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg7ei32.c index 43f5dd46a284e..44fd0c9803085 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg7ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg7ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg7ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg7ei64.c index 369f3c0cd73b0..78df8958be7c0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg7ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg7ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg7ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg7ei8.c index 59242eb71a33b..7fa707b5c4682 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg7ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg7ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg8ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg8ei16.c index 6e892339dafd2..28f4623f39620 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg8ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg8ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg8ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg8ei32.c index 0f40c87648d07..8b8a12c63d8c3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg8ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg8ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg8ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg8ei64.c index 708204fced65c..ce2704f913e5c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg8ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg8ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg8ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg8ei8.c index 5719ffea7335d..bd61169c84ed5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg8ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsuxseg8ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vfncvt.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vfncvt.c index a62dd2e054542..10eb4ea7d1238 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vfncvt.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vfncvt.c @@ -327,56 +327,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4(vuint32m8_t src, size_t vl) { return __riscv_vfncvt_f(src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f16.nxv1f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4(vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f16.nxv2f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2(vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1(vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f16.nxv8f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2(vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv16f16.nxv16f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4(vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f(src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2 // CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -537,46 +487,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4(vuint64m8_t src, size_t vl) { return __riscv_vfncvt_f(src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f32.nxv1f64.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2(vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f32.nxv2f64.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1(vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f32.nxv4f64.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2(vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f32.nxv8f64.i64( poison, [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4(vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f(src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_m // CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -897,56 +807,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_m(vbool4_t mask, vuint32m8_t src, size_t v return __riscv_vfncvt_f(mask, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_m(vbool64_t mask, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_m(vbool32_t mask, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_m(vbool16_t mask, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_m(vbool8_t mask, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_m(vbool4_t mask, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_m // CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1107,46 +967,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_m(vbool8_t mask, vuint64m8_t src, size_t v return __riscv_vfncvt_f(mask, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_m(vbool64_t mask, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_m(vbool32_t mask, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_m(vbool16_t mask, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_m(vbool8_t mask, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_rm // CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1467,56 +1287,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_rm(vuint32m8_t src, size_t vl) { return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f16.nxv1f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm(vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f16.nxv2f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm(vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm(vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f16.nxv8f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm(vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv16f16.nxv16f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm(vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_rm // CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1677,46 +1447,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_rm(vuint64m8_t src, size_t vl) { return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f32.nxv1f64.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm(vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f32.nxv2f64.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm(vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f32.nxv4f64.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm(vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f32.nxv8f64.i64( poison, [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm(vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_rm_m // CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -2037,56 +1767,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_rm_m(vbool4_t mask, vuint32m8_t src, size_ return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_m(vbool64_t mask, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_m(vbool32_t mask, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_m(vbool16_t mask, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_m(vbool8_t mask, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_m(vbool4_t mask, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_rm_m // CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -2247,43 +1927,3 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_rm_m(vbool8_t mask, vuint64m8_t src, size_ return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_m(vbool64_t mask, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_m(vbool32_t mask, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_m(vbool16_t mask, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_m(vbool8_t mask, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); -} - diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vfncvt_f_f.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vfncvt_f_f.c new file mode 100644 index 0000000000000..2c017d5fccac6 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vfncvt_f_f.c @@ -0,0 +1,369 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f16.nxv1f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4(vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f16.nxv2f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2(vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1(vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f16.nxv8f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2(vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv16f16.nxv16f32.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4(vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f32.nxv1f64.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2(vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f32.nxv2f64.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1(vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f32.nxv4f64.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2(vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f32.nxv8f64.i64( poison, [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4(vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_m(vbool64_t mask, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_m(vbool32_t mask, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_m(vbool16_t mask, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_m(vbool8_t mask, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_m(vbool4_t mask, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_m(vbool64_t mask, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_m(vbool32_t mask, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_m(vbool16_t mask, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( poison, [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_m(vbool8_t mask, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f16.nxv1f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm(vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f16.nxv2f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm(vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm(vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f16.nxv8f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm(vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv16f16.nxv16f32.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm(vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f32.nxv1f64.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm(vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f32.nxv2f64.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm(vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f32.nxv4f64.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm(vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f32.nxv8f64.i64( poison, [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm(vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f(src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_m(vbool64_t mask, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_m(vbool32_t mask, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_m(vbool16_t mask, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_m(vbool8_t mask, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_m(vbool4_t mask, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_m(vbool64_t mask, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_m(vbool32_t mask, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_m(vbool16_t mask, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( poison, [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_m(vbool8_t mask, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f(mask, src, __RISCV_FRM_RNE, vl); +} + diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vfwcvt.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vfwcvt.c index f59f986b7ad44..4dcab0dc956d3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vfwcvt.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vfwcvt.c @@ -327,56 +327,6 @@ vfloat32m8_t test_vfwcvt_f_xu_v_f32m8(vuint16m4_t src, size_t vl) { return __riscv_vfwcvt_f(src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv1f32.nxv1f16.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2(vfloat16mf4_t src, size_t vl) { - return __riscv_vfwcvt_f(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv2f32.nxv2f16.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfwcvt_f_f_v_f32m1(vfloat16mf2_t src, size_t vl) { - return __riscv_vfwcvt_f(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f32.nxv4f16.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfwcvt_f_f_v_f32m2(vfloat16m1_t src, size_t vl) { - return __riscv_vfwcvt_f(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv8f32.nxv8f16.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfwcvt_f_f_v_f32m4(vfloat16m2_t src, size_t vl) { - return __riscv_vfwcvt_f(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv16f32.nxv16f16.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m8_t test_vfwcvt_f_f_v_f32m8(vfloat16m4_t src, size_t vl) { - return __riscv_vfwcvt_f(src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_x_f_v_i64m1 // CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -537,46 +487,6 @@ vfloat64m8_t test_vfwcvt_f_xu_v_f64m8(vuint32m4_t src, size_t vl) { return __riscv_vfwcvt_f(src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv1f64.nxv1f32.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m1_t test_vfwcvt_f_f_v_f64m1(vfloat32mf2_t src, size_t vl) { - return __riscv_vfwcvt_f(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv2f64.nxv2f32.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m2_t test_vfwcvt_f_f_v_f64m2(vfloat32m1_t src, size_t vl) { - return __riscv_vfwcvt_f(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f64.nxv4f32.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m4_t test_vfwcvt_f_f_v_f64m4(vfloat32m2_t src, size_t vl) { - return __riscv_vfwcvt_f(src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8 -// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv8f64.nxv8f32.i64( poison, [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m8_t test_vfwcvt_f_f_v_f64m8(vfloat32m4_t src, size_t vl) { - return __riscv_vfwcvt_f(src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_x_v_f16mf4_m // CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -897,56 +807,6 @@ vfloat32m8_t test_vfwcvt_f_xu_v_f32m8_m(vbool4_t mask, vuint16m4_t src, size_t v return __riscv_vfwcvt_f(mask, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f32.nxv1f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_m(vbool64_t mask, vfloat16mf4_t src, size_t vl) { - return __riscv_vfwcvt_f(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f32.nxv2f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfwcvt_f_f_v_f32m1_m(vbool32_t mask, vfloat16mf2_t src, size_t vl) { - return __riscv_vfwcvt_f(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f32.nxv4f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfwcvt_f_f_v_f32m2_m(vbool16_t mask, vfloat16m1_t src, size_t vl) { - return __riscv_vfwcvt_f(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f32.nxv8f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfwcvt_f_f_v_f32m4_m(vbool8_t mask, vfloat16m2_t src, size_t vl) { - return __riscv_vfwcvt_f(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv16f32.nxv16f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m8_t test_vfwcvt_f_f_v_f32m8_m(vbool4_t mask, vfloat16m4_t src, size_t vl) { - return __riscv_vfwcvt_f(mask, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_x_f_v_i64m1_m // CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1107,46 +967,6 @@ vfloat64m8_t test_vfwcvt_f_xu_v_f64m8_m(vbool8_t mask, vuint32m4_t src, size_t v return __riscv_vfwcvt_f(mask, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f64.nxv1f32.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m1_t test_vfwcvt_f_f_v_f64m1_m(vbool64_t mask, vfloat32mf2_t src, size_t vl) { - return __riscv_vfwcvt_f(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f64.nxv2f32.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m2_t test_vfwcvt_f_f_v_f64m2_m(vbool32_t mask, vfloat32m1_t src, size_t vl) { - return __riscv_vfwcvt_f(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f64.nxv4f32.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m4_t test_vfwcvt_f_f_v_f64m4_m(vbool16_t mask, vfloat32m2_t src, size_t vl) { - return __riscv_vfwcvt_f(mask, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_m -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f64.nxv8f32.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m8_t test_vfwcvt_f_f_v_f64m8_m(vbool8_t mask, vfloat32m4_t src, size_t vl) { - return __riscv_vfwcvt_f(mask, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_x_f_v_i32mf2_rm // CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vfwcvt_f_f.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vfwcvt_f_f.c new file mode 100644 index 0000000000000..96825ff3ab73d --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vfwcvt_f_f.c @@ -0,0 +1,188 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv1f32.nxv1f16.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2(vfloat16mf4_t src, size_t vl) { + return __riscv_vfwcvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv2f32.nxv2f16.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfwcvt_f_f_v_f32m1(vfloat16mf2_t src, size_t vl) { + return __riscv_vfwcvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f32.nxv4f16.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfwcvt_f_f_v_f32m2(vfloat16m1_t src, size_t vl) { + return __riscv_vfwcvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv8f32.nxv8f16.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfwcvt_f_f_v_f32m4(vfloat16m2_t src, size_t vl) { + return __riscv_vfwcvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv16f32.nxv16f16.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfwcvt_f_f_v_f32m8(vfloat16m4_t src, size_t vl) { + return __riscv_vfwcvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv1f64.nxv1f32.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfwcvt_f_f_v_f64m1(vfloat32mf2_t src, size_t vl) { + return __riscv_vfwcvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv2f64.nxv2f32.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfwcvt_f_f_v_f64m2(vfloat32m1_t src, size_t vl) { + return __riscv_vfwcvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f64.nxv4f32.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfwcvt_f_f_v_f64m4(vfloat32m2_t src, size_t vl) { + return __riscv_vfwcvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8 +// CHECK-RV64-SAME: ( [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv8f64.nxv8f32.i64( poison, [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfwcvt_f_f_v_f64m8(vfloat32m4_t src, size_t vl) { + return __riscv_vfwcvt_f(src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f32.nxv1f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_m(vbool64_t mask, vfloat16mf4_t src, size_t vl) { + return __riscv_vfwcvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f32.nxv2f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfwcvt_f_f_v_f32m1_m(vbool32_t mask, vfloat16mf2_t src, size_t vl) { + return __riscv_vfwcvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f32.nxv4f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfwcvt_f_f_v_f32m2_m(vbool16_t mask, vfloat16m1_t src, size_t vl) { + return __riscv_vfwcvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f32.nxv8f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfwcvt_f_f_v_f32m4_m(vbool8_t mask, vfloat16m2_t src, size_t vl) { + return __riscv_vfwcvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv16f32.nxv16f16.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfwcvt_f_f_v_f32m8_m(vbool4_t mask, vfloat16m4_t src, size_t vl) { + return __riscv_vfwcvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f64.nxv1f32.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfwcvt_f_f_v_f64m1_m(vbool64_t mask, vfloat32mf2_t src, size_t vl) { + return __riscv_vfwcvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f64.nxv2f32.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfwcvt_f_f_v_f64m2_m(vbool32_t mask, vfloat32m1_t src, size_t vl) { + return __riscv_vfwcvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f64.nxv4f32.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfwcvt_f_f_v_f64m4_m(vbool16_t mask, vfloat32m2_t src, size_t vl) { + return __riscv_vfwcvt_f(mask, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_m +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f64.nxv8f32.i64( poison, [[SRC]], [[MASK]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfwcvt_f_f_v_f64m8_m(vbool8_t mask, vfloat32m4_t src, size_t vl) { + return __riscv_vfwcvt_f(mask, src, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vle16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vle16.c index e6b9b12966859..2619ab270ff3a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vle16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vle16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vle16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vle16ff.c index d2a9819a10677..7b56c07da07d6 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vle16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vle16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxei16.c index 5fadd983f6225..1e844dc531ee2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxei32.c index b4a3d98694d20..8e5bf2f7db245 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxei64.c index 34ab499f78bf5..57b945e01293d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxei8.c index 4b1a0b4a96936..3d330b38dbd10 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg2ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg2ei16.c index bdd448a2e7aba..3a7f583b5967a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg2ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg2ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg2ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg2ei32.c index 801ad6f4fd45d..c7d9ec9044564 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg2ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg2ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg2ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg2ei64.c index 539c0733e827a..ab973072be3bb 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg2ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg2ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg2ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg2ei8.c index 602c6e9552686..02f11042afc65 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg2ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg2ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg3ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg3ei16.c index 892d2e39be380..f7061b87281c8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg3ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg3ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg3ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg3ei32.c index 3137ed3abe3e0..aee251a1b3e14 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg3ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg3ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg3ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg3ei64.c index 1abcc1f7d35b9..b440267822dd0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg3ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg3ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg3ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg3ei8.c index 0fbe8a38406a8..c322762102908 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg3ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg3ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg4ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg4ei16.c index 86250ece1cf5a..9c6420d484c61 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg4ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg4ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg4ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg4ei32.c index 20e998f2921a9..9812f060fa39e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg4ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg4ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg4ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg4ei64.c index 5d23db26f4d48..8f0a8e54ba075 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg4ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg4ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg4ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg4ei8.c index f772f190030b0..0e07251576351 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg4ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg4ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg5ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg5ei16.c index 5df3d1597ca20..66b8916772e7e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg5ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg5ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg5ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg5ei32.c index 5ffde2352624e..edd5aaaaddbf5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg5ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg5ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg5ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg5ei64.c index 1312733533b49..5bf228fbbe390 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg5ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg5ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg5ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg5ei8.c index a0de00862d4db..e5ee08be86d79 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg5ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg5ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg6ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg6ei16.c index 0a183183b8989..d4e92cd0b898d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg6ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg6ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg6ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg6ei32.c index 108bed88cd9a5..3f42dfdbf12c9 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg6ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg6ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg6ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg6ei64.c index 42d4b1af039e4..22f0cbd3a88c2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg6ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg6ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg6ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg6ei8.c index 69a0e9ede8be7..5f05d592748ab 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg6ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg6ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg7ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg7ei16.c index b0b14540340f6..976321790fc08 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg7ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg7ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg7ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg7ei32.c index 604dcd84cb05c..275f12f8ab401 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg7ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg7ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg7ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg7ei64.c index e30f8018c05bf..cf25c8daed08d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg7ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg7ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg7ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg7ei8.c index 62b602ae6a81c..09a3cc183768e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg7ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg7ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg8ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg8ei16.c index a691eaf564a6e..b478d96d6a247 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg8ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg8ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg8ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg8ei32.c index 608b2457b3ecd..07e93052d056b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg8ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg8ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg8ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg8ei64.c index 14b94cde4be7c..c95bab7c8b865 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg8ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg8ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg8ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg8ei8.c index 2e2eb03c941d7..25fb1cbb07390 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg8ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vloxseg8ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlse16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlse16.c index f2aba9a6b2849..4fdb4045769b4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlse16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlse16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg2e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg2e16.c index 4eb2c7102dbcf..8eb78f9c2a833 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg2e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg2e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg2e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg2e16ff.c index a3d0d595736ff..975ea0865e14c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg2e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg2e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg3e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg3e16.c index 036dd8b855ac3..6915855fa438f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg3e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg3e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg3e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg3e16ff.c index 57635694d5d3f..94ece8d731414 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg3e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg3e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg4e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg4e16.c index 39a64d0e0066b..96da31eef0822 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg4e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg4e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg4e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg4e16ff.c index 9017f5951b56f..6faee625460a7 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg4e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg4e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg5e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg5e16.c index fdd31c3b3fa77..998905b8eecb9 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg5e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg5e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg5e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg5e16ff.c index 9bc3c2659a1ff..fd2b398629bff 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg5e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg5e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg6e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg6e16.c index 511a9495cb113..57c4cff6a85c3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg6e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg6e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg6e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg6e16ff.c index 8057b94b49b37..cfeb725c1e690 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg6e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg6e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg7e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg7e16.c index 14a521e3d9d25..8ffff51bd2f36 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg7e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg7e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg7e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg7e16ff.c index b4e94e31ecf13..31da9fa31b3bc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg7e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg7e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg8e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg8e16.c index 5a35fc6d59b8a..4d229ac49f6e8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg8e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg8e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg8e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg8e16ff.c index 54e325286e459..c5dc4cff8a7b2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg8e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlseg8e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg2e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg2e16.c index 9d23e742d0d64..2e22f0e731174 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg2e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg2e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg3e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg3e16.c index bd59dd6c1eef1..e8cb448459545 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg3e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg3e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg4e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg4e16.c index 44a65ac07b598..ec6ec2a9cd111 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg4e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg4e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg5e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg5e16.c index 654fd18fcf0d3..6e77e24991af0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg5e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg5e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg6e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg6e16.c index 8a2d8e063695e..c1b97a8ed6cbc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg6e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg6e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg7e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg7e16.c index 2bbffe0f33301..3b7894b75a1d5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg7e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg7e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg8e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg8e16.c index e5b67749fa0ef..1eb13dffe1c37 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg8e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vlsseg8e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxei16.c index 15d2379cb769d..59820e5572b20 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxei32.c index 6e6f472d13b92..3697e0d7014dc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxei64.c index fb3adb4a56518..e794888b7c73b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxei8.c index c2337ed01b298..853a7adb6c478 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg2ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg2ei16.c index f85a4d21e0d80..2d7400a03629e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg2ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg2ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg2ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg2ei32.c index 05b82b50b41e9..e8a933a9e3edf 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg2ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg2ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg2ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg2ei64.c index f2b86dc6cf0ac..7537868b10d9d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg2ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg2ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg2ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg2ei8.c index f215f7c06be09..bcb378288e99d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg2ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg2ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg3ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg3ei16.c index bd01e4a26ef42..2618904bda3ba 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg3ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg3ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg3ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg3ei32.c index d1e29f62400bc..37de7d3d9ab6e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg3ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg3ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg3ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg3ei64.c index f1aa76a9910d8..9c6120d546cbe 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg3ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg3ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg3ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg3ei8.c index 32cf171063f4e..5a7f1657a2a3a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg3ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg3ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg4ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg4ei16.c index f51854479df0c..bbb64b057781e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg4ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg4ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg4ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg4ei32.c index 0002ed1f54bf0..68a12760e8c86 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg4ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg4ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg4ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg4ei64.c index e0936fb0e3f7c..1cf8074143ee3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg4ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg4ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg4ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg4ei8.c index c6448978d08cc..1c8273f71797b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg4ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg4ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg5ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg5ei16.c index e86e80aad18ba..a45981209d449 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg5ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg5ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg5ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg5ei32.c index f6280c9315ac7..58f9f8f1377bb 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg5ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg5ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg5ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg5ei64.c index fc5ab22010d20..256fd9f6b181d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg5ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg5ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg5ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg5ei8.c index 7973a137e411a..9cbbe4ba0fe73 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg5ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg5ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg6ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg6ei16.c index a91e920113b4d..051627ce134c9 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg6ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg6ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg6ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg6ei32.c index 7e7324f1aa41f..d5321b8570a63 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg6ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg6ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg6ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg6ei64.c index fc248bce9165c..30e9944c30365 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg6ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg6ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg6ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg6ei8.c index e78ccf41101d2..1e15ab2b9c0a7 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg6ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg6ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg7ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg7ei16.c index 4337a97d5a129..1acf7e77c1ee2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg7ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg7ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg7ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg7ei32.c index 78609f0473205..4721c74f6699b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg7ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg7ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg7ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg7ei64.c index 002178b126130..f69c4a40c23f9 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg7ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg7ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg7ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg7ei8.c index 882ad94a1dec6..f950650cc3c2f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg7ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg7ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg8ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg8ei16.c index 42a01fdf73374..b1b60e5894f36 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg8ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg8ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg8ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg8ei32.c index 02591e137c960..6278d5ef47844 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg8ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg8ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg8ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg8ei64.c index 9ee2585b02a54..d35e436110942 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg8ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg8ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg8ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg8ei8.c index c9536929512d4..9592ecd4a5e25 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg8ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vluxseg8ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vmerge.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vmerge.c index 2ed27e6d7b467..d67aa70fc8c8a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vmerge.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vmerge.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vmv.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vmv.c index ffd6f7dc4f577..44f34c4fe8101 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vmv.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vmv.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vreinterpret.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vreinterpret.c index e1af8ba146562..0c33d509114df 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vreinterpret.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vreinterpret.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vse16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vse16.c index 3cb965b826840..6d15de10bdf46 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vse16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vse16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxei16.c index 1986cc90727d4..0ea2fa60849b1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxei32.c index b414a5a36d308..e79d8c592a673 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxei64.c index ba1a6dbf7edaa..a238c56f45542 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxei8.c index 8295692189bb9..8c4805270440c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg2ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg2ei16.c index 4c4c1b3aa2d6b..53d203ba5202b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg2ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg2ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg2ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg2ei32.c index c77eb7ea794aa..16e4e2b045877 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg2ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg2ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg2ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg2ei64.c index 066f844c40d70..b852fd81eb4ff 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg2ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg2ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg2ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg2ei8.c index fe8f137556acb..69abe299351ac 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg2ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg2ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg3ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg3ei16.c index e6df42969f01a..db106d7e31ffe 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg3ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg3ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg3ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg3ei32.c index 5e4b7c1123a8a..23976cdac17b6 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg3ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg3ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg3ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg3ei64.c index 8b70ad11aed26..7a1c4a5260944 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg3ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg3ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg3ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg3ei8.c index dbcb1a9d24542..b8fd905d9ae83 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg3ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg3ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg4ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg4ei16.c index c891f1ecabf07..201b0e38655a1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg4ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg4ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg4ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg4ei32.c index fcfc94dcf9dd3..70ac9357a2dfc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg4ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg4ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg4ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg4ei64.c index 2631aed62911f..c0255f3ce6735 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg4ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg4ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg4ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg4ei8.c index 43353a9a8f4af..27a4a520335a4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg4ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg4ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg5ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg5ei16.c index 751d564fcfe4c..99a2ad5085c48 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg5ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg5ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg5ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg5ei32.c index cac2ac580eb66..e6a39b48889dd 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg5ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg5ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg5ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg5ei64.c index 5db0e8f43aa4b..867758cdfe351 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg5ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg5ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg5ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg5ei8.c index 878a396be458f..80b60b3b59353 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg5ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg5ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg6ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg6ei16.c index 25d812a4dcb29..5f6728ec93de0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg6ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg6ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg6ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg6ei32.c index 2cef48221a471..690ea92cbd7f4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg6ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg6ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg6ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg6ei64.c index e418542898761..9aa6577fcc9ee 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg6ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg6ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg6ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg6ei8.c index 3f62203eb682a..580464506d46e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg6ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg6ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg7ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg7ei16.c index 77f4ef8f62a5c..2931707e2489d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg7ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg7ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg7ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg7ei32.c index c37268c32160b..ea0d8b47c4001 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg7ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg7ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg7ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg7ei64.c index b0748812dae74..9144bc14042e4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg7ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg7ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg7ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg7ei8.c index e978b6c1654b7..9548a2abf245c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg7ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg7ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg8ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg8ei16.c index 385719ae80b95..9b68352389aa6 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg8ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg8ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg8ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg8ei32.c index c8d7df8791918..6ae6c2d62420b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg8ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg8ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg8ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg8ei64.c index 3aec2a1c30d4d..bc36d126d92df 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg8ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg8ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg8ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg8ei8.c index 2c6ceee55c49c..f52c91bdc6649 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg8ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsoxseg8ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsse16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsse16.c index c1c1dd465a864..576d8df491b36 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsse16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsse16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg2e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg2e16.c index 495c8536001c8..fc09cfd4bf781 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg2e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg2e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg3e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg3e16.c index 83889bc693ec6..8aa890eb4ee2d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg3e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg3e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg4e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg4e16.c index 4f3d79d6941a2..692cb8f46e3a5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg4e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg4e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg5e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg5e16.c index 73db6a6f10e20..ec51aa19c7155 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg5e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg5e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg6e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg6e16.c index ea7115567c36e..4c790d52ff46e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg6e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg6e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg7e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg7e16.c index 3a4248a6e86f6..6ac7c800b6f8c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg7e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg7e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg8e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg8e16.c index eb31c335b3228..3778d499d2f6f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg8e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsseg8e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg2e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg2e16.c index e379891e43759..fc58882b568e5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg2e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg2e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg3e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg3e16.c index ccb28e126e757..1d17d93318327 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg3e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg3e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg4e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg4e16.c index de3fc0718f252..c4731e71b6fbc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg4e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg4e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg5e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg5e16.c index 5143b7bbcd69a..1b254aba03291 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg5e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg5e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg6e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg6e16.c index 2fdef1570a3c7..c094f08e38375 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg6e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg6e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg7e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg7e16.c index 9f3f007e6d066..4f8c7fad1c1dc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg7e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg7e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg8e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg8e16.c index 992b84da5ba1f..8c89dfa0a818e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg8e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vssseg8e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxei16.c index 42dd207d78a39..2d38a79950829 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxei32.c index 09f6cdf3dc66c..e0ca634229712 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxei64.c index 1f897a1b2e6f9..819fa8af5affb 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxei8.c index 79d49fef32de4..23386d7ce3919 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg2ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg2ei16.c index 3f9a46069dc4e..42684da49e62c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg2ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg2ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg2ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg2ei32.c index b9b7798f36a73..bb329086b5af0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg2ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg2ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg2ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg2ei64.c index a5fd03f1e47f7..b79fd032f9ba8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg2ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg2ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg2ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg2ei8.c index f9da66db4a52b..1292fd91a1ab1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg2ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg2ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg3ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg3ei16.c index b4b830694e83b..aba54c0887ef8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg3ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg3ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg3ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg3ei32.c index 196b404da034b..c2d6fee7e279a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg3ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg3ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg3ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg3ei64.c index d42924709a5dd..52c2438cac544 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg3ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg3ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg3ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg3ei8.c index f7046b11aaae4..398f9d6ba1e42 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg3ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg3ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg4ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg4ei16.c index 853612483ff3f..b5ae454ef843f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg4ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg4ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg4ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg4ei32.c index ad2f062c0d0f7..7ea185ba9fe90 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg4ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg4ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg4ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg4ei64.c index 245b9041e64fb..b6e4aa5ac1fcd 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg4ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg4ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg4ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg4ei8.c index 16334f8d4f7bc..037630051d405 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg4ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg4ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg5ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg5ei16.c index 2c001f00436ed..f7d9682853512 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg5ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg5ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg5ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg5ei32.c index fab54bfe517b2..067d7c5431aff 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg5ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg5ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg5ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg5ei64.c index 08fee857416a0..5f7c0ce93952d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg5ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg5ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg5ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg5ei8.c index 43cdd093d73fd..20535e664b05d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg5ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg5ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg6ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg6ei16.c index 8e8788272ddf5..7eb59526a55dc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg6ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg6ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg6ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg6ei32.c index 3255a5ca32606..c8b7caa75aaa8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg6ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg6ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg6ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg6ei64.c index 6ea66a6f7d5be..6f0b838651336 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg6ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg6ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg6ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg6ei8.c index 671014b152540..8a2c64c38a3fc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg6ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg6ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg7ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg7ei16.c index 66ec251fff8f9..0b347cf8513e8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg7ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg7ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg7ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg7ei32.c index b6d35f5080298..d8270260a1c9b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg7ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg7ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg7ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg7ei64.c index c8bf3c372c8e1..68916f17747a9 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg7ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg7ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg7ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg7ei8.c index c527a7231f3a3..3b4f8af16ffc5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg7ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg7ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg8ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg8ei16.c index 52c7a8f067ad1..f11b5911c305b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg8ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg8ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg8ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg8ei32.c index ccb43829631b3..be8993a1990dc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg8ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg8ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg8ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg8ei64.c index c71edaaad735d..47e12eea323a8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg8ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg8ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg8ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg8ei8.c index b025649ef2cff..c9f70e2ae96a0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg8ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsuxseg8ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vfncvt.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vfncvt.c index e52e5b592d3f6..cd2f074f74b98 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vfncvt.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vfncvt.c @@ -327,56 +327,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_tu(vfloat16m4_t maskedoff, vuint32m8_t src return __riscv_vfncvt_f_xu_w_f16m4_tu(maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_tu(vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf4_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_tu(vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf2_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_tu(vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m1_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_tu(vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m2_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_tu(vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m4_tu(maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_tu // CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -537,46 +487,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_tu(vfloat32m4_t maskedoff, vuint64m8_t src return __riscv_vfncvt_f_xu_w_f32m4_tu(maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_tu(vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32mf2_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_tu(vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m1_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_tu(vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m2_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_tu(vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m4_tu(maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_tum // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -897,56 +807,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_tum(vbool4_t mask, vfloat16m4_t maskedoff, return __riscv_vfncvt_f_xu_w_f16m4_tum(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_tum(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf4_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_tum(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf2_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_tum(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m1_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_tum(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m2_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_tum(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m4_tum(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_tum // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1107,46 +967,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_tum(vbool8_t mask, vfloat32m4_t maskedoff, return __riscv_vfncvt_f_xu_w_f32m4_tum(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_tum(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32mf2_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_tum(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m1_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_tum(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m2_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_tum(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m4_tum(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_tumu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1467,56 +1287,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_tumu(vbool4_t mask, vfloat16m4_t maskedoff return __riscv_vfncvt_f_xu_w_f16m4_tumu(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_tumu(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf4_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_tumu(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf2_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_tumu(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m1_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_tumu(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m2_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_tumu(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m4_tumu(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_tumu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1677,46 +1447,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_tumu(vbool8_t mask, vfloat32m4_t maskedoff return __riscv_vfncvt_f_xu_w_f32m4_tumu(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_tumu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32mf2_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_tumu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m1_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_tumu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m2_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_tumu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m4_tumu(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_mu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -2037,56 +1767,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_mu(vbool4_t mask, vfloat16m4_t maskedoff, return __riscv_vfncvt_f_xu_w_f16m4_mu(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_mu(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf4_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_mu(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf2_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_mu(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m1_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_mu(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m2_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_mu(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m4_mu(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_mu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -2247,46 +1927,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_mu(vbool8_t mask, vfloat32m4_t maskedoff, return __riscv_vfncvt_f_xu_w_f32m4_mu(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_mu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32mf2_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_mu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m1_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_mu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m2_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_mu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m4_mu(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_rm_tu // CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -2607,56 +2247,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_rm_tu(vfloat16m4_t maskedoff, vuint32m8_t return __riscv_vfncvt_f_xu_w_f16m4_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_tu(vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf4_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_tu(vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf2_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_tu(vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m1_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_tu(vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m2_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_tu(vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m4_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_rm_tu // CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -2817,46 +2407,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_rm_tu(vfloat32m4_t maskedoff, vuint64m8_t return __riscv_vfncvt_f_xu_w_f32m4_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_tu(vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32mf2_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_tu(vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m1_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_tu(vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m2_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_tu(vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m4_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_rm_tum // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -3177,56 +2727,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_rm_tum(vbool4_t mask, vfloat16m4_t maskedo return __riscv_vfncvt_f_xu_w_f16m4_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_tum(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf4_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_tum(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf2_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_tum(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m1_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_tum(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m2_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_tum(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m4_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_rm_tum // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -3387,46 +2887,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_rm_tum(vbool8_t mask, vfloat32m4_t maskedo return __riscv_vfncvt_f_xu_w_f32m4_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_tum(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32mf2_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_tum(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m1_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_tum(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m2_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_tum(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m4_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_rm_tumu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -3747,56 +3207,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_rm_tumu(vbool4_t mask, vfloat16m4_t masked return __riscv_vfncvt_f_xu_w_f16m4_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_tumu(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf4_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_tumu(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf2_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_tumu(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m1_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_tumu(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m2_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_tumu(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m4_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_rm_tumu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -3957,46 +3367,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_rm_tumu(vbool8_t mask, vfloat32m4_t masked return __riscv_vfncvt_f_xu_w_f32m4_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_tumu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32mf2_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_tumu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m1_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_tumu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m2_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_tumu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m4_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_rm_mu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -4317,56 +3687,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_rm_mu(vbool4_t mask, vfloat16m4_t maskedof return __riscv_vfncvt_f_xu_w_f16m4_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_mu(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf4_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_mu(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16mf2_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_mu(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m1_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_mu(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m2_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_mu(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f16m4_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_rm_mu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -4527,43 +3847,3 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_rm_mu(vbool8_t mask, vfloat32m4_t maskedof return __riscv_vfncvt_f_xu_w_f32m4_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_mu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32mf2_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_mu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m1_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_mu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m2_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_mu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_f_w_f32m4_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vfncvt_f_f.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vfncvt_f_f.c new file mode 100644 index 0000000000000..a704525df0e51 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vfncvt_f_f.c @@ -0,0 +1,729 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_tu(vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf4_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_tu(vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf2_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_tu(vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m1_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_tu(vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m2_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_tu(vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m4_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_tu(vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32mf2_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_tu(vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m1_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_tu(vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m2_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_tu(vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m4_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_tum(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf4_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_tum(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf2_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_tum(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m1_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_tum(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m2_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_tum(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m4_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_tum(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32mf2_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_tum(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m1_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_tum(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m2_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_tum(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m4_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_tumu(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf4_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_tumu(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf2_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_tumu(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m1_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_tumu(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m2_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_tumu(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m4_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_tumu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32mf2_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_tumu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m1_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_tumu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m2_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_tumu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m4_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_mu(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf4_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_mu(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf2_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_mu(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m1_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_mu(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m2_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_mu(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m4_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_mu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32mf2_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_mu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m1_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_mu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m2_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_mu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m4_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_tu(vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf4_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_tu(vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf2_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_tu(vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m1_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_tu(vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m2_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_tu(vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m4_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_tu(vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32mf2_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_tu(vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m1_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_tu(vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m2_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_tu(vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m4_rm_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_tum(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf4_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_tum(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf2_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_tum(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m1_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_tum(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m2_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_tum(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m4_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_tum(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32mf2_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_tum(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m1_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_tum(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m2_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_tum(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m4_rm_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_tumu(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf4_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_tumu(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf2_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_tumu(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m1_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_tumu(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m2_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_tumu(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m4_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_tumu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32mf2_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_tumu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m1_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_tumu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m2_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_tumu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m4_rm_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_mu(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf4_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_mu(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16mf2_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_mu(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m1_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_mu(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m2_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_mu(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f16m4_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_mu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32mf2_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_mu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m1_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_mu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m2_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_mu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_f_w_f32m4_rm_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vfwcvt.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vfwcvt.c index 16a26766806f7..acb88ed5f3bd8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vfwcvt.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vfwcvt.c @@ -327,56 +327,6 @@ vfloat32m8_t test_vfwcvt_f_xu_v_f32m8_tu(vfloat32m8_t maskedoff, vuint16m4_t src return __riscv_vfwcvt_f_xu_v_f32m8_tu(maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv1f32.nxv1f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_tu(vfloat32mf2_t maskedoff, vfloat16mf4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32mf2_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv2f32.nxv2f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfwcvt_f_f_v_f32m1_tu(vfloat32m1_t maskedoff, vfloat16mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m1_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f32.nxv4f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfwcvt_f_f_v_f32m2_tu(vfloat32m2_t maskedoff, vfloat16m1_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m2_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv8f32.nxv8f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfwcvt_f_f_v_f32m4_tu(vfloat32m4_t maskedoff, vfloat16m2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m4_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv16f32.nxv16f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m8_t test_vfwcvt_f_f_v_f32m8_tu(vfloat32m8_t maskedoff, vfloat16m4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m8_tu(maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_x_f_v_i64m1_tu // CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -537,46 +487,6 @@ vfloat64m8_t test_vfwcvt_f_xu_v_f64m8_tu(vfloat64m8_t maskedoff, vuint32m4_t src return __riscv_vfwcvt_f_xu_v_f64m8_tu(maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv1f64.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m1_t test_vfwcvt_f_f_v_f64m1_tu(vfloat64m1_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m1_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv2f64.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m2_t test_vfwcvt_f_f_v_f64m2_tu(vfloat64m2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m2_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f64.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m4_t test_vfwcvt_f_f_v_f64m4_tu(vfloat64m4_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m4_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv8f64.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m8_t test_vfwcvt_f_f_v_f64m8_tu(vfloat64m8_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m8_tu(maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_x_v_f16mf4_tum // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -897,56 +807,6 @@ vfloat32m8_t test_vfwcvt_f_xu_v_f32m8_tum(vbool4_t mask, vfloat32m8_t maskedoff, return __riscv_vfwcvt_f_xu_v_f32m8_tum(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f32.nxv1f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_tum(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat16mf4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32mf2_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f32.nxv2f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfwcvt_f_f_v_f32m1_tum(vbool32_t mask, vfloat32m1_t maskedoff, vfloat16mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m1_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f32.nxv4f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfwcvt_f_f_v_f32m2_tum(vbool16_t mask, vfloat32m2_t maskedoff, vfloat16m1_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m2_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f32.nxv8f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfwcvt_f_f_v_f32m4_tum(vbool8_t mask, vfloat32m4_t maskedoff, vfloat16m2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m4_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv16f32.nxv16f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m8_t test_vfwcvt_f_f_v_f32m8_tum(vbool4_t mask, vfloat32m8_t maskedoff, vfloat16m4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m8_tum(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_x_f_v_i64m1_tum // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1107,46 +967,6 @@ vfloat64m8_t test_vfwcvt_f_xu_v_f64m8_tum(vbool8_t mask, vfloat64m8_t maskedoff, return __riscv_vfwcvt_f_xu_v_f64m8_tum(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f64.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m1_t test_vfwcvt_f_f_v_f64m1_tum(vbool64_t mask, vfloat64m1_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m1_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f64.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m2_t test_vfwcvt_f_f_v_f64m2_tum(vbool32_t mask, vfloat64m2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m2_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f64.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m4_t test_vfwcvt_f_f_v_f64m4_tum(vbool16_t mask, vfloat64m4_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m4_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f64.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m8_t test_vfwcvt_f_f_v_f64m8_tum(vbool8_t mask, vfloat64m8_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m8_tum(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_x_v_f16mf4_tumu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1467,56 +1287,6 @@ vfloat32m8_t test_vfwcvt_f_xu_v_f32m8_tumu(vbool4_t mask, vfloat32m8_t maskedoff return __riscv_vfwcvt_f_xu_v_f32m8_tumu(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f32.nxv1f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_tumu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat16mf4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32mf2_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f32.nxv2f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfwcvt_f_f_v_f32m1_tumu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat16mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m1_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f32.nxv4f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfwcvt_f_f_v_f32m2_tumu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat16m1_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m2_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f32.nxv8f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfwcvt_f_f_v_f32m4_tumu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat16m2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m4_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv16f32.nxv16f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m8_t test_vfwcvt_f_f_v_f32m8_tumu(vbool4_t mask, vfloat32m8_t maskedoff, vfloat16m4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m8_tumu(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_x_f_v_i64m1_tumu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1677,46 +1447,6 @@ vfloat64m8_t test_vfwcvt_f_xu_v_f64m8_tumu(vbool8_t mask, vfloat64m8_t maskedoff return __riscv_vfwcvt_f_xu_v_f64m8_tumu(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f64.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m1_t test_vfwcvt_f_f_v_f64m1_tumu(vbool64_t mask, vfloat64m1_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m1_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f64.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m2_t test_vfwcvt_f_f_v_f64m2_tumu(vbool32_t mask, vfloat64m2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m2_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f64.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m4_t test_vfwcvt_f_f_v_f64m4_tumu(vbool16_t mask, vfloat64m4_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m4_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f64.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m8_t test_vfwcvt_f_f_v_f64m8_tumu(vbool8_t mask, vfloat64m8_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m8_tumu(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_x_v_f16mf4_mu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -2037,56 +1767,6 @@ vfloat32m8_t test_vfwcvt_f_xu_v_f32m8_mu(vbool4_t mask, vfloat32m8_t maskedoff, return __riscv_vfwcvt_f_xu_v_f32m8_mu(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f32.nxv1f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_mu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat16mf4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32mf2_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f32.nxv2f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfwcvt_f_f_v_f32m1_mu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat16mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m1_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f32.nxv4f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfwcvt_f_f_v_f32m2_mu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat16m1_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m2_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f32.nxv8f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfwcvt_f_f_v_f32m4_mu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat16m2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m4_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv16f32.nxv16f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m8_t test_vfwcvt_f_f_v_f32m8_mu(vbool4_t mask, vfloat32m8_t maskedoff, vfloat16m4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f32m8_mu(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_x_f_v_i64m1_mu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -2247,46 +1927,6 @@ vfloat64m8_t test_vfwcvt_f_xu_v_f64m8_mu(vbool8_t mask, vfloat64m8_t maskedoff, return __riscv_vfwcvt_f_xu_v_f64m8_mu(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f64.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m1_t test_vfwcvt_f_f_v_f64m1_mu(vbool64_t mask, vfloat64m1_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m1_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f64.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m2_t test_vfwcvt_f_f_v_f64m2_mu(vbool32_t mask, vfloat64m2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m2_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f64.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m4_t test_vfwcvt_f_f_v_f64m4_mu(vbool16_t mask, vfloat64m4_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m4_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f64.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m8_t test_vfwcvt_f_f_v_f64m8_mu(vbool8_t mask, vfloat64m8_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfwcvt_f_f_v_f64m8_mu(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_x_f_v_i32mf2_rm_tu // CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vfwcvt_f_f.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vfwcvt_f_f.c new file mode 100644 index 0000000000000..3a8cfb46c9b0e --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vfwcvt_f_f.c @@ -0,0 +1,368 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv1f32.nxv1f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_tu(vfloat32mf2_t maskedoff, vfloat16mf4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32mf2_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv2f32.nxv2f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfwcvt_f_f_v_f32m1_tu(vfloat32m1_t maskedoff, vfloat16mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m1_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f32.nxv4f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfwcvt_f_f_v_f32m2_tu(vfloat32m2_t maskedoff, vfloat16m1_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m2_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv8f32.nxv8f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfwcvt_f_f_v_f32m4_tu(vfloat32m4_t maskedoff, vfloat16m2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m4_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv16f32.nxv16f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfwcvt_f_f_v_f32m8_tu(vfloat32m8_t maskedoff, vfloat16m4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m8_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv1f64.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfwcvt_f_f_v_f64m1_tu(vfloat64m1_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m1_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv2f64.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfwcvt_f_f_v_f64m2_tu(vfloat64m2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m2_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f64.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfwcvt_f_f_v_f64m4_tu(vfloat64m4_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m4_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv8f64.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfwcvt_f_f_v_f64m8_tu(vfloat64m8_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m8_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f32.nxv1f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_tum(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat16mf4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32mf2_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f32.nxv2f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfwcvt_f_f_v_f32m1_tum(vbool32_t mask, vfloat32m1_t maskedoff, vfloat16mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m1_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f32.nxv4f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfwcvt_f_f_v_f32m2_tum(vbool16_t mask, vfloat32m2_t maskedoff, vfloat16m1_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m2_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f32.nxv8f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfwcvt_f_f_v_f32m4_tum(vbool8_t mask, vfloat32m4_t maskedoff, vfloat16m2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m4_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv16f32.nxv16f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfwcvt_f_f_v_f32m8_tum(vbool4_t mask, vfloat32m8_t maskedoff, vfloat16m4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m8_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f64.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfwcvt_f_f_v_f64m1_tum(vbool64_t mask, vfloat64m1_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m1_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f64.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfwcvt_f_f_v_f64m2_tum(vbool32_t mask, vfloat64m2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m2_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f64.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfwcvt_f_f_v_f64m4_tum(vbool16_t mask, vfloat64m4_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m4_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f64.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfwcvt_f_f_v_f64m8_tum(vbool8_t mask, vfloat64m8_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m8_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f32.nxv1f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_tumu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat16mf4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32mf2_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f32.nxv2f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfwcvt_f_f_v_f32m1_tumu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat16mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m1_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f32.nxv4f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfwcvt_f_f_v_f32m2_tumu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat16m1_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m2_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f32.nxv8f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfwcvt_f_f_v_f32m4_tumu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat16m2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m4_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv16f32.nxv16f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfwcvt_f_f_v_f32m8_tumu(vbool4_t mask, vfloat32m8_t maskedoff, vfloat16m4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m8_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f64.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfwcvt_f_f_v_f64m1_tumu(vbool64_t mask, vfloat64m1_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m1_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f64.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfwcvt_f_f_v_f64m2_tumu(vbool32_t mask, vfloat64m2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m2_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f64.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfwcvt_f_f_v_f64m4_tumu(vbool16_t mask, vfloat64m4_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m4_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f64.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfwcvt_f_f_v_f64m8_tumu(vbool8_t mask, vfloat64m8_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m8_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f32.nxv1f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_mu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat16mf4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32mf2_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f32.nxv2f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfwcvt_f_f_v_f32m1_mu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat16mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m1_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f32.nxv4f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfwcvt_f_f_v_f32m2_mu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat16m1_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m2_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f32.nxv8f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfwcvt_f_f_v_f32m4_mu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat16m2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m4_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv16f32.nxv16f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfwcvt_f_f_v_f32m8_mu(vbool4_t mask, vfloat32m8_t maskedoff, vfloat16m4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f32m8_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f64.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfwcvt_f_f_v_f64m1_mu(vbool64_t mask, vfloat64m1_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m1_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f64.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfwcvt_f_f_v_f64m2_mu(vbool32_t mask, vfloat64m2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m2_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f64.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfwcvt_f_f_v_f64m4_mu(vbool16_t mask, vfloat64m4_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m4_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f64.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfwcvt_f_f_v_f64m8_mu(vbool8_t mask, vfloat64m8_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfwcvt_f_f_v_f64m8_mu(mask, maskedoff, src, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vle16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vle16.c index 81ebd741ff356..f34cf48053cc4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vle16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vle16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vle16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vle16ff.c index 6c7a930bfdf9a..1d0722dbf2008 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vle16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vle16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxei16.c index 95c81e92a6c54..c042b73228b60 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxei32.c index fc4cba11d3890..0f1ac7312ad89 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxei64.c index 3a4909fe5de0b..2755a4c5e59b8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxei8.c index eb1a22c016edb..54497b607bf92 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg2ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg2ei16.c index ecc3943488f86..83db0fabc771a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg2ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg2ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg2ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg2ei32.c index c37e14b059c64..0844848e74af8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg2ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg2ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg2ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg2ei64.c index 1669cba208dc9..edbf69833f089 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg2ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg2ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg2ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg2ei8.c index fde713cfe0be3..7601c65d1dc63 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg2ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg2ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg3ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg3ei16.c index 1e3bc5ade6855..be97d06949b86 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg3ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg3ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg3ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg3ei32.c index cb25f67f7f86f..04bb11fec3551 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg3ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg3ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg3ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg3ei64.c index c99e2741bc3fe..71c591b780230 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg3ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg3ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg3ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg3ei8.c index be1132ddc0a5a..8eb9763240ce6 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg3ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg3ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg4ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg4ei16.c index 7d776e01209c4..add1067e4a4bf 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg4ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg4ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg4ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg4ei32.c index 932355d381f9c..e5ea6fea80df9 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg4ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg4ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg4ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg4ei64.c index 263e48868f6c5..dbaa07e075a81 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg4ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg4ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg4ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg4ei8.c index 7f6d944629f92..4bf420cf5b3e2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg4ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg4ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg5ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg5ei16.c index 08f4d24856594..2d680aca126b0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg5ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg5ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg5ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg5ei32.c index 44d49e5e2c558..ca39a856d2018 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg5ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg5ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg5ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg5ei64.c index e8b259635dc36..0985eb069a70e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg5ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg5ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg5ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg5ei8.c index 27d0e843b4ebb..d09fb723d2f93 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg5ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg5ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg6ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg6ei16.c index b5a05193af2dc..fc1c6926710be 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg6ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg6ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg6ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg6ei32.c index 2081f947da874..567002ccb232f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg6ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg6ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg6ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg6ei64.c index 0e8888bd25f03..c3a0b42b94549 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg6ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg6ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg6ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg6ei8.c index 0dd8667ba76ad..0e9765c70d6d9 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg6ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg6ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg7ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg7ei16.c index 01c461d4b619f..f73a859bae48a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg7ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg7ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg7ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg7ei32.c index b835c5f8cbdb9..d557943ac57d8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg7ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg7ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg7ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg7ei64.c index c3969d223c737..9b9d502fc96a4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg7ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg7ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg7ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg7ei8.c index 0b6b3424d8e2c..04c48afa37cf8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg7ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg7ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg8ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg8ei16.c index 3d658e3effdb3..bd27639fc498f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg8ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg8ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg8ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg8ei32.c index 3c91aecab77a1..5012d7e6383aa 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg8ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg8ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg8ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg8ei64.c index 394fa602cd984..658ab532a7a5d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg8ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg8ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg8ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg8ei8.c index c19e4637abfe0..3c764c248f7d0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg8ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vloxseg8ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlse16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlse16.c index 9ff1aa0003cae..469dd7d654272 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlse16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlse16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg2e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg2e16.c index 69e3656edc748..e28809ee7df7b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg2e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg2e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg2e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg2e16ff.c index 36a2ff30b3010..e10b9971d8ecf 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg2e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg2e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg3e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg3e16.c index 1e7a689bc2327..c97bfa10ca5cd 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg3e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg3e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg3e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg3e16ff.c index 3089f0e369c94..d54571666c367 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg3e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg3e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg4e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg4e16.c index 969363878108b..7c20dcc2fea6f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg4e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg4e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg4e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg4e16ff.c index bf2b469585dca..a9e79452772f0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg4e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg4e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg5e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg5e16.c index 9a393f0331ca3..0c74d19237f3c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg5e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg5e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg5e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg5e16ff.c index 42e788e127e72..68be4e5f18e6c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg5e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg5e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg6e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg6e16.c index 4fca146f8c7a0..9ed47f14726a4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg6e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg6e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg6e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg6e16ff.c index abdd90fbd0466..2bcae7ee412e3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg6e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg6e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg7e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg7e16.c index ac15d63747272..7e558a3bad6a1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg7e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg7e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg7e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg7e16ff.c index 3d54c04ad1458..e0262f295dca5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg7e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg7e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg8e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg8e16.c index 8d60f5f0bed54..7d9f54712142c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg8e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg8e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg8e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg8e16ff.c index fa41b017a6c8c..765bb29c87dbd 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg8e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlseg8e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg2e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg2e16.c index 7260cfa0bb3be..7cfa8002ffecd 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg2e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg2e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg3e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg3e16.c index a4fe77b229afa..3ae4c113d96bf 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg3e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg3e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg4e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg4e16.c index eff8ed9996db1..74986a9760ccb 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg4e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg4e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg5e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg5e16.c index 16dd04e106ed2..bef42c1993cbe 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg5e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg5e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg6e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg6e16.c index 872ca88ca4796..20fff1909d9f3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg6e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg6e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg7e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg7e16.c index 39b81c4a52841..64d580e6211e1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg7e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg7e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg8e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg8e16.c index 5053d27ef29dc..e5349b4c1fb91 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg8e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vlsseg8e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxei16.c index 7b584c9ee79c5..19496e5cbac1b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxei32.c index 7e8eda71ff436..ba4c9a6fb33d1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxei64.c index f788ff0b67acf..3f9b85eae1bad 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxei8.c index dde110aa2fc97..d5b858276dccf 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg2ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg2ei16.c index a62d13ab140a0..32857db63474f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg2ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg2ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg2ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg2ei32.c index fdcb33efd8840..bd8bfcc4fcbf0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg2ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg2ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg2ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg2ei64.c index fb361396f75bc..778f26a5153e1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg2ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg2ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg2ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg2ei8.c index 47cc216bac392..27b257e4ac316 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg2ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg2ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg3ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg3ei16.c index a62294be66a36..4bff4f9f62a82 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg3ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg3ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg3ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg3ei32.c index f5558324cd3e9..253ea1304ff76 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg3ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg3ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg3ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg3ei64.c index 52c80e3fa647e..c4337e936086d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg3ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg3ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg3ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg3ei8.c index d6d5854b9129a..4aa07e42b6208 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg3ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg3ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg4ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg4ei16.c index e86cabd103510..b3d57e23fff04 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg4ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg4ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg4ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg4ei32.c index 98d882b66a5a1..36b79dbd4d3b5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg4ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg4ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg4ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg4ei64.c index 9d82d8566514b..11bc4c10f31ef 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg4ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg4ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg4ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg4ei8.c index b26f072ffd0bd..65b39071f9a6f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg4ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg4ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg5ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg5ei16.c index b98d447dcd12b..dfb0faf693b0c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg5ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg5ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg5ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg5ei32.c index aef2f814c79a9..e7d30dcc482b5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg5ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg5ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg5ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg5ei64.c index e7acb1e2f1fcd..8a8ee26fc1633 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg5ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg5ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg5ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg5ei8.c index ec89215f1cd46..a17eb2faa5008 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg5ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg5ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg6ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg6ei16.c index 999b4d1fdfecd..ac39344ce1fa8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg6ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg6ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg6ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg6ei32.c index e80bb4ee66e17..69d6bf33e3cbe 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg6ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg6ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg6ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg6ei64.c index 14a7749aaf959..793380c6d3510 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg6ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg6ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg6ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg6ei8.c index bf2edd94340ea..8570fdc150226 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg6ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg6ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg7ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg7ei16.c index dcd2e93cb6611..c2f7afb6983a1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg7ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg7ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg7ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg7ei32.c index ca4294a707a54..5e277566e5724 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg7ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg7ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg7ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg7ei64.c index 1fd9fc1bcdcbb..373466580ce5a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg7ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg7ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg7ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg7ei8.c index 8912a7e9587cc..9e5ed180900a4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg7ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg7ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg8ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg8ei16.c index 1b951f9d01877..176f753e40a3d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg8ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg8ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg8ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg8ei32.c index 4a61541dfd231..01703cf756efe 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg8ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg8ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg8ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg8ei64.c index 055dc860c9afc..6a782d444e6cc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg8ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg8ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg8ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg8ei8.c index 6488b02056a7e..595fc708663e4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg8ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vluxseg8ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vmerge.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vmerge.c index 75365b75e3a65..4f723c579597e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vmerge.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vmerge.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vmv.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vmv.c index a60c19eaf7f9f..2a5a0f4f892d3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vmv.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vmv.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vfncvt.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vfncvt.c index 5ec971affac90..f6a454556e9dc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vfncvt.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vfncvt.c @@ -327,56 +327,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_tu(vfloat16m4_t maskedoff, vuint32m8_t src return __riscv_vfncvt_f_tu(maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_tu(vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_tu(vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_tu(vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_tu(vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_tu(vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_tu // CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -537,46 +487,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_tu(vfloat32m4_t maskedoff, vuint64m8_t src return __riscv_vfncvt_f_tu(maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_tu(vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_tu(vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_tu(vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_tu(vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_tum // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -897,56 +807,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_tum(vbool4_t mask, vfloat16m4_t maskedoff, return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_tum(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_tum(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_tum(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_tum(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_tum(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_tum // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1107,46 +967,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_tum(vbool8_t mask, vfloat32m4_t maskedoff, return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_tum(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_tum(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_tum(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_tum(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_tumu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1467,56 +1287,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_tumu(vbool4_t mask, vfloat16m4_t maskedoff return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_tumu(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_tumu(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_tumu(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_tumu(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_tumu(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_tumu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1677,46 +1447,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_tumu(vbool8_t mask, vfloat32m4_t maskedoff return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_tumu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_tumu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_tumu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_tumu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_mu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -2037,56 +1767,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_mu(vbool4_t mask, vfloat16m4_t maskedoff, return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_mu(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_mu(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_mu(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_mu(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_mu(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_mu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -2247,46 +1927,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_mu(vbool8_t mask, vfloat32m4_t maskedoff, return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_mu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_mu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_mu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_mu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_rm_tu // CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -2607,56 +2247,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_rm_tu(vfloat16m4_t maskedoff, vuint32m8_t return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_tu(vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_tu(vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_tu(vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_tu(vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_tu(vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_rm_tu // CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -2817,46 +2407,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_rm_tu(vfloat32m4_t maskedoff, vuint64m8_t return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_tu(vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_tu(vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_tu(vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_tu(vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_rm_tum // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -3177,56 +2727,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_rm_tum(vbool4_t mask, vfloat16m4_t maskedo return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_tum(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_tum(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_tum(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_tum(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_tum(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_rm_tum // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -3387,46 +2887,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_rm_tum(vbool8_t mask, vfloat32m4_t maskedo return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_tum(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_tum(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_tum(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_tum(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_rm_tumu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -3747,56 +3207,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_rm_tumu(vbool4_t mask, vfloat16m4_t masked return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_tumu(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_tumu(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_tumu(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_tumu(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_tumu(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_rm_tumu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -3957,46 +3367,6 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_rm_tumu(vbool8_t mask, vfloat32m4_t masked return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_tumu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_tumu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_tumu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_tumu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i8mf8_rm_mu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -4317,56 +3687,6 @@ vfloat16m4_t test_vfncvt_f_xu_w_f16m4_rm_mu(vbool4_t mask, vfloat16m4_t maskedof return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_mu(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_mu(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_mu(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_mu(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_mu(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfncvt_x_f_w_i32mf2_rm_mu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -4527,43 +3847,3 @@ vfloat32m4_t test_vfncvt_f_xu_w_f32m4_rm_mu(vbool8_t mask, vfloat32m4_t maskedof return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_mu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_mu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_mu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_mu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { - return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); -} - diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vfncvt_f_f.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vfncvt_f_f.c new file mode 100644 index 0000000000000..88d67f0b0a882 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vfncvt_f_f.c @@ -0,0 +1,729 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ +// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_tu(vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_tu(vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_tu(vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_tu(vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_tu(vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_tu(vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_tu(vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_tu(vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], i64 7, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_tu(vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_tum(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_tum(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_tum(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_tum(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_tum(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_tum(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_tum(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_tum(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_tum(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_tumu(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_tumu(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_tumu(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_tumu(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_tumu(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_tumu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_tumu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_tumu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_tumu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_mu(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_mu(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_mu(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_mu(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_mu(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_mu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_mu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_mu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 7, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_mu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_tu(vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_tu(vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_tu(vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_tu(vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_tu(vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_tu(vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_tu(vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_tu(vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], i64 0, i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_tu(vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_tu(maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_tum(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_tum(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_tum(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_tum(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_tum(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_tum(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_tum(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_tum(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_tum(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_tum(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_tumu(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_tumu(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_tumu(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_tumu(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_tumu(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_tumu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_tumu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_tumu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_tumu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_tumu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf4_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f16.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf4_t test_vfncvt_f_f_w_f16mf4_rm_mu(vbool64_t mask, vfloat16mf4_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16mf2_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f16.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16mf2_t test_vfncvt_f_f_w_f16mf2_rm_mu(vbool32_t mask, vfloat16mf2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m1_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f16.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1_rm_mu(vbool16_t mask, vfloat16m1_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m2_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f16.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_vfncvt_f_f_w_f16m2_rm_mu(vbool8_t mask, vfloat16m2_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f16m4_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv16f16.nxv16f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_vfncvt_f_f_w_f16m4_rm_mu(vbool4_t mask, vfloat16m4_t maskedoff, vfloat32m8_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32mf2_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv1f32.nxv1f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfncvt_f_f_w_f32mf2_rm_mu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat64m1_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m1_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv2f32.nxv2f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfncvt_f_f_w_f32m1_rm_mu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat64m2_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m2_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv4f32.nxv4f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfncvt_f_f_w_f32m2_rm_mu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat64m4_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfncvt_f_f_w_f32m4_rm_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.mask.nxv8f32.nxv8f64.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 0, i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfncvt_f_f_w_f32m4_rm_mu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat64m8_t src, size_t vl) { + return __riscv_vfncvt_f_mu(mask, maskedoff, src, __RISCV_FRM_RNE, vl); +} + diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vfwcvt.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vfwcvt.c index ecd1e7d3c7d39..327a67c133091 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vfwcvt.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vfwcvt.c @@ -327,56 +327,6 @@ vfloat32m8_t test_vfwcvt_f_xu_v_f32m8_tu(vfloat32m8_t maskedoff, vuint16m4_t src return __riscv_vfwcvt_f_tu(maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv1f32.nxv1f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_tu(vfloat32mf2_t maskedoff, vfloat16mf4_t src, size_t vl) { - return __riscv_vfwcvt_f_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv2f32.nxv2f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfwcvt_f_f_v_f32m1_tu(vfloat32m1_t maskedoff, vfloat16mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f32.nxv4f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfwcvt_f_f_v_f32m2_tu(vfloat32m2_t maskedoff, vfloat16m1_t src, size_t vl) { - return __riscv_vfwcvt_f_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv8f32.nxv8f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfwcvt_f_f_v_f32m4_tu(vfloat32m4_t maskedoff, vfloat16m2_t src, size_t vl) { - return __riscv_vfwcvt_f_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv16f32.nxv16f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m8_t test_vfwcvt_f_f_v_f32m8_tu(vfloat32m8_t maskedoff, vfloat16m4_t src, size_t vl) { - return __riscv_vfwcvt_f_tu(maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_x_f_v_i64m1_tu // CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -537,46 +487,6 @@ vfloat64m8_t test_vfwcvt_f_xu_v_f64m8_tu(vfloat64m8_t maskedoff, vuint32m4_t src return __riscv_vfwcvt_f_tu(maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv1f64.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m1_t test_vfwcvt_f_f_v_f64m1_tu(vfloat64m1_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv2f64.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m2_t test_vfwcvt_f_f_v_f64m2_tu(vfloat64m2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfwcvt_f_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f64.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m4_t test_vfwcvt_f_f_v_f64m4_tu(vfloat64m4_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfwcvt_f_tu(maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_tu -// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv8f64.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m8_t test_vfwcvt_f_f_v_f64m8_tu(vfloat64m8_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfwcvt_f_tu(maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_x_v_f16mf4_tum // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -897,56 +807,6 @@ vfloat32m8_t test_vfwcvt_f_xu_v_f32m8_tum(vbool4_t mask, vfloat32m8_t maskedoff, return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f32.nxv1f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_tum(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat16mf4_t src, size_t vl) { - return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f32.nxv2f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfwcvt_f_f_v_f32m1_tum(vbool32_t mask, vfloat32m1_t maskedoff, vfloat16mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f32.nxv4f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfwcvt_f_f_v_f32m2_tum(vbool16_t mask, vfloat32m2_t maskedoff, vfloat16m1_t src, size_t vl) { - return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f32.nxv8f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfwcvt_f_f_v_f32m4_tum(vbool8_t mask, vfloat32m4_t maskedoff, vfloat16m2_t src, size_t vl) { - return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv16f32.nxv16f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m8_t test_vfwcvt_f_f_v_f32m8_tum(vbool4_t mask, vfloat32m8_t maskedoff, vfloat16m4_t src, size_t vl) { - return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_x_f_v_i64m1_tum // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1107,45 +967,6 @@ vfloat64m8_t test_vfwcvt_f_xu_v_f64m8_tum(vbool8_t mask, vfloat64m8_t maskedoff, return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f64.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m1_t test_vfwcvt_f_f_v_f64m1_tum(vbool64_t mask, vfloat64m1_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f64.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m2_t test_vfwcvt_f_f_v_f64m2_tum(vbool32_t mask, vfloat64m2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f64.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m4_t test_vfwcvt_f_f_v_f64m4_tum(vbool16_t mask, vfloat64m4_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_tum -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f64.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m8_t test_vfwcvt_f_f_v_f64m8_tum(vbool8_t mask, vfloat64m8_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); -} // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_x_v_f16mf4_tumu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { @@ -1467,56 +1288,6 @@ vfloat32m8_t test_vfwcvt_f_xu_v_f32m8_tumu(vbool4_t mask, vfloat32m8_t maskedoff return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f32.nxv1f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_tumu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat16mf4_t src, size_t vl) { - return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f32.nxv2f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfwcvt_f_f_v_f32m1_tumu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat16mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f32.nxv4f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfwcvt_f_f_v_f32m2_tumu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat16m1_t src, size_t vl) { - return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f32.nxv8f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfwcvt_f_f_v_f32m4_tumu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat16m2_t src, size_t vl) { - return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv16f32.nxv16f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m8_t test_vfwcvt_f_f_v_f32m8_tumu(vbool4_t mask, vfloat32m8_t maskedoff, vfloat16m4_t src, size_t vl) { - return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_x_f_v_i64m1_tumu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -1677,46 +1448,6 @@ vfloat64m8_t test_vfwcvt_f_xu_v_f64m8_tumu(vbool8_t mask, vfloat64m8_t maskedoff return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f64.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m1_t test_vfwcvt_f_f_v_f64m1_tumu(vbool64_t mask, vfloat64m1_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f64.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m2_t test_vfwcvt_f_f_v_f64m2_tumu(vbool32_t mask, vfloat64m2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f64.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m4_t test_vfwcvt_f_f_v_f64m4_tumu(vbool16_t mask, vfloat64m4_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_tumu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f64.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m8_t test_vfwcvt_f_f_v_f64m8_tumu(vbool8_t mask, vfloat64m8_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_x_v_f16mf4_mu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -2037,56 +1768,6 @@ vfloat32m8_t test_vfwcvt_f_xu_v_f32m8_mu(vbool4_t mask, vfloat32m8_t maskedoff, return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f32.nxv1f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_mu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat16mf4_t src, size_t vl) { - return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f32.nxv2f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m1_t test_vfwcvt_f_f_v_f32m1_mu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat16mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f32.nxv4f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfwcvt_f_f_v_f32m2_mu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat16m1_t src, size_t vl) { - return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f32.nxv8f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m4_t test_vfwcvt_f_f_v_f32m4_mu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat16m2_t src, size_t vl) { - return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv16f32.nxv16f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat32m8_t test_vfwcvt_f_f_v_f32m8_mu(vbool4_t mask, vfloat32m8_t maskedoff, vfloat16m4_t src, size_t vl) { - return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_x_f_v_i64m1_mu // CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: @@ -2247,46 +1928,6 @@ vfloat64m8_t test_vfwcvt_f_xu_v_f64m8_mu(vbool8_t mask, vfloat64m8_t maskedoff, return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); } -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f64.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m1_t test_vfwcvt_f_f_v_f64m1_mu(vbool64_t mask, vfloat64m1_t maskedoff, vfloat32mf2_t src, size_t vl) { - return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f64.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m2_t test_vfwcvt_f_f_v_f64m2_mu(vbool32_t mask, vfloat64m2_t maskedoff, vfloat32m1_t src, size_t vl) { - return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f64.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m4_t test_vfwcvt_f_f_v_f64m4_mu(vbool16_t mask, vfloat64m4_t maskedoff, vfloat32m2_t src, size_t vl) { - return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); -} - -// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_mu -// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { -// CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f64.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) -// CHECK-RV64-NEXT: ret [[TMP0]] -// -vfloat64m8_t test_vfwcvt_f_f_v_f64m8_mu(vbool8_t mask, vfloat64m8_t maskedoff, vfloat32m4_t src, size_t vl) { - return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); -} - // CHECK-RV64-LABEL: define dso_local @test_vfwcvt_x_f_v_i32mf2_rm_tu // CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vfwcvt_f_f.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vfwcvt_f_f.c new file mode 100644 index 0000000000000..202998020b359 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vfwcvt_f_f.c @@ -0,0 +1,368 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv1f32.nxv1f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_tu(vfloat32mf2_t maskedoff, vfloat16mf4_t src, size_t vl) { + return __riscv_vfwcvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv2f32.nxv2f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfwcvt_f_f_v_f32m1_tu(vfloat32m1_t maskedoff, vfloat16mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f32.nxv4f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfwcvt_f_f_v_f32m2_tu(vfloat32m2_t maskedoff, vfloat16m1_t src, size_t vl) { + return __riscv_vfwcvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv8f32.nxv8f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfwcvt_f_f_v_f32m4_tu(vfloat32m4_t maskedoff, vfloat16m2_t src, size_t vl) { + return __riscv_vfwcvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv16f32.nxv16f16.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfwcvt_f_f_v_f32m8_tu(vfloat32m8_t maskedoff, vfloat16m4_t src, size_t vl) { + return __riscv_vfwcvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv1f64.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfwcvt_f_f_v_f64m1_tu(vfloat64m1_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv2f64.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfwcvt_f_f_v_f64m2_tu(vfloat64m2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfwcvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f64.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfwcvt_f_f_v_f64m4_tu(vfloat64m4_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfwcvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_tu +// CHECK-RV64-SAME: ( [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv8f64.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfwcvt_f_f_v_f64m8_tu(vfloat64m8_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfwcvt_f_tu(maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f32.nxv1f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_tum(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat16mf4_t src, size_t vl) { + return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f32.nxv2f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfwcvt_f_f_v_f32m1_tum(vbool32_t mask, vfloat32m1_t maskedoff, vfloat16mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f32.nxv4f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfwcvt_f_f_v_f32m2_tum(vbool16_t mask, vfloat32m2_t maskedoff, vfloat16m1_t src, size_t vl) { + return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f32.nxv8f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfwcvt_f_f_v_f32m4_tum(vbool8_t mask, vfloat32m4_t maskedoff, vfloat16m2_t src, size_t vl) { + return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv16f32.nxv16f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfwcvt_f_f_v_f32m8_tum(vbool4_t mask, vfloat32m8_t maskedoff, vfloat16m4_t src, size_t vl) { + return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f64.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfwcvt_f_f_v_f64m1_tum(vbool64_t mask, vfloat64m1_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f64.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfwcvt_f_f_v_f64m2_tum(vbool32_t mask, vfloat64m2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f64.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfwcvt_f_f_v_f64m4_tum(vbool16_t mask, vfloat64m4_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_tum +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f64.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfwcvt_f_f_v_f64m8_tum(vbool8_t mask, vfloat64m8_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfwcvt_f_tum(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f32.nxv1f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_tumu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat16mf4_t src, size_t vl) { + return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f32.nxv2f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfwcvt_f_f_v_f32m1_tumu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat16mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f32.nxv4f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfwcvt_f_f_v_f32m2_tumu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat16m1_t src, size_t vl) { + return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f32.nxv8f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfwcvt_f_f_v_f32m4_tumu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat16m2_t src, size_t vl) { + return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv16f32.nxv16f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfwcvt_f_f_v_f32m8_tumu(vbool4_t mask, vfloat32m8_t maskedoff, vfloat16m4_t src, size_t vl) { + return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f64.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfwcvt_f_f_v_f64m1_tumu(vbool64_t mask, vfloat64m1_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f64.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfwcvt_f_f_v_f64m2_tumu(vbool32_t mask, vfloat64m2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f64.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfwcvt_f_f_v_f64m4_tumu(vbool16_t mask, vfloat64m4_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_tumu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f64.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 0) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfwcvt_f_f_v_f64m8_tumu(vbool8_t mask, vfloat64m8_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfwcvt_f_tumu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32mf2_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f32.nxv1f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_vfwcvt_f_f_v_f32mf2_mu(vbool64_t mask, vfloat32mf2_t maskedoff, vfloat16mf4_t src, size_t vl) { + return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m1_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f32.nxv2f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_vfwcvt_f_f_v_f32m1_mu(vbool32_t mask, vfloat32m1_t maskedoff, vfloat16mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m2_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f32.nxv4f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfwcvt_f_f_v_f32m2_mu(vbool16_t mask, vfloat32m2_t maskedoff, vfloat16m1_t src, size_t vl) { + return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m4_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f32.nxv8f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_vfwcvt_f_f_v_f32m4_mu(vbool8_t mask, vfloat32m4_t maskedoff, vfloat16m2_t src, size_t vl) { + return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f32m8_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv16f32.nxv16f16.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_vfwcvt_f_f_v_f32m8_mu(vbool4_t mask, vfloat32m8_t maskedoff, vfloat16m4_t src, size_t vl) { + return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m1_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv1f64.nxv1f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_vfwcvt_f_f_v_f64m1_mu(vbool64_t mask, vfloat64m1_t maskedoff, vfloat32mf2_t src, size_t vl) { + return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m2_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv2f64.nxv2f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_vfwcvt_f_f_v_f64m2_mu(vbool32_t mask, vfloat64m2_t maskedoff, vfloat32m1_t src, size_t vl) { + return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m4_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv4f64.nxv4f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_vfwcvt_f_f_v_f64m4_mu(vbool16_t mask, vfloat64m4_t maskedoff, vfloat32m2_t src, size_t vl) { + return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_vfwcvt_f_f_v_f64m8_mu +// CHECK-RV64-SAME: ( [[MASK:%.*]], [[MASKEDOFF:%.*]], [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.mask.nxv8f64.nxv8f32.i64( [[MASKEDOFF]], [[SRC]], [[MASK]], i64 [[VL]], i64 1) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_vfwcvt_f_f_v_f64m8_mu(vbool8_t mask, vfloat64m8_t maskedoff, vfloat32m4_t src, size_t vl) { + return __riscv_vfwcvt_f_mu(mask, maskedoff, src, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vle16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vle16.c index dce131aaa0c4a..f7e1fc5d81f2a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vle16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vle16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vle16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vle16ff.c index f03c58045559c..bfdae9a1ee139 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vle16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vle16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxei16.c index 8878764bed26f..7128f29739b25 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxei32.c index 0f44dde7a98c1..5cb048af9ba31 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxei64.c index 5483359c4c7ab..23370beef8b9d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxei8.c index 7b2a921072cff..32577b6180acc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg2ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg2ei16.c index 89b461a92008b..0b8692166a07f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg2ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg2ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg2ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg2ei32.c index 9acbfb3f7c378..6c019b624b4a1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg2ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg2ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg2ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg2ei64.c index a79123ce54fa9..7409e48418cb2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg2ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg2ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg2ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg2ei8.c index 2036206790044..716170e24d1cb 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg2ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg2ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg3ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg3ei16.c index cfa032ad414a6..d874457ab740e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg3ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg3ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg3ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg3ei32.c index 25dab4b8ba536..3ba48a2a9a515 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg3ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg3ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg3ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg3ei64.c index 6489a05647067..ce7cacaf04da5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg3ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg3ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg3ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg3ei8.c index eef6e63265cdc..0941b6ad3e483 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg3ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg3ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg4ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg4ei16.c index dc5e103cc6432..3103c1b0f1105 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg4ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg4ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg4ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg4ei32.c index 561b848af1ac3..4dc9e5f480407 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg4ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg4ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg4ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg4ei64.c index 0d3f335c105e7..fefb90b8a6e23 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg4ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg4ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg4ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg4ei8.c index 06740621dea9d..70f1a47e126eb 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg4ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg4ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg5ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg5ei16.c index c70badf3dc4a5..6c11ca833d523 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg5ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg5ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg5ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg5ei32.c index bfa1894c61464..4e71e118744f2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg5ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg5ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg5ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg5ei64.c index 8dd6889f7b860..c68c15a638004 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg5ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg5ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg5ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg5ei8.c index 145504c5b552e..8681c32b5cdba 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg5ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg5ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg6ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg6ei16.c index bf282e258fdf3..0d59ddd619623 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg6ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg6ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg6ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg6ei32.c index 39a28ba87b669..f42ae9605928b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg6ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg6ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg6ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg6ei64.c index a8e79c4bddc03..e5f6b864be775 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg6ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg6ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg6ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg6ei8.c index 1dea35c86531e..74033769f7114 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg6ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg6ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg7ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg7ei16.c index 29eaa61876361..634ba33976bb4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg7ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg7ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg7ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg7ei32.c index 60ea5de100e37..2a5293be5a4f1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg7ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg7ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg7ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg7ei64.c index b49ed58c2c1b7..576db6adb6f35 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg7ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg7ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg7ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg7ei8.c index bb21a6cc985a7..9a8d7ba7558c8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg7ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg7ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg8ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg8ei16.c index c4d6cecfecf21..65295514609d6 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg8ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg8ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg8ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg8ei32.c index f8b6d7436d885..8a309703d681c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg8ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg8ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg8ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg8ei64.c index 0db4ec702b733..705d4485b70bc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg8ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg8ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg8ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg8ei8.c index 54b77a2d440b2..99e11bd39dd7b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg8ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vloxseg8ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlse16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlse16.c index 137847218513d..c0c4d832e4d3f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlse16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlse16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg2e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg2e16.c index 14e7842cdb8ed..b0658ab02e201 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg2e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg2e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg2e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg2e16ff.c index d09b80f023f36..6820030490b85 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg2e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg2e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg3e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg3e16.c index 3dbe9e88a235a..9568d22bd0f4a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg3e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg3e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg3e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg3e16ff.c index 797c14005df40..1a3d86c8fdb1e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg3e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg3e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg4e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg4e16.c index e66fb24e49802..9a8f8b1866659 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg4e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg4e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg4e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg4e16ff.c index 4658867e45dea..9b93997474448 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg4e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg4e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg5e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg5e16.c index b17da4099bfb9..7ad2b43935c35 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg5e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg5e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg5e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg5e16ff.c index 7beda5dc44424..5627ce44fc172 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg5e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg5e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg6e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg6e16.c index 9cb5895682233..e5c3974d30868 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg6e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg6e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg6e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg6e16ff.c index 206f722803d0a..0296f8c56b700 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg6e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg6e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg7e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg7e16.c index b73d2fe7cb7ef..fed3395a20610 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg7e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg7e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg7e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg7e16ff.c index f2b87726155e1..6c1732847aa94 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg7e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg7e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg8e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg8e16.c index 719c552f2930b..28bbbd6ef052d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg8e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg8e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg8e16ff.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg8e16ff.c index b09649fd34f92..2b9b654b8eeee 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg8e16ff.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlseg8e16ff.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg2e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg2e16.c index cf893e304e22f..b9e926d485b41 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg2e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg2e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg3e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg3e16.c index 3ae596218ea56..606aa3ed518b0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg3e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg3e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg4e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg4e16.c index 2b349817c775f..bcb9ccf1581b6 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg4e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg4e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg5e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg5e16.c index d88daa4fc8bb1..e61b33e009c0e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg5e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg5e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg6e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg6e16.c index 03b46d080b957..0dfd496bb958b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg6e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg6e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg7e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg7e16.c index f08f46f00886a..c69d05d7352e8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg7e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg7e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg8e16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg8e16.c index 23b304a3bd99e..1377dbbfaa862 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg8e16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vlsseg8e16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxei16.c index a09087aa217f4..67f7db5265b7c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxei32.c index 519f54568b8f2..2cd1ef7c7df4b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxei64.c index a154c734a07bf..55f84a640bb1f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxei8.c index e2d5273cc8449..2c6a65a4c2851 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg2ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg2ei16.c index 10ede6e64a89b..f5344338395e4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg2ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg2ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg2ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg2ei32.c index 22610e7d4eb73..693055395619a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg2ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg2ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg2ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg2ei64.c index d5f640c137b12..938f29e178dd3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg2ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg2ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg2ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg2ei8.c index 4d4e32a75263c..ed70a912dbfd9 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg2ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg2ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg3ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg3ei16.c index 2c201fad04fe4..e32ec5a147880 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg3ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg3ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg3ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg3ei32.c index a0e7f502ed823..2e105d82ac759 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg3ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg3ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg3ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg3ei64.c index 8bdcd630405df..507ef6f77e98c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg3ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg3ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg3ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg3ei8.c index c1bb3e6f56ccc..18c5da3aaaf56 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg3ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg3ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg4ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg4ei16.c index 7ddf1cb8a8203..5d78f73c9f06f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg4ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg4ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg4ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg4ei32.c index a2fcbfcf19bb1..b57f1e8af1b12 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg4ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg4ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg4ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg4ei64.c index 45c7218fb0c59..7e6380bf00b56 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg4ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg4ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg4ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg4ei8.c index 6d63e63382aac..ad4e97c6df82f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg4ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg4ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg5ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg5ei16.c index b03e5799c9715..090b6bdb06460 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg5ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg5ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg5ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg5ei32.c index 55830fac00306..ab3a9c980ac4b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg5ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg5ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg5ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg5ei64.c index 02e73420d722e..d2794b85e3d7b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg5ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg5ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg5ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg5ei8.c index fe71382caf4ca..e9dff851dd888 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg5ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg5ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg6ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg6ei16.c index 4bbba7ae1687b..4f4e62dc7b5aa 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg6ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg6ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg6ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg6ei32.c index 6ebb5c2435187..0d92c170b12a9 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg6ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg6ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg6ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg6ei64.c index 1d3720f4f8393..8dfc0f32bfe92 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg6ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg6ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg6ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg6ei8.c index f5178d0d688dc..6ecb54ca08f7f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg6ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg6ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg7ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg7ei16.c index d202d6f68f56c..8d2b7151fbbf4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg7ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg7ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg7ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg7ei32.c index 07344f4ca6d46..b097573990fd6 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg7ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg7ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg7ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg7ei64.c index 2688563e0b3e7..fa673cd236ed2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg7ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg7ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg7ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg7ei8.c index f09032a190a76..68a005107de36 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg7ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg7ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg8ei16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg8ei16.c index c6d7982700fd8..bc4d9b7103045 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg8ei16.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg8ei16.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg8ei32.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg8ei32.c index 801edf325f47c..12e29355a954b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg8ei32.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg8ei32.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg8ei64.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg8ei64.c index cec356d8166d9..077383005ad76 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg8ei64.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg8ei64.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg8ei8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg8ei8.c index e58722f747160..ddf8824025e6c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg8ei8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vluxseg8ei8.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vmerge.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vmerge.c index d346a8da669e7..8149be4cb2e71 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vmerge.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vmerge.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vmv.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vmv.c index 47b68303a15b2..ac95c77340202 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vmv.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vmv.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \ -// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/zvfhmin.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/zvfhmin.c deleted file mode 100644 index 100699ae19ef2..0000000000000 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/zvfhmin.c +++ /dev/null @@ -1,216 +0,0 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py -// REQUIRES: riscv-registered-target -// RUN: %clang_cc1 -triple riscv64 -target-feature +v \ -// RUN: -target-feature +zvfhmin -disable-O0-optnone \ -// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ -// RUN: FileCheck --check-prefix=CHECK-ZVFHMIN %s - -#include - -// CHECK-ZVFHMIN-LABEL: @test_vfncvt_f_f_w_f16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( poison, [[SRC:%.*]], i64 7, i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vfncvt_f_f_w_f16m1(vfloat32m2_t src, size_t vl) { - return __riscv_vfncvt_f(src, vl); -} - - -// CHECK-ZVFHMIN-LABEL: @test_vfwcvt_f_f_v_f16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f32.nxv4f16.i64( poison, [[SRC:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: ret [[TMP0]] -// -vfloat32m2_t test_vfwcvt_f_f_v_f16m1(vfloat16m1_t src, size_t vl) { - return __riscv_vfwcvt_f(src, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vle16_v_f16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vle.nxv4f16.i64( poison, ptr [[BASE:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vle16_v_f16m1(const _Float16 *base, size_t vl) { - return __riscv_vle16_v_f16m1(base, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vse16_v_f16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: call void @llvm.riscv.vse.nxv4f16.i64( [[VALUE:%.*]], ptr [[BASE:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: ret void -// -void test_vse16_v_f16m1(_Float16 *base, vfloat16m1_t value, size_t vl) { - return __riscv_vse16_v_f16m1(base, value, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vlse16_v_f16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vlse.nxv4f16.i64( poison, ptr [[BASE:%.*]], i64 [[BSTRIDE:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vlse16_v_f16m1(const _Float16 *base, ptrdiff_t bstride, size_t vl) { - return __riscv_vlse16_v_f16m1(base, bstride, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vsse16_v_f16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: call void @llvm.riscv.vsse.nxv4f16.i64( [[VALUE:%.*]], ptr [[BASE:%.*]], i64 [[BSTRIDE:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: ret void -// -void test_vsse16_v_f16m1(_Float16 *base, ptrdiff_t bstride, vfloat16m1_t value, size_t vl) { - return __riscv_vsse16_v_f16m1(base, bstride, value, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vluxei32_v_f16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vluxei.nxv4f16.nxv4i32.i64( poison, ptr [[BASE:%.*]], [[BINDEX:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vluxei32_v_f16m1(const _Float16 *base, vuint32m2_t bindex, size_t vl) { - return __riscv_vluxei32_v_f16m1(base, bindex, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vsuxei32_v_f16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: call void @llvm.riscv.vsuxei.nxv4f16.nxv4i32.i64( [[VALUE:%.*]], ptr [[BASE:%.*]], [[BINDEX:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: ret void -// -void test_vsuxei32_v_f16m1(_Float16 *base, vuint32m2_t bindex, vfloat16m1_t value, size_t vl) { - return __riscv_vsuxei32_v_f16m1(base, bindex, value, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vloxei32_v_f16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vloxei.nxv4f16.nxv4i32.i64( poison, ptr [[BASE:%.*]], [[BINDEX:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vloxei32_v_f16m1(const _Float16 *base, vuint32m2_t bindex, size_t vl) { - return __riscv_vloxei32_v_f16m1(base, bindex, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vsoxei32_v_f16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: call void @llvm.riscv.vsoxei.nxv4f16.nxv4i32.i64( [[VALUE:%.*]], ptr [[BASE:%.*]], [[BINDEX:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: ret void -// -void test_vsoxei32_v_f16m1(_Float16 *base, vuint32m2_t bindex, vfloat16m1_t value, size_t vl) { - return __riscv_vsoxei32_v_f16m1(base, bindex, value, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vle16ff_v_f16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = call { , i64 } @llvm.riscv.vleff.nxv4f16.i64( poison, ptr [[BASE:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: [[TMP1:%.*]] = extractvalue { , i64 } [[TMP0]], 0 -// CHECK-ZVFHMIN-NEXT: [[TMP2:%.*]] = extractvalue { , i64 } [[TMP0]], 1 -// CHECK-ZVFHMIN-NEXT: store i64 [[TMP2]], ptr [[NEW_VL:%.*]], align 8 -// CHECK-ZVFHMIN-NEXT: ret [[TMP1]] -// -vfloat16m1_t test_vle16ff_v_f16m1(const _Float16 *base, size_t *new_vl, size_t vl) { - return __riscv_vle16ff_v_f16m1(base, new_vl, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vlseg2e16_v_f16m1x2( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = call { , } @llvm.riscv.vlseg2.nxv4f16.i64( poison, poison, ptr [[BASE:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: ret { , } [[TMP0]] -// -vfloat16m1x2_t test_vlseg2e16_v_f16m1x2(const _Float16 *base, size_t vl) { - return __riscv_vlseg2e16_v_f16m1x2(base, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vlseg2e16ff_v_f16m1x2( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = call { , , i64 } @llvm.riscv.vlseg2ff.nxv4f16.i64( poison, poison, ptr [[BASE:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: [[TMP1:%.*]] = extractvalue { , , i64 } [[TMP0]], 0 -// CHECK-ZVFHMIN-NEXT: [[TMP2:%.*]] = insertvalue { , } poison, [[TMP1]], 0 -// CHECK-ZVFHMIN-NEXT: [[TMP3:%.*]] = extractvalue { , , i64 } [[TMP0]], 1 -// CHECK-ZVFHMIN-NEXT: [[TMP4:%.*]] = insertvalue { , } [[TMP2]], [[TMP3]], 1 -// CHECK-ZVFHMIN-NEXT: [[TMP5:%.*]] = extractvalue { , , i64 } [[TMP0]], 2 -// CHECK-ZVFHMIN-NEXT: store i64 [[TMP5]], ptr [[NEW_VL:%.*]], align 8 -// CHECK-ZVFHMIN-NEXT: ret { , } [[TMP4]] -// -vfloat16m1x2_t test_vlseg2e16ff_v_f16m1x2(const _Float16 *base, size_t *new_vl, size_t vl) { - return __riscv_vlseg2e16ff_v_f16m1x2(base, new_vl, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vlsseg2e16_v_f16m1x2( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = call { , } @llvm.riscv.vlsseg2.nxv4f16.i64( poison, poison, ptr [[BASE:%.*]], i64 [[BSTRIDE:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: ret { , } [[TMP0]] -// -vfloat16m1x2_t test_vlsseg2e16_v_f16m1x2(const _Float16 *base, ptrdiff_t bstride, size_t vl) { - return __riscv_vlsseg2e16_v_f16m1x2(base, bstride, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vluxseg2ei32_v_f16m1x2( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = call { , } @llvm.riscv.vluxseg2.nxv4f16.nxv4i32.i64( poison, poison, ptr [[BASE:%.*]], [[BINDEX:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: ret { , } [[TMP0]] -// -vfloat16m1x2_t test_vluxseg2ei32_v_f16m1x2(const _Float16 *base, vuint32m2_t bindex, size_t vl) { - return __riscv_vluxseg2ei32_v_f16m1x2(base, bindex, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vloxseg2ei32_v_f16m1x2( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = call { , } @llvm.riscv.vloxseg2.nxv4f16.nxv4i32.i64( poison, poison, ptr [[BASE:%.*]], [[BINDEX:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: ret { , } [[TMP0]] -// -vfloat16m1x2_t test_vloxseg2ei32_v_f16m1x2(const _Float16 *base, vuint32m2_t bindex, size_t vl) { - return __riscv_vloxseg2ei32_v_f16m1x2(base, bindex, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vmerge_vvm_f16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vmerge.nxv4f16.nxv4f16.i64( poison, [[OP1:%.*]], [[OP2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vmerge_vvm_f16m1(vfloat16m1_t op1, vfloat16m1_t op2, vbool16_t mask, size_t vl) { - return __riscv_vmerge(op1, op2, mask, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vmv_v_v_f16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vmv.v.v.nxv4f16.i64( poison, [[SRC:%.*]], i64 [[VL:%.*]]) -// CHECK-ZVFHMIN-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vmv_v_v_f16m1(vfloat16m1_t src, size_t vl) { - return __riscv_vmv_v(src, vl); -} - -// CHECK-ZVFHMIN-LABEL: @test_vreinterpret_v_f16m1_i16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = bitcast [[SRC:%.*]] to -// CHECK-ZVFHMIN-NEXT: ret [[TMP0]] -// -vint16m1_t test_vreinterpret_v_f16m1_i16m1(vfloat16m1_t src) { - return __riscv_vreinterpret_v_f16m1_i16m1(src); -} - -// CHECK-ZVFHMIN-LABEL: @test_vreinterpret_v_f16m1_u16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = bitcast [[SRC:%.*]] to -// CHECK-ZVFHMIN-NEXT: ret [[TMP0]] -// -vuint16m1_t test_vreinterpret_v_f16m1_u16m1(vfloat16m1_t src) { - return __riscv_vreinterpret_v_f16m1_u16m1(src); -} - -// CHECK-ZVFHMIN-LABEL: @test_vreinterpret_v_i16m1_f16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = bitcast [[SRC:%.*]] to -// CHECK-ZVFHMIN-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vreinterpret_v_i16m1_f16m1(vint16m1_t src) { - return __riscv_vreinterpret_v_i16m1_f16m1(src); -} - -// CHECK-ZVFHMIN-LABEL: @test_vreinterpret_v_u16m1_f16m1( -// CHECK-ZVFHMIN-NEXT: entry: -// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = bitcast [[SRC:%.*]] to -// CHECK-ZVFHMIN-NEXT: ret [[TMP0]] -// -vfloat16m1_t test_vreinterpret_v_u16m1_f16m1(vuint16m1_t src) { - return __riscv_vreinterpret_v_u16m1_f16m1(src); -} diff --git a/clang/test/CodeGen/SystemZ/systemz-abi.c b/clang/test/CodeGen/SystemZ/systemz-abi.c index 65a2bc9bbb680..3e39425e57f17 100644 --- a/clang/test/CodeGen/SystemZ/systemz-abi.c +++ b/clang/test/CodeGen/SystemZ/systemz-abi.c @@ -173,6 +173,29 @@ union union_double pass_union_double(union union_double arg) { return arg; } // CHECK-LABEL: define{{.*}} void @pass_union_double(ptr dead_on_unwind noalias writable sret(%union.union_double) align 8 %{{.*}}, i64 %{{.*}}) +// Verify that transparent unions are passed like their first member (but returned like a union) + +union tu_char { char a; } __attribute__((transparent_union)); +union tu_char pass_tu_char(union tu_char arg) { return arg; } +// CHECK-LABEL: define{{.*}} void @pass_tu_char(ptr dead_on_unwind noalias writable sret(%union.tu_char) align 1 %{{.*}}, i8 signext %{{.*}}) + +union tu_short { short a; } __attribute__((transparent_union)); +union tu_short pass_tu_short(union tu_short arg) { return arg; } +// CHECK-LABEL: define{{.*}} void @pass_tu_short(ptr dead_on_unwind noalias writable sret(%union.tu_short) align 2 %{{.*}}, i16 signext %{{.*}}) + +union tu_int { int a; } __attribute__((transparent_union)); +union tu_int pass_tu_int(union tu_int arg) { return arg; } +// CHECK-LABEL: define{{.*}} void @pass_tu_int(ptr dead_on_unwind noalias writable sret(%union.tu_int) align 4 %{{.*}}, i32 signext %{{.*}}) + +union tu_long { long a; } __attribute__((transparent_union)); +union tu_long pass_tu_long(union tu_long arg) { return arg; } +// CHECK-LABEL: define{{.*}} void @pass_tu_long(ptr dead_on_unwind noalias writable sret(%union.tu_long) align 8 %{{.*}}, i64 %{{.*}}) + +union tu_ptr { void *a; } __attribute__((transparent_union)); +union tu_ptr pass_tu_ptr(union tu_ptr arg) { return arg; } +// CHECK-LABEL: define{{.*}} void @pass_tu_ptr(ptr dead_on_unwind noalias writable sret(%union.tu_ptr) align 8 %{{.*}}, ptr %{{.*}}) + + // Accessing variable argument lists int va_int(__builtin_va_list l) { return __builtin_va_arg(l, int); } diff --git a/clang/test/CodeGen/X86/math-builtins.c b/clang/test/CodeGen/X86/math-builtins.c index d26db19574051..48465df21cca1 100644 --- a/clang/test/CodeGen/X86/math-builtins.c +++ b/clang/test/CodeGen/X86/math-builtins.c @@ -168,10 +168,10 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { /* math */ __builtin_acos(f); __builtin_acosf(f); __builtin_acosl(f); __builtin_acosf128(f); -// NO__ERRNO: declare double @acos(double noundef) [[READNONE]] -// NO__ERRNO: declare float @acosf(float noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @acosl(x86_fp80 noundef) [[READNONE]] -// NO__ERRNO: declare fp128 @acosf128(fp128 noundef) [[READNONE]] +// NO__ERRNO: declare double @llvm.acos.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.acos.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.acos.f80(x86_fp80) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare fp128 @llvm.acos.f128(fp128) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare double @acos(double noundef) [[NOT_READNONE]] // HAS_ERRNO: declare float @acosf(float noundef) [[NOT_READNONE]] // HAS_ERRNO: declare x86_fp80 @acosl(x86_fp80 noundef) [[NOT_READNONE]] @@ -190,10 +190,10 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { __builtin_asin(f); __builtin_asinf(f); __builtin_asinl(f); __builtin_asinf128(f); -// NO__ERRNO: declare double @asin(double noundef) [[READNONE]] -// NO__ERRNO: declare float @asinf(float noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @asinl(x86_fp80 noundef) [[READNONE]] -// NO__ERRNO: declare fp128 @asinf128(fp128 noundef) [[READNONE]] +// NO__ERRNO: declare double @llvm.asin.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.asin.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.asin.f80(x86_fp80) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare fp128 @llvm.asin.f128(fp128) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare double @asin(double noundef) [[NOT_READNONE]] // HAS_ERRNO: declare float @asinf(float noundef) [[NOT_READNONE]] // HAS_ERRNO: declare x86_fp80 @asinl(x86_fp80 noundef) [[NOT_READNONE]] @@ -212,10 +212,10 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { __builtin_atan(f); __builtin_atanf(f); __builtin_atanl(f); __builtin_atanf128(f); -// NO__ERRNO: declare double @atan(double noundef) [[READNONE]] -// NO__ERRNO: declare float @atanf(float noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @atanl(x86_fp80 noundef) [[READNONE]] -// NO__ERRNO: declare fp128 @atanf128(fp128 noundef) [[READNONE]] +// NO__ERRNO: declare double @llvm.atan.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.atan.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.atan.f80(x86_fp80) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare fp128 @llvm.atan.f128(fp128) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare double @atan(double noundef) [[NOT_READNONE]] // HAS_ERRNO: declare float @atanf(float noundef) [[NOT_READNONE]] // HAS_ERRNO: declare x86_fp80 @atanl(x86_fp80 noundef) [[NOT_READNONE]] @@ -267,10 +267,10 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { __builtin_cosh(f); __builtin_coshf(f); __builtin_coshl(f); __builtin_coshf128(f); -// NO__ERRNO: declare double @cosh(double noundef) [[READNONE]] -// NO__ERRNO: declare float @coshf(float noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @coshl(x86_fp80 noundef) [[READNONE]] -// NO__ERRNO: declare fp128 @coshf128(fp128 noundef) [[READNONE]] +// NO__ERRNO: declare double @llvm.cosh.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.cosh.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.cosh.f80(x86_fp80) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare fp128 @llvm.cosh.f128(fp128) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare double @cosh(double noundef) [[NOT_READNONE]] // HAS_ERRNO: declare float @coshf(float noundef) [[NOT_READNONE]] // HAS_ERRNO: declare x86_fp80 @coshl(x86_fp80 noundef) [[NOT_READNONE]] @@ -656,10 +656,10 @@ __builtin_sin(f); __builtin_sinf(f); __builtin_sinl(f); __builtin_s __builtin_sinh(f); __builtin_sinhf(f); __builtin_sinhl(f); __builtin_sinhf128(f); -// NO__ERRNO: declare double @sinh(double noundef) [[READNONE]] -// NO__ERRNO: declare float @sinhf(float noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @sinhl(x86_fp80 noundef) [[READNONE]] -// NO__ERRNO: declare fp128 @sinhf128(fp128 noundef) [[READNONE]] +// NO__ERRNO: declare double @llvm.sinh.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.sinh.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.sinh.f80(x86_fp80) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare fp128 @llvm.sinh.f128(fp128) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare double @sinh(double noundef) [[NOT_READNONE]] // HAS_ERRNO: declare float @sinhf(float noundef) [[NOT_READNONE]] // HAS_ERRNO: declare x86_fp80 @sinhl(x86_fp80 noundef) [[NOT_READNONE]] @@ -689,10 +689,10 @@ __builtin_tan(f); __builtin_tanf(f); __builtin_tanl(f); __builtin_t __builtin_tanh(f); __builtin_tanhf(f); __builtin_tanhl(f); __builtin_tanhf128(f); -// NO__ERRNO: declare double @tanh(double noundef) [[READNONE]] -// NO__ERRNO: declare float @tanhf(float noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @tanhl(x86_fp80 noundef) [[READNONE]] -// NO__ERRNO: declare fp128 @tanhf128(fp128 noundef) [[READNONE]] +// NO__ERRNO: declare double @llvm.tanh.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.tanh.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.tanh.f80(x86_fp80) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare fp128 @llvm.tanh.f128(fp128) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare double @tanh(double noundef) [[NOT_READNONE]] // HAS_ERRNO: declare float @tanhf(float noundef) [[NOT_READNONE]] // HAS_ERRNO: declare x86_fp80 @tanhl(x86_fp80 noundef) [[NOT_READNONE]] diff --git a/clang/test/CodeGen/X86/mmx-builtins.c b/clang/test/CodeGen/X86/mmx-builtins.c index 5b5bc301bddc0..495ae7e181159 100644 --- a/clang/test/CodeGen/X86/mmx-builtins.c +++ b/clang/test/CodeGen/X86/mmx-builtins.c @@ -1,193 +1,200 @@ -// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +ssse3 -emit-llvm -o - -Wall -Werror | FileCheck %s -// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +ssse3 -fno-signed-char -emit-llvm -o - -Wall -Werror | FileCheck %s +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +ssse3 -emit-llvm -o - -Wall -Werror | FileCheck %s --implicit-check-not=x86mmx +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +ssse3 -fno-signed-char -emit-llvm -o - -Wall -Werror | FileCheck %s --implicit-check-not=x86mmx #include __m64 test_mm_abs_pi8(__m64 a) { // CHECK-LABEL: test_mm_abs_pi8 - // CHECK: call x86_mmx @llvm.x86.ssse3.pabs.b + // CHECK: call <8 x i8> @llvm.abs.v8i8( return _mm_abs_pi8(a); } __m64 test_mm_abs_pi16(__m64 a) { // CHECK-LABEL: test_mm_abs_pi16 - // CHECK: call x86_mmx @llvm.x86.ssse3.pabs.w + // CHECK: call <4 x i16> @llvm.abs.v4i16( return _mm_abs_pi16(a); } __m64 test_mm_abs_pi32(__m64 a) { // CHECK-LABEL: test_mm_abs_pi32 - // CHECK: call x86_mmx @llvm.x86.ssse3.pabs.d + // CHECK: call <2 x i32> @llvm.abs.v2i32( return _mm_abs_pi32(a); } __m64 test_mm_add_pi8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_add_pi8 - // CHECK: call x86_mmx @llvm.x86.mmx.padd.b + // CHECK: add <8 x i8> {{%.*}}, {{%.*}} return _mm_add_pi8(a, b); } __m64 test_mm_add_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_add_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.padd.w + // CHECK: add <4 x i16> {{%.*}}, {{%.*}} return _mm_add_pi16(a, b); } __m64 test_mm_add_pi32(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_add_pi32 - // CHECK: call x86_mmx @llvm.x86.mmx.padd.d + // CHECK: add <2 x i32> {{%.*}}, {{%.*}} return _mm_add_pi32(a, b); } __m64 test_mm_add_si64(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_add_si64 - // CHECK: call x86_mmx @llvm.x86.mmx.padd.q(x86_mmx %{{.*}}, x86_mmx %{{.*}}) + // CHECK: add i64 {{%.*}}, {{%.*}} return _mm_add_si64(a, b); } __m64 test_mm_adds_pi8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_adds_pi8 - // CHECK: call x86_mmx @llvm.x86.mmx.padds.b + // CHECK: call <8 x i8> @llvm.sadd.sat.v8i8( return _mm_adds_pi8(a, b); } __m64 test_mm_adds_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_adds_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.padds.w + // CHECK: call <4 x i16> @llvm.sadd.sat.v4i16( return _mm_adds_pi16(a, b); } __m64 test_mm_adds_pu8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_adds_pu8 - // CHECK: call x86_mmx @llvm.x86.mmx.paddus.b + // CHECK: call <8 x i8> @llvm.uadd.sat.v8i8( return _mm_adds_pu8(a, b); } __m64 test_mm_adds_pu16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_adds_pu16 - // CHECK: call x86_mmx @llvm.x86.mmx.paddus.w + // CHECK: call <4 x i16> @llvm.uadd.sat.v4i16( return _mm_adds_pu16(a, b); } __m64 test_mm_alignr_pi8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_alignr_pi8 - // CHECK: call x86_mmx @llvm.x86.mmx.palignr.b + // CHECK: shufflevector <16 x i8> {{%.*}}, <16 x i8> zeroinitializer, <16 x i32> return _mm_alignr_pi8(a, b, 2); } __m64 test_mm_and_si64(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_and_si64 - // CHECK: call x86_mmx @llvm.x86.mmx.pand + // CHECK: and <1 x i64> {{%.*}}, {{%.*}} return _mm_and_si64(a, b); } __m64 test_mm_andnot_si64(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_andnot_si64 - // CHECK: call x86_mmx @llvm.x86.mmx.pandn + // CHECK: [[TMP:%.*]] = xor <1 x i64> {{%.*}}, + // CHECK: and <1 x i64> [[TMP]], {{%.*}} return _mm_andnot_si64(a, b); } __m64 test_mm_avg_pu8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_avg_pu8 - // CHECK: call x86_mmx @llvm.x86.mmx.pavg.b + // CHECK: call <16 x i8> @llvm.x86.sse2.pavg.b( return _mm_avg_pu8(a, b); } __m64 test_mm_avg_pu16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_avg_pu16 - // CHECK: call x86_mmx @llvm.x86.mmx.pavg.w + // CHECK: call <8 x i16> @llvm.x86.sse2.pavg.w( return _mm_avg_pu16(a, b); } __m64 test_mm_cmpeq_pi8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_cmpeq_pi8 - // CHECK: call x86_mmx @llvm.x86.mmx.pcmpeq.b + // CHECK: [[CMP:%.*]] = icmp eq <8 x i8> {{%.*}}, {{%.*}} + // CHECK-NEXT: {{%.*}} = sext <8 x i1> [[CMP]] to <8 x i8> return _mm_cmpeq_pi8(a, b); } __m64 test_mm_cmpeq_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_cmpeq_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.pcmpeq.w + // CHECK: [[CMP:%.*]] = icmp eq <4 x i16> {{%.*}}, {{%.*}} + // CHECK-NEXT: {{%.*}} = sext <4 x i1> [[CMP]] to <4 x i16> return _mm_cmpeq_pi16(a, b); } __m64 test_mm_cmpeq_pi32(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_cmpeq_pi32 - // CHECK: call x86_mmx @llvm.x86.mmx.pcmpeq.d + // CHECK: [[CMP:%.*]] = icmp eq <2 x i32> {{%.*}}, {{%.*}} + // CHECK-NEXT: {{%.*}} = sext <2 x i1> [[CMP]] to <2 x i32> return _mm_cmpeq_pi32(a, b); } __m64 test_mm_cmpgt_pi8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_cmpgt_pi8 - // CHECK: call x86_mmx @llvm.x86.mmx.pcmpgt.b + // CHECK: [[CMP:%.*]] = icmp sgt <8 x i8> {{%.*}}, {{%.*}} + // CHECK-NEXT: {{%.*}} = sext <8 x i1> [[CMP]] to <8 x i8> return _mm_cmpgt_pi8(a, b); } __m64 test_mm_cmpgt_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_cmpgt_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.pcmpgt.w + // CHECK: [[CMP:%.*]] = icmp sgt <4 x i16> {{%.*}}, {{%.*}} + // CHECK-NEXT: {{%.*}} = sext <4 x i1> [[CMP]] to <4 x i16> return _mm_cmpgt_pi16(a, b); } __m64 test_mm_cmpgt_pi32(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_cmpgt_pi32 - // CHECK: call x86_mmx @llvm.x86.mmx.pcmpgt.d + // CHECK: [[CMP:%.*]] = icmp sgt <2 x i32> {{%.*}}, {{%.*}} + // CHECK-NEXT: {{%.*}} = sext <2 x i1> [[CMP]] to <2 x i32> return _mm_cmpgt_pi32(a, b); } __m128 test_mm_cvt_pi2ps(__m128 a, __m64 b) { // CHECK-LABEL: test_mm_cvt_pi2ps - // CHECK: <4 x float> @llvm.x86.sse.cvtpi2ps + // CHECK: sitofp <4 x i32> {{%.*}} to <4 x float> return _mm_cvt_pi2ps(a, b); } __m64 test_mm_cvt_ps2pi(__m128 a) { // CHECK-LABEL: test_mm_cvt_ps2pi - // CHECK: call x86_mmx @llvm.x86.sse.cvtps2pi + // CHECK: call <4 x i32> @llvm.x86.sse2.cvtps2dq( return _mm_cvt_ps2pi(a); } __m64 test_mm_cvtpd_pi32(__m128d a) { // CHECK-LABEL: test_mm_cvtpd_pi32 - // CHECK: call x86_mmx @llvm.x86.sse.cvtpd2pi + // CHECK: call <4 x i32> @llvm.x86.sse2.cvtpd2dq( return _mm_cvtpd_pi32(a); } __m128 test_mm_cvtpi16_ps(__m64 a) { // CHECK-LABEL: test_mm_cvtpi16_ps - // CHECK: call <4 x float> @llvm.x86.sse.cvtpi2ps + // CHECK: sitofp <4 x i16> {{%.*}} to <4 x float> return _mm_cvtpi16_ps(a); } __m128d test_mm_cvtpi32_pd(__m64 a) { // CHECK-LABEL: test_mm_cvtpi32_pd - // CHECK: call <2 x double> @llvm.x86.sse.cvtpi2pd + // CHECK: sitofp <2 x i32> {{%.*}} to <2 x double> return _mm_cvtpi32_pd(a); } __m128 test_mm_cvtpi32_ps(__m128 a, __m64 b) { // CHECK-LABEL: test_mm_cvtpi32_ps - // CHECK: call <4 x float> @llvm.x86.sse.cvtpi2ps + // CHECK: sitofp <4 x i32> {{%.*}} to <4 x float> return _mm_cvtpi32_ps(a, b); } __m128 test_mm_cvtpi32x2_ps(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_cvtpi32x2_ps - // CHECK: call <4 x float> @llvm.x86.sse.cvtpi2ps - // CHECK: call <4 x float> @llvm.x86.sse.cvtpi2ps + // CHECK: sitofp <4 x i32> {{%.*}} to <4 x float> return _mm_cvtpi32x2_ps(a, b); } __m64 test_mm_cvtps_pi16(__m128 a) { // CHECK-LABEL: test_mm_cvtps_pi16 - // CHECK: call x86_mmx @llvm.x86.sse.cvtps2pi + // CHECK: [[TMP0:%.*]] = call <4 x i32> @llvm.x86.sse2.cvtps2dq(<4 x float> {{%.*}}) + // CHECK: call <8 x i16> @llvm.x86.sse2.packssdw.128(<4 x i32> [[TMP0]], return _mm_cvtps_pi16(a); } __m64 test_mm_cvtps_pi32(__m128 a) { // CHECK-LABEL: test_mm_cvtps_pi32 - // CHECK: call x86_mmx @llvm.x86.sse.cvtps2pi + // CHECK: call <4 x i32> @llvm.x86.sse2.cvtps2dq( return _mm_cvtps_pi32(a); } @@ -205,19 +212,19 @@ int test_mm_cvtsi64_si32(__m64 a) { __m64 test_mm_cvttpd_pi32(__m128d a) { // CHECK-LABEL: test_mm_cvttpd_pi32 - // CHECK: call x86_mmx @llvm.x86.sse.cvttpd2pi + // CHECK: call <4 x i32> @llvm.x86.sse2.cvttpd2dq( return _mm_cvttpd_pi32(a); } __m64 test_mm_cvttps_pi32(__m128 a) { // CHECK-LABEL: test_mm_cvttps_pi32 - // CHECK: call x86_mmx @llvm.x86.sse.cvttps2pi + // CHECK: call <4 x i32> @llvm.x86.sse2.cvttps2dq( return _mm_cvttps_pi32(a); } int test_mm_extract_pi16(__m64 a) { // CHECK-LABEL: test_mm_extract_pi16 - // CHECK: call i32 @llvm.x86.mmx.pextr.w + // CHECK: extractelement <4 x i16> {{%.*}}, i64 2 return _mm_extract_pi16(a, 2); } @@ -234,151 +241,153 @@ __m64 test_m_from_int64(long long a) { __m64 test_mm_hadd_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_hadd_pi16 - // CHECK: call x86_mmx @llvm.x86.ssse3.phadd.w + // CHECK: call <8 x i16> @llvm.x86.ssse3.phadd.w.128( return _mm_hadd_pi16(a, b); } __m64 test_mm_hadd_pi32(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_hadd_pi32 - // CHECK: call x86_mmx @llvm.x86.ssse3.phadd.d + // CHECK: call <4 x i32> @llvm.x86.ssse3.phadd.d.128( return _mm_hadd_pi32(a, b); } __m64 test_mm_hadds_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_hadds_pi16 - // CHECK: call x86_mmx @llvm.x86.ssse3.phadd.sw + // CHECK: call <8 x i16> @llvm.x86.ssse3.phadd.sw.128( return _mm_hadds_pi16(a, b); } __m64 test_mm_hsub_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_hsub_pi16 - // CHECK: call x86_mmx @llvm.x86.ssse3.phsub.w + // CHECK: call <8 x i16> @llvm.x86.ssse3.phsub.w.128( return _mm_hsub_pi16(a, b); } __m64 test_mm_hsub_pi32(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_hsub_pi32 - // CHECK: call x86_mmx @llvm.x86.ssse3.phsub.d + // CHECK: call <4 x i32> @llvm.x86.ssse3.phsub.d.128( return _mm_hsub_pi32(a, b); } __m64 test_mm_hsubs_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_hsubs_pi16 - // CHECK: call x86_mmx @llvm.x86.ssse3.phsub.sw + // CHECK: call <8 x i16> @llvm.x86.ssse3.phsub.sw.128( return _mm_hsubs_pi16(a, b); } __m64 test_mm_insert_pi16(__m64 a, int d) { // CHECK-LABEL: test_mm_insert_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.pinsr.w + // CHECK: insertelement <4 x i16> return _mm_insert_pi16(a, d, 2); } __m64 test_mm_madd_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_madd_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.pmadd.wd + // CHECK: call <4 x i32> @llvm.x86.sse2.pmadd.wd( return _mm_madd_pi16(a, b); } __m64 test_mm_maddubs_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_maddubs_pi16 - // CHECK: call x86_mmx @llvm.x86.ssse3.pmadd.ub.sw + // CHECK: call <8 x i16> @llvm.x86.ssse3.pmadd.ub.sw.128( return _mm_maddubs_pi16(a, b); } void test_mm_maskmove_si64(__m64 d, __m64 n, char *p) { // CHECK-LABEL: test_mm_maskmove_si64 - // CHECK: call void @llvm.x86.mmx.maskmovq + // CHECK: call void @llvm.x86.sse2.maskmov.dqu( _mm_maskmove_si64(d, n, p); } __m64 test_mm_max_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_max_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.pmaxs.w + // CHECK: call <4 x i16> @llvm.smax.v4i16( return _mm_max_pi16(a, b); } __m64 test_mm_max_pu8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_max_pu8 - // CHECK: call x86_mmx @llvm.x86.mmx.pmaxu.b + // CHECK: call <8 x i8> @llvm.umax.v8i8( return _mm_max_pu8(a, b); } __m64 test_mm_min_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_min_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.pmins.w + // CHECK: call <4 x i16> @llvm.smin.v4i16( return _mm_min_pi16(a, b); } __m64 test_mm_min_pu8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_min_pu8 - // CHECK: call x86_mmx @llvm.x86.mmx.pminu.b + // CHECK: call <8 x i8> @llvm.umin.v8i8( return _mm_min_pu8(a, b); } int test_mm_movemask_pi8(__m64 a) { // CHECK-LABEL: test_mm_movemask_pi8 - // CHECK: call i32 @llvm.x86.mmx.pmovmskb + // CHECK: call i32 @llvm.x86.sse2.pmovmskb.128( return _mm_movemask_pi8(a); } __m64 test_mm_mul_su32(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_mul_su32 - // CHECK: call x86_mmx @llvm.x86.mmx.pmulu.dq(x86_mmx %{{.*}}, x86_mmx %{{.*}}) + // CHECK: and <2 x i64> {{%.*}}, + // CHECK: and <2 x i64> {{%.*}}, + // CHECK: mul <2 x i64> %{{.*}}, %{{.*}} return _mm_mul_su32(a, b); } __m64 test_mm_mulhi_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_mulhi_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.pmulh.w + // CHECK: call <8 x i16> @llvm.x86.sse2.pmulh.w( return _mm_mulhi_pi16(a, b); } __m64 test_mm_mulhi_pu16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_mulhi_pu16 - // CHECK: call x86_mmx @llvm.x86.mmx.pmulhu.w + // CHECK: call <8 x i16> @llvm.x86.sse2.pmulhu.w( return _mm_mulhi_pu16(a, b); } __m64 test_mm_mulhrs_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_mulhrs_pi16 - // CHECK: call x86_mmx @llvm.x86.ssse3.pmul.hr.sw + // CHECK: call <8 x i16> @llvm.x86.ssse3.pmul.hr.sw.128( return _mm_mulhrs_pi16(a, b); } __m64 test_mm_mullo_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_mullo_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.pmull.w + // CHECK: mul <4 x i16> {{%.*}}, {{%.*}} return _mm_mullo_pi16(a, b); } __m64 test_mm_or_si64(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_or_si64 - // CHECK: call x86_mmx @llvm.x86.mmx.por + // CHECK: or <1 x i64> {{%.*}}, {{%.*}} return _mm_or_si64(a, b); } __m64 test_mm_packs_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_packs_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.packsswb + // CHECK: call <16 x i8> @llvm.x86.sse2.packsswb.128( return _mm_packs_pi16(a, b); } __m64 test_mm_packs_pi32(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_packs_pi32 - // CHECK: call x86_mmx @llvm.x86.mmx.packssdw + // CHECK: call <8 x i16> @llvm.x86.sse2.packssdw.128( return _mm_packs_pi32(a, b); } __m64 test_mm_packs_pu16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_packs_pu16 - // CHECK: call x86_mmx @llvm.x86.mmx.packuswb + // CHECK: call <16 x i8> @llvm.x86.sse2.packuswb.128( return _mm_packs_pu16(a, b); } __m64 test_mm_sad_pu8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_sad_pu8 - // CHECK: call x86_mmx @llvm.x86.mmx.psad.bw + // CHECK: call <2 x i64> @llvm.x86.sse2.psad.bw(<16 x i8> return _mm_sad_pu8(a, b); } @@ -471,187 +480,187 @@ __m64 test_mm_set1_pi32(int a) { __m64 test_mm_shuffle_pi8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_shuffle_pi8 - // CHECK: call x86_mmx @llvm.x86.ssse3.pshuf.b + // CHECK: call <16 x i8> @llvm.x86.ssse3.pshuf.b.128( return _mm_shuffle_pi8(a, b); } __m64 test_mm_shuffle_pi16(__m64 a) { // CHECK-LABEL: test_mm_shuffle_pi16 - // CHECK: call x86_mmx @llvm.x86.sse.pshuf.w + // CHECK: shufflevector <4 x i16> {{%.*}}, <4 x i16> {{%.*}}, <4 x i32> return _mm_shuffle_pi16(a, 3); } __m64 test_mm_sign_pi8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_sign_pi8 - // CHECK: call x86_mmx @llvm.x86.ssse3.psign.b + // CHECK: call <16 x i8> @llvm.x86.ssse3.psign.b.128( return _mm_sign_pi8(a, b); } __m64 test_mm_sign_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_sign_pi16 - // CHECK: call x86_mmx @llvm.x86.ssse3.psign.w + // CHECK: call <8 x i16> @llvm.x86.ssse3.psign.w.128( return _mm_sign_pi16(a, b); } __m64 test_mm_sign_pi32(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_sign_pi32 - // CHECK: call x86_mmx @llvm.x86.ssse3.psign.d + // CHECK: call <4 x i32> @llvm.x86.ssse3.psign.d.128( return _mm_sign_pi32(a, b); } __m64 test_mm_sll_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_sll_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.psll.w + // CHECK: call <8 x i16> @llvm.x86.sse2.psll.w( return _mm_sll_pi16(a, b); } __m64 test_mm_sll_pi32(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_sll_pi32 - // CHECK: call x86_mmx @llvm.x86.mmx.psll.d + // CHECK: call <4 x i32> @llvm.x86.sse2.psll.d( return _mm_sll_pi32(a, b); } __m64 test_mm_sll_si64(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_sll_si64 - // CHECK: call x86_mmx @llvm.x86.mmx.psll.q + // CHECK: call <2 x i64> @llvm.x86.sse2.psll.q( return _mm_sll_si64(a, b); } __m64 test_mm_slli_pi16(__m64 a) { // CHECK-LABEL: test_mm_slli_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.pslli.w + // CHECK: call <8 x i16> @llvm.x86.sse2.pslli.w( return _mm_slli_pi16(a, 3); } __m64 test_mm_slli_pi32(__m64 a) { // CHECK-LABEL: test_mm_slli_pi32 - // CHECK: call x86_mmx @llvm.x86.mmx.pslli.d + // CHECK: call <4 x i32> @llvm.x86.sse2.pslli.d( return _mm_slli_pi32(a, 3); } __m64 test_mm_slli_si64(__m64 a) { // CHECK-LABEL: test_mm_slli_si64 - // CHECK: call x86_mmx @llvm.x86.mmx.pslli.q + // CHECK: call <2 x i64> @llvm.x86.sse2.pslli.q( return _mm_slli_si64(a, 3); } __m64 test_mm_sra_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_sra_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.psra.w + // CHECK: call <8 x i16> @llvm.x86.sse2.psra.w( return _mm_sra_pi16(a, b); } __m64 test_mm_sra_pi32(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_sra_pi32 - // CHECK: call x86_mmx @llvm.x86.mmx.psra.d + // CHECK: call <4 x i32> @llvm.x86.sse2.psra.d( return _mm_sra_pi32(a, b); } __m64 test_mm_srai_pi16(__m64 a) { // CHECK-LABEL: test_mm_srai_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.psrai.w + // CHECK: call <8 x i16> @llvm.x86.sse2.psrai.w( return _mm_srai_pi16(a, 3); } __m64 test_mm_srai_pi32(__m64 a) { // CHECK-LABEL: test_mm_srai_pi32 - // CHECK: call x86_mmx @llvm.x86.mmx.psrai.d + // CHECK: call <4 x i32> @llvm.x86.sse2.psrai.d( return _mm_srai_pi32(a, 3); } __m64 test_mm_srl_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_srl_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.psrl.w + // CHECK: call <8 x i16> @llvm.x86.sse2.psrl.w( return _mm_srl_pi16(a, b); } __m64 test_mm_srl_pi32(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_srl_pi32 - // CHECK: call x86_mmx @llvm.x86.mmx.psrl.d + // CHECK: call <4 x i32> @llvm.x86.sse2.psrl.d( return _mm_srl_pi32(a, b); } __m64 test_mm_srl_si64(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_srl_si64 - // CHECK: call x86_mmx @llvm.x86.mmx.psrl.q + // CHECK: call <2 x i64> @llvm.x86.sse2.psrl.q( return _mm_srl_si64(a, b); } __m64 test_mm_srli_pi16(__m64 a) { // CHECK-LABEL: test_mm_srli_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.psrli.w + // CHECK: call <8 x i16> @llvm.x86.sse2.psrli.w( return _mm_srli_pi16(a, 3); } __m64 test_mm_srli_pi32(__m64 a) { // CHECK-LABEL: test_mm_srli_pi32 - // CHECK: call x86_mmx @llvm.x86.mmx.psrli.d + // CHECK: call <4 x i32> @llvm.x86.sse2.psrli.d( return _mm_srli_pi32(a, 3); } __m64 test_mm_srli_si64(__m64 a) { // CHECK-LABEL: test_mm_srli_si64 - // CHECK: call x86_mmx @llvm.x86.mmx.psrli.q + // CHECK: call <2 x i64> @llvm.x86.sse2.psrli.q( return _mm_srli_si64(a, 3); } void test_mm_stream_pi(__m64 *p, __m64 a) { // CHECK-LABEL: test_mm_stream_pi - // CHECK: call void @llvm.x86.mmx.movnt.dq + // CHECK: store <1 x i64> {{%.*}}, ptr {{%.*}}, align 8, !nontemporal _mm_stream_pi(p, a); } void test_mm_stream_pi_void(void *p, __m64 a) { // CHECK-LABEL: test_mm_stream_pi_void - // CHECK: call void @llvm.x86.mmx.movnt.dq + // CHECK: store <1 x i64> {{%.*}}, ptr {{%.*}}, align 8, !nontemporal _mm_stream_pi(p, a); } __m64 test_mm_sub_pi8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_sub_pi8 - // CHECK: call x86_mmx @llvm.x86.mmx.psub.b + // CHECK: sub <8 x i8> {{%.*}}, {{%.*}} return _mm_sub_pi8(a, b); } __m64 test_mm_sub_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_sub_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.psub.w + // CHECK: sub <4 x i16> {{%.*}}, {{%.*}} return _mm_sub_pi16(a, b); } __m64 test_mm_sub_pi32(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_sub_pi32 - // CHECK: call x86_mmx @llvm.x86.mmx.psub.d + // CHECK: sub <2 x i32> {{%.*}}, {{%.*}} return _mm_sub_pi32(a, b); } __m64 test_mm_sub_si64(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_sub_si64 - // CHECK: call x86_mmx @llvm.x86.mmx.psub.q(x86_mmx %{{.*}}, x86_mmx %{{.*}}) + // CHECK: sub i64 {{%.*}}, {{%.*}} return _mm_sub_si64(a, b); } __m64 test_mm_subs_pi8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_subs_pi8 - // CHECK: call x86_mmx @llvm.x86.mmx.psubs.b + // CHECK: call <8 x i8> @llvm.ssub.sat.v8i8( return _mm_subs_pi8(a, b); } __m64 test_mm_subs_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_subs_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.psubs.w + // CHECK: call <4 x i16> @llvm.ssub.sat.v4i16( return _mm_subs_pi16(a, b); } __m64 test_mm_subs_pu8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_subs_pu8 - // CHECK: call x86_mmx @llvm.x86.mmx.psubus.b + // CHECK: call <8 x i8> @llvm.usub.sat.v8i8( return _mm_subs_pu8(a, b); } __m64 test_mm_subs_pu16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_subs_pu16 - // CHECK: call x86_mmx @llvm.x86.mmx.psubus.w + // CHECK: call <4 x i16> @llvm.usub.sat.v4i16( return _mm_subs_pu16(a, b); } @@ -668,42 +677,42 @@ long long test_m_to_int64(__m64 a) { __m64 test_mm_unpackhi_pi8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_unpackhi_pi8 - // CHECK: call x86_mmx @llvm.x86.mmx.punpckhbw + // CHECK: shufflevector <8 x i8> {{%.*}}, <8 x i8> {{%.*}}, <8 x i32> return _mm_unpackhi_pi8(a, b); } __m64 test_mm_unpackhi_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_unpackhi_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.punpckhwd + // CHECK: shufflevector <4 x i16> {{%.*}}, <4 x i16> {{%.*}}, <4 x i32> return _mm_unpackhi_pi16(a, b); } __m64 test_mm_unpackhi_pi32(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_unpackhi_pi32 - // CHECK: call x86_mmx @llvm.x86.mmx.punpckhdq + // CHECK: shufflevector <2 x i32> {{%.*}}, <2 x i32> {{%.*}}, <2 x i32> return _mm_unpackhi_pi32(a, b); } __m64 test_mm_unpacklo_pi8(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_unpacklo_pi8 - // CHECK: call x86_mmx @llvm.x86.mmx.punpcklbw + // CHECK: shufflevector <8 x i8> {{%.*}}, <8 x i8> {{%.*}}, <8 x i32> return _mm_unpacklo_pi8(a, b); } __m64 test_mm_unpacklo_pi16(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_unpacklo_pi16 - // CHECK: call x86_mmx @llvm.x86.mmx.punpcklwd + // CHECK: shufflevector <4 x i16> {{%.*}}, <4 x i16> {{%.*}}, <4 x i32> return _mm_unpacklo_pi16(a, b); } __m64 test_mm_unpacklo_pi32(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_unpacklo_pi32 - // CHECK: call x86_mmx @llvm.x86.mmx.punpckldq + // CHECK: shufflevector <2 x i32> {{%.*}}, <2 x i32> {{%.*}}, <2 x i32> return _mm_unpacklo_pi32(a, b); } __m64 test_mm_xor_si64(__m64 a, __m64 b) { // CHECK-LABEL: test_mm_xor_si64 - // CHECK: call x86_mmx @llvm.x86.mmx.pxor + // CHECK: xor <1 x i64> {{%.*}}, {{%.*}} return _mm_xor_si64(a, b); } diff --git a/clang/test/CodeGen/X86/mmx-inline-asm.c b/clang/test/CodeGen/X86/mmx-inline-asm.c index 19c24a3a91e14..17fce1a48755e 100644 --- a/clang/test/CodeGen/X86/mmx-inline-asm.c +++ b/clang/test/CodeGen/X86/mmx-inline-asm.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -emit-llvm -triple i386 -target-feature +mmx %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -triple i386 -target-feature +mmx -target-feature +sse2 %s -o - | FileCheck %s #include -// CHECK: { x86_mmx, x86_mmx, x86_mmx, x86_mmx, x86_mmx, x86_mmx, x86_mmx } +// CHECK: { <1 x i64>, <1 x i64>, <1 x i64>, <1 x i64>, <1 x i64>, <1 x i64>, <1 x i64> } void foo(long long fill) { __m64 vfill = _mm_cvtsi64_m64(fill); diff --git a/clang/test/CodeGen/X86/mmx-shift-with-immediate.c b/clang/test/CodeGen/X86/mmx-shift-with-immediate.c index 83be6b5517c01..741cb9c9c5ecf 100644 --- a/clang/test/CodeGen/X86/mmx-shift-with-immediate.c +++ b/clang/test/CodeGen/X86/mmx-shift-with-immediate.c @@ -1,23 +1,23 @@ -// RUN: %clang_cc1 -emit-llvm -triple i386 -target-feature +mmx %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -triple i386 -target-feature +sse2 %s -o - | FileCheck %s #include void shift(__m64 a, __m64 b, int c) { - // CHECK: x86_mmx @llvm.x86.mmx.pslli.w(x86_mmx %{{.*}}, i32 {{.*}}) + // CHECK: <8 x i16> @llvm.x86.sse2.pslli.w(<8 x i16> %{{.*}}, i32 {{.*}}) _mm_slli_pi16(a, c); - // CHECK: x86_mmx @llvm.x86.mmx.pslli.d(x86_mmx %{{.*}}, i32 {{.*}}) + // CHECK: <4 x i32> @llvm.x86.sse2.pslli.d(<4 x i32> %{{.*}}, i32 {{.*}}) _mm_slli_pi32(a, c); - // CHECK: x86_mmx @llvm.x86.mmx.pslli.q(x86_mmx %{{.*}}, i32 {{.*}}) + // CHECK: <2 x i64> @llvm.x86.sse2.pslli.q(<2 x i64> %{{.*}}, i32 {{.*}}) _mm_slli_si64(a, c); - // CHECK: x86_mmx @llvm.x86.mmx.psrli.w(x86_mmx %{{.*}}, i32 {{.*}}) + // CHECK: <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16> %{{.*}}, i32 {{.*}}) _mm_srli_pi16(a, c); - // CHECK: x86_mmx @llvm.x86.mmx.psrli.d(x86_mmx %{{.*}}, i32 {{.*}}) + // CHECK: <4 x i32> @llvm.x86.sse2.psrli.d(<4 x i32> %{{.*}}, i32 {{.*}}) _mm_srli_pi32(a, c); - // CHECK: x86_mmx @llvm.x86.mmx.psrli.q(x86_mmx %{{.*}}, i32 {{.*}}) + // CHECK: <2 x i64> @llvm.x86.sse2.psrli.q(<2 x i64> %{{.*}}, i32 {{.*}}) _mm_srli_si64(a, c); - // CHECK: x86_mmx @llvm.x86.mmx.psrai.w(x86_mmx %{{.*}}, i32 {{.*}}) + // CHECK: <8 x i16> @llvm.x86.sse2.psrai.w(<8 x i16> %{{.*}}, i32 {{.*}}) _mm_srai_pi16(a, c); - // CHECK: x86_mmx @llvm.x86.mmx.psrai.d(x86_mmx %{{.*}}, i32 {{.*}}) + // CHECK: <4 x i32> @llvm.x86.sse2.psrai.d(<4 x i32> %{{.*}}, i32 {{.*}}) _mm_srai_pi32(a, c); } diff --git a/clang/test/CodeGen/aarch64-fmv-resolver-emission.c b/clang/test/CodeGen/aarch64-fmv-resolver-emission.c new file mode 100644 index 0000000000000..eeafb3d41860d --- /dev/null +++ b/clang/test/CodeGen/aarch64-fmv-resolver-emission.c @@ -0,0 +1,111 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s + +// CHECK: @used_before_default_def = weak_odr ifunc void (), ptr @used_before_default_def.resolver +// CHECK: @used_after_default_def = weak_odr ifunc void (), ptr @used_after_default_def.resolver +// CHECK-NOT: @used_before_default_decl = weak_odr ifunc void (), ptr @used_before_default_decl.resolver +// CHECK-NOT: @used_after_default_decl = weak_odr ifunc void (), ptr @used_after_default_decl.resolver +// CHECK-NOT: @used_no_default = weak_odr ifunc void (), ptr @used_no_default.resolver +// CHECK-NOT: @not_used_no_default = weak_odr ifunc void (), ptr @not_used_no_default.resolver +// CHECK: @not_used_with_default = weak_odr ifunc void (), ptr @not_used_with_default.resolver + + +// Test that an ifunc is generated and used when the default +// version is defined after the first use of the function. +// +__attribute__((target_version("aes"))) void used_before_default_def(void) {} +// CHECK-LABEL: define dso_local void @used_before_default_def._Maes( +// +void call_before_def(void) { used_before_default_def(); } +// CHECK-LABEL: define dso_local void @call_before_def( +// CHECK: call void @used_before_default_def() +// +__attribute__((target_version("default"))) void used_before_default_def(void) {} +// CHECK-LABEL: define dso_local void @used_before_default_def.default( +// +// CHECK-NOT: declare void @used_before_default_def( + + +// Test that an ifunc is generated and used when the default +// version is defined before the first use of the function. +// +__attribute__((target_version("aes"))) void used_after_default_def(void) {} +// CHECK-LABEL: define dso_local void @used_after_default_def._Maes( +// +__attribute__((target_version("default"))) void used_after_default_def(void) {} +// CHECK-LABEL: define dso_local void @used_after_default_def.default( +// +void call_after_def(void) { used_after_default_def(); } +// CHECK-LABEL: define dso_local void @call_after_def( +// CHECK: call void @used_after_default_def() +// +// CHECK-NOT: declare void @used_after_default_def( + + +// Test that an unmagled declaration is generated and used when the +// default version is declared after the first use of the function. +// +__attribute__((target_version("aes"))) void used_before_default_decl(void) {} +// CHECK-LABEL: define dso_local void @used_before_default_decl._Maes( +// +void call_before_decl(void) { used_before_default_decl(); } +// CHECK-LABEL: define dso_local void @call_before_decl( +// CHECK: call void @used_before_default_decl() +// +__attribute__((target_version("default"))) void used_before_default_decl(void); +// CHECK: declare void @used_before_default_decl() + + +// Test that an unmagled declaration is generated and used when the +// default version is declared before the first use of the function. +// +__attribute__((target_version("aes"))) void used_after_default_decl(void) {} +// CHECK-LABEL: define dso_local void @used_after_default_decl._Maes( +// +__attribute__((target_version("default"))) void used_after_default_decl(void); +// CHECK: declare void @used_after_default_decl() +// +void call_after_decl(void) { used_after_default_decl(); } +// CHECK-LABEL: define dso_local void @call_after_decl( +// CHECK: call void @used_after_default_decl() + + +// Test that an unmagled declaration is generated and used when +// the default version is not present. +// +__attribute__((target_version("aes"))) void used_no_default(void) {} +// CHECK-LABEL: define dso_local void @used_no_default._Maes( +// +void call_no_default(void) { used_no_default(); } +// CHECK-LABEL: define dso_local void @call_no_default( +// CHECK: call void @used_no_default() +// +// CHECK: declare void @used_no_default() + + +// Test that neither an ifunc nor a declaration is generated if the default +// definition is missing since the versioned function is not used. +// +__attribute__((target_version("aes"))) void not_used_no_default(void) {} +// CHECK-LABEL: define dso_local void @not_used_no_default._Maes( +// +// CHECK-NOT: declare void @not_used_no_default( + + +// Test that an ifunc is generated if the default version is defined but not used. +// +__attribute__((target_version("aes"))) void not_used_with_default(void) {} +// CHECK-LABEL: define dso_local void @not_used_with_default._Maes( +// +__attribute__((target_version("default"))) void not_used_with_default(void) {} +// CHECK-LABEL: define dso_local void @not_used_with_default.default( +// +// CHECK-NOT: declare void @not_used_with_default( + + +// CHECK: define weak_odr ptr @used_before_default_def.resolver() +// CHECK: define weak_odr ptr @used_after_default_def.resolver() +// CHECK-NOT: define weak_odr ptr @used_before_default_decl.resolver( +// CHECK-NOT: define weak_odr ptr @used_after_default_decl.resolver( +// CHECK-NOT: define weak_odr ptr @used_no_default.resolver( +// CHECK-NOT: define weak_odr ptr @not_used_no_default.resolver( +// CHECK: define weak_odr ptr @not_used_with_default.resolver() diff --git a/clang/test/CodeGen/aarch64-fmv-streaming.c b/clang/test/CodeGen/aarch64-fmv-streaming.c new file mode 100644 index 0000000000000..e549ccda59ad8 --- /dev/null +++ b/clang/test/CodeGen/aarch64-fmv-streaming.c @@ -0,0 +1,107 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -emit-llvm -o - %s | FileCheck %s + + +// CHECK-LABEL: define {{[^@]+}}@n_callee._Msve +// CHECK-SAME: () #[[ATTR0:[0-9]+]] { +// +// CHECK-LABEL: define {{[^@]+}}@n_callee._Msimd +// CHECK-SAME: () #[[ATTR1:[0-9]+]] { +// +__arm_locally_streaming __attribute__((target_clones("sve", "simd"))) void n_callee(void) {} +// CHECK-LABEL: define {{[^@]+}}@n_callee._Msme2 +// CHECK-SAME: () #[[ATTR2:[0-9]+]] { +// +__attribute__((target_version("sme2"))) void n_callee(void) {} +// CHECK-LABEL: define {{[^@]+}}@n_callee.default +// CHECK-SAME: () #[[ATTR3:[0-9]+]] { +// +__attribute__((target_version("default"))) void n_callee(void) {} + + +// CHECK-LABEL: define {{[^@]+}}@s_callee._Msve +// CHECK-SAME: () #[[ATTR4:[0-9]+]] { +// +// CHECK-LABEL: define {{[^@]+}}@s_callee._Msimd +// CHECK-SAME: () #[[ATTR5:[0-9]+]] { +// +__attribute__((target_clones("sve", "simd"))) void s_callee(void) __arm_streaming {} +// CHECK-LABEL: define {{[^@]+}}@s_callee._Msme2 +// CHECK-SAME: () #[[ATTR6:[0-9]+]] { +// +__arm_locally_streaming __attribute__((target_version("sme2"))) void s_callee(void) __arm_streaming {} +// CHECK-LABEL: define {{[^@]+}}@s_callee.default +// CHECK-SAME: () #[[ATTR7:[0-9]+]] { +// +__attribute__((target_version("default"))) void s_callee(void) __arm_streaming {} + + +// CHECK-LABEL: define {{[^@]+}}@sc_callee._Msve +// CHECK-SAME: () #[[ATTR8:[0-9]+]] { +// +// CHECK-LABEL: define {{[^@]+}}@sc_callee._Msimd +// CHECK-SAME: () #[[ATTR9:[0-9]+]] { +// +__attribute__((target_clones("sve", "simd"))) void sc_callee(void) __arm_streaming_compatible {} +// CHECK-LABEL: define {{[^@]+}}@sc_callee._Msme2 +// CHECK-SAME: () #[[ATTR10:[0-9]+]] { +// +__arm_locally_streaming __attribute__((target_version("sme2"))) void sc_callee(void) __arm_streaming_compatible {} +// CHECK-LABEL: define {{[^@]+}}@sc_callee.default +// CHECK-SAME: () #[[ATTR11:[0-9]+]] { +// +__attribute__((target_version("default"))) void sc_callee(void) __arm_streaming_compatible {} + + +// CHECK-LABEL: define {{[^@]+}}@n_caller +// CHECK-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK: call void @n_callee() +// CHECK: call void @s_callee() #[[ATTR12:[0-9]+]] +// CHECK: call void @sc_callee() #[[ATTR13:[0-9]+]] +// +void n_caller(void) { + n_callee(); + s_callee(); + sc_callee(); +} + + +// CHECK-LABEL: define {{[^@]+}}@s_caller +// CHECK-SAME: () #[[ATTR7:[0-9]+]] { +// CHECK: call void @n_callee() +// CHECK: call void @s_callee() #[[ATTR12]] +// CHECK: call void @sc_callee() #[[ATTR13]] +// +void s_caller(void) __arm_streaming { + n_callee(); + s_callee(); + sc_callee(); +} + + +// CHECK-LABEL: define {{[^@]+}}@sc_caller +// CHECK-SAME: () #[[ATTR11:[0-9]+]] { +// CHECK: call void @n_callee() +// CHECK: call void @s_callee() #[[ATTR12]] +// CHECK: call void @sc_callee() #[[ATTR13]] +// +void sc_caller(void) __arm_streaming_compatible { + n_callee(); + s_callee(); + sc_callee(); +} + + +// CHECK: attributes #[[ATTR0:[0-9]+]] = {{.*}} "aarch64_pstate_sm_body" +// CHECK: attributes #[[ATTR1:[0-9]+]] = {{.*}} "aarch64_pstate_sm_body" +// CHECK: attributes #[[ATTR2:[0-9]+]] = {{.*}} +// CHECK: attributes #[[ATTR3]] = {{.*}} +// CHECK: attributes #[[ATTR4:[0-9]+]] = {{.*}} "aarch64_pstate_sm_enabled" +// CHECK: attributes #[[ATTR5:[0-9]+]] = {{.*}} "aarch64_pstate_sm_enabled" +// CHECK: attributes #[[ATTR6:[0-9]+]] = {{.*}} "aarch64_pstate_sm_body" "aarch64_pstate_sm_enabled" +// CHECK: attributes #[[ATTR7]] = {{.*}} "aarch64_pstate_sm_enabled" +// CHECK: attributes #[[ATTR8:[0-9]+]] = {{.*}} "aarch64_pstate_sm_compatible" +// CHECK: attributes #[[ATTR9:[0-9]+]] = {{.*}} "aarch64_pstate_sm_compatible" +// CHECK: attributes #[[ATTR10]] = {{.*}} "aarch64_pstate_sm_body" "aarch64_pstate_sm_compatible" +// CHECK: attributes #[[ATTR11]] = {{.*}} "aarch64_pstate_sm_compatible" +// CHECK: attributes #[[ATTR12]] = {{.*}} "aarch64_pstate_sm_enabled" +// CHECK: attributes #[[ATTR13]] = {{.*}} "aarch64_pstate_sm_compatible" diff --git a/clang/test/CodeGen/aarch64-mixed-target-attributes.c b/clang/test/CodeGen/aarch64-mixed-target-attributes.c index 3c047fec6ceed..d779abd395b5f 100644 --- a/clang/test/CodeGen/aarch64-mixed-target-attributes.c +++ b/clang/test/CodeGen/aarch64-mixed-target-attributes.c @@ -261,9 +261,9 @@ __attribute__((target_version("jscvt"))) int default_def_with_version_decls(void // CHECK: attributes #[[ATTR3]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse,-v9.5a" } // CHECK: attributes #[[ATTR4]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rdm,-v9.5a" } // CHECK: attributes #[[ATTR5:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR6:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+jsconv,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR7:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-v9.5a" } -// CHECK: attributes #[[ATTR8:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse,-v9.5a" } +// CHECK: attributes #[[ATTR6:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-v9.5a" } +// CHECK: attributes #[[ATTR7:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse,-v9.5a" } +// CHECK: attributes #[[ATTR8:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+jsconv,+neon,-v9.5a" } //. // CHECK-NOFMV: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fmv" } //. diff --git a/clang/test/CodeGen/aarch64-sme-inline-streaming-attrs.c b/clang/test/CodeGen/aarch64-sme-inline-streaming-attrs.c index 25aebeced9379..9c3d08a25945a 100644 --- a/clang/test/CodeGen/aarch64-sme-inline-streaming-attrs.c +++ b/clang/test/CodeGen/aarch64-sme-inline-streaming-attrs.c @@ -3,6 +3,8 @@ // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -S -o /dev/null -target-feature +sme -verify -DTEST_STREAMING %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -S -o /dev/null -target-feature +sme -verify -DTEST_LOCALLY %s +// REQUIRES: aarch64-registered-target + #define __ai __attribute__((always_inline)) __ai void inlined_fn(void) {} __ai void inlined_fn_streaming_compatible(void) __arm_streaming_compatible {} @@ -20,7 +22,7 @@ void caller(void) { #ifdef TEST_COMPATIBLE void caller_compatible(void) __arm_streaming_compatible { - inlined_fn(); // expected-error {{always_inline function 'inlined_fn' and its caller 'caller_compatible' have mismatching streaming attributes}} + inlined_fn(); // expected-warning {{always_inline function 'inlined_fn' and its caller 'caller_compatible' have mismatching streaming attributes, inlining may change runtime behaviour}} inlined_fn_streaming_compatible(); inlined_fn_streaming(); // expected-error {{always_inline function 'inlined_fn_streaming' and its caller 'caller_compatible' have mismatching streaming attributes}} inlined_fn_local(); // expected-error {{always_inline function 'inlined_fn_local' and its caller 'caller_compatible' have mismatching streaming attributes}} @@ -29,7 +31,7 @@ void caller_compatible(void) __arm_streaming_compatible { #ifdef TEST_STREAMING void caller_streaming(void) __arm_streaming { - inlined_fn(); // expected-error {{always_inline function 'inlined_fn' and its caller 'caller_streaming' have mismatching streaming attributes}} + inlined_fn(); // expected-warning {{always_inline function 'inlined_fn' and its caller 'caller_streaming' have mismatching streaming attributes, inlining may change runtime behaviour}} inlined_fn_streaming_compatible(); inlined_fn_streaming(); inlined_fn_local(); @@ -39,7 +41,7 @@ void caller_streaming(void) __arm_streaming { #ifdef TEST_LOCALLY __arm_locally_streaming void caller_local(void) { - inlined_fn(); // expected-error {{always_inline function 'inlined_fn' and its caller 'caller_local' have mismatching streaming attributes}} + inlined_fn(); // expected-warning {{always_inline function 'inlined_fn' and its caller 'caller_local' have mismatching streaming attributes, inlining may change runtime behaviour}} inlined_fn_streaming_compatible(); inlined_fn_streaming(); inlined_fn_local(); diff --git a/clang/test/CodeGen/aix-builtin-cpu-is.c b/clang/test/CodeGen/aix-builtin-cpu-is.c index e17cf7353511a..83e8c99e0a78d 100644 --- a/clang/test/CodeGen/aix-builtin-cpu-is.c +++ b/clang/test/CodeGen/aix-builtin-cpu-is.c @@ -1,55 +1,67 @@ -// RUN: echo "int main() { return __builtin_cpu_is(\"ppc970\");}" > %t.c +// RUN: echo "int main() { return __builtin_cpu_is(\"ppc970\");}" > %t.c // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -// RUN: echo "int main() { return __builtin_cpu_is(\"ppc-cell-be\");}" > %t.c +// RUN: echo "int main() { return __builtin_cpu_is(\"ppc-cell-be\");}" > %t.c // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -// RUN: echo "int main() { return __builtin_cpu_is(\"ppca2\");}" > %t.c +// RUN: echo "int main() { return __builtin_cpu_is(\"ppca2\");}" > %t.c // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -// RUN: echo "int main() { return __builtin_cpu_is(\"ppc405\");}" > %t.c +// RUN: echo "int main() { return __builtin_cpu_is(\"ppc405\");}" > %t.c // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -// RUN: echo "int main() { return __builtin_cpu_is(\"ppc440\");}" > %t.c +// RUN: echo "int main() { return __builtin_cpu_is(\"ppc440\");}" > %t.c // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -// RUN: echo "int main() { return __builtin_cpu_is(\"ppc464\");}" > %t.c +// RUN: echo "int main() { return __builtin_cpu_is(\"ppc464\");}" > %t.c // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -// RUN: echo "int main() { return __builtin_cpu_is(\"ppc476\");}" > %t.c +// RUN: echo "int main() { return __builtin_cpu_is(\"ppc476\");}" > %t.c // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -// RUN: echo "int main() { return __builtin_cpu_is(\"power4\");}" > %t.c +// RUN: echo "int main() { return __builtin_cpu_is(\"power4\");}" > %t.c // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -// RUN: echo "int main() { return __builtin_cpu_is(\"power5\");}" > %t.c +// RUN: echo "int main() { return __builtin_cpu_is(\"power5\");}" > %t.c // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -// RUN: echo "int main() { return __builtin_cpu_is(\"power5+\");}" > %t.c +// RUN: echo "int main() { return __builtin_cpu_is(\"power5+\");}" > %t.c // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -// RUN: echo "int main() { return __builtin_cpu_is(\"power6\");}" > %t.c +// RUN: echo "int main() { return __builtin_cpu_is(\"power6\");}" > %t.c // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -// RUN: echo "int main() { return __builtin_cpu_is(\"power6x\");}" > %t.c +// RUN: echo "int main() { return __builtin_cpu_is(\"power6x\");}" > %t.c // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -// RUN: echo "int main() { return __builtin_cpu_is(\"power7\");}" > %t.c +// RUN: echo "int main() { return __builtin_cpu_is(\"power7\");}" > %t.c // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=32768 \ // RUN: --check-prefix=CHECKOP -// RUN: echo "int main() { return __builtin_cpu_is(\"power8\");}" > %t.c +// RUN: echo "int main() { return __builtin_cpu_is(\"pwr7\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=32768 \ +// RUN: --check-prefix=CHECKOP + +// RUN: echo "int main() { return __builtin_cpu_is(\"power8\");}" > %t.c // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=65536 \ // RUN: --check-prefix=CHECKOP -// RUN: echo "int main() { return __builtin_cpu_is(\"power9\");}" > %t.c +// RUN: echo "int main() { return __builtin_cpu_is(\"power9\");}" > %t.c // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=131072\ // RUN: --check-prefix=CHECKOP -// RUN: echo "int main() { return __builtin_cpu_is(\"power10\");}" > %t.c +// RUN: echo "int main() { return __builtin_cpu_is(\"power10\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=262144 \ +// RUN: --check-prefix=CHECKOP + +// RUN: echo "int main() { return __builtin_cpu_is(\"pwr10\");}" > %t.c // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=262144 \ // RUN: --check-prefix=CHECKOP +// RUN: echo "int main() { return __builtin_cpu_is(\"power11\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=524288 \ +// RUN: --check-prefix=CHECKOP + // CHECK: define i32 @main() #0 { // CHECK-NEXT: entry: // CHECK-NEXT: %retval = alloca i32, align 4 @@ -63,7 +75,7 @@ // CHECKOP-NEXT: %retval = alloca i32, align 4 // CHECKOP-NEXT: store i32 0, ptr %retval, align 4 // CHECKOP-NEXT: %0 = load i32, ptr getelementptr inbounds ({ i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i64, i32, i32, i32, i32, i64, i64, i64, i64, i32, i32, i32, i32, i32, i32, i64, i32, i8, i8, i8, i8, i32, i32, i16, i16, [3 x i32], i32 }, ptr @_system_configuration, i32 0, i32 1), align 4 -// CHECKOP-NEXT: %1 = icmp eq i32 %0, [[VALUE]] +// CHECKOP-NEXT: %1 = icmp eq i32 %0, [[VALUE]] // CHECKOP-NEXT: %conv = zext i1 %1 to i32 // CHECKOP-NEXT: ret i32 %conv // CHECKOP-NEXT: } diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vld24.c b/clang/test/CodeGen/arm-mve-intrinsics/vld24.c index 03c870e281549..15619bef5373d 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vld24.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vld24.c @@ -48,10 +48,13 @@ uint8x16x4_t test_vld4q_u8(const uint8_t *addr) // CHECK-LABEL: @test_vst2q_u32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VALUE_COERCE_FCA_0_0_EXTRACT:%.*]] = extractvalue [[STRUCT_UINT32X4X2_T:%.*]] [[VALUE_COERCE:%.*]], 0, 0 -// CHECK-NEXT: [[VALUE_COERCE_FCA_0_1_EXTRACT:%.*]] = extractvalue [[STRUCT_UINT32X4X2_T]] [[VALUE_COERCE]], 0, 1 -// CHECK-NEXT: call void @llvm.arm.mve.vst2q.p0.v4i32(ptr [[ADDR:%.*]], <4 x i32> [[VALUE_COERCE_FCA_0_0_EXTRACT]], <4 x i32> [[VALUE_COERCE_FCA_0_1_EXTRACT]], i32 0) -// CHECK-NEXT: call void @llvm.arm.mve.vst2q.p0.v4i32(ptr [[ADDR]], <4 x i32> [[VALUE_COERCE_FCA_0_0_EXTRACT]], <4 x i32> [[VALUE_COERCE_FCA_0_1_EXTRACT]], i32 1) +// CHECK-NEXT: [[TMP0:%.*]] = extractvalue [[STRUCT_UINT32X4X2_T:%.*]] [[VALUE_COERCE:%.*]], 0 +// CHECK-NEXT: [[DOTFCA_0_EXTRACT:%.*]] = extractvalue [2 x <4 x i32>] [[TMP0]], 0 +// CHECK-NEXT: [[DOTFCA_1_EXTRACT:%.*]] = extractvalue [2 x <4 x i32>] [[TMP0]], 1 +// CHECK-NEXT: [[DOTFCA_0_0_INSERT:%.*]] = insertvalue [[STRUCT_UINT32X4X2_T]] poison, <4 x i32> [[DOTFCA_0_EXTRACT]], 0, 0 +// CHECK-NEXT: [[DOTFCA_0_1_INSERT:%.*]] = insertvalue [[STRUCT_UINT32X4X2_T]] [[DOTFCA_0_0_INSERT]], <4 x i32> [[DOTFCA_1_EXTRACT]], 0, 1 +// CHECK-NEXT: call void @llvm.arm.mve.vst2q.p0.v4i32(ptr [[ADDR:%.*]], <4 x i32> [[DOTFCA_0_EXTRACT]], <4 x i32> [[DOTFCA_1_EXTRACT]], i32 0) +// CHECK-NEXT: call void @llvm.arm.mve.vst2q.p0.v4i32(ptr [[ADDR]], <4 x i32> [[DOTFCA_0_EXTRACT]], <4 x i32> [[DOTFCA_1_EXTRACT]], i32 1) // CHECK-NEXT: ret void // void test_vst2q_u32(uint32_t *addr, uint32x4x2_t value) @@ -65,14 +68,19 @@ void test_vst2q_u32(uint32_t *addr, uint32x4x2_t value) // CHECK-LABEL: @test_vst4q_s8( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VALUE_COERCE_FCA_0_0_EXTRACT:%.*]] = extractvalue [[STRUCT_INT8X16X4_T:%.*]] [[VALUE_COERCE:%.*]], 0, 0 -// CHECK-NEXT: [[VALUE_COERCE_FCA_0_1_EXTRACT:%.*]] = extractvalue [[STRUCT_INT8X16X4_T]] [[VALUE_COERCE]], 0, 1 -// CHECK-NEXT: [[VALUE_COERCE_FCA_0_2_EXTRACT:%.*]] = extractvalue [[STRUCT_INT8X16X4_T]] [[VALUE_COERCE]], 0, 2 -// CHECK-NEXT: [[VALUE_COERCE_FCA_0_3_EXTRACT:%.*]] = extractvalue [[STRUCT_INT8X16X4_T]] [[VALUE_COERCE]], 0, 3 -// CHECK-NEXT: call void @llvm.arm.mve.vst4q.p0.v16i8(ptr [[ADDR:%.*]], <16 x i8> [[VALUE_COERCE_FCA_0_0_EXTRACT]], <16 x i8> [[VALUE_COERCE_FCA_0_1_EXTRACT]], <16 x i8> [[VALUE_COERCE_FCA_0_2_EXTRACT]], <16 x i8> [[VALUE_COERCE_FCA_0_3_EXTRACT]], i32 0) -// CHECK-NEXT: call void @llvm.arm.mve.vst4q.p0.v16i8(ptr [[ADDR]], <16 x i8> [[VALUE_COERCE_FCA_0_0_EXTRACT]], <16 x i8> [[VALUE_COERCE_FCA_0_1_EXTRACT]], <16 x i8> [[VALUE_COERCE_FCA_0_2_EXTRACT]], <16 x i8> [[VALUE_COERCE_FCA_0_3_EXTRACT]], i32 1) -// CHECK-NEXT: call void @llvm.arm.mve.vst4q.p0.v16i8(ptr [[ADDR]], <16 x i8> [[VALUE_COERCE_FCA_0_0_EXTRACT]], <16 x i8> [[VALUE_COERCE_FCA_0_1_EXTRACT]], <16 x i8> [[VALUE_COERCE_FCA_0_2_EXTRACT]], <16 x i8> [[VALUE_COERCE_FCA_0_3_EXTRACT]], i32 2) -// CHECK-NEXT: call void @llvm.arm.mve.vst4q.p0.v16i8(ptr [[ADDR]], <16 x i8> [[VALUE_COERCE_FCA_0_0_EXTRACT]], <16 x i8> [[VALUE_COERCE_FCA_0_1_EXTRACT]], <16 x i8> [[VALUE_COERCE_FCA_0_2_EXTRACT]], <16 x i8> [[VALUE_COERCE_FCA_0_3_EXTRACT]], i32 3) +// CHECK-NEXT: [[TMP0:%.*]] = extractvalue [[STRUCT_INT8X16X4_T:%.*]] [[VALUE_COERCE:%.*]], 0 +// CHECK-NEXT: [[DOTFCA_0_EXTRACT:%.*]] = extractvalue [4 x <16 x i8>] [[TMP0]], 0 +// CHECK-NEXT: [[DOTFCA_1_EXTRACT:%.*]] = extractvalue [4 x <16 x i8>] [[TMP0]], 1 +// CHECK-NEXT: [[DOTFCA_2_EXTRACT:%.*]] = extractvalue [4 x <16 x i8>] [[TMP0]], 2 +// CHECK-NEXT: [[DOTFCA_3_EXTRACT:%.*]] = extractvalue [4 x <16 x i8>] [[TMP0]], 3 +// CHECK-NEXT: [[DOTFCA_0_0_INSERT:%.*]] = insertvalue [[STRUCT_INT8X16X4_T]] poison, <16 x i8> [[DOTFCA_0_EXTRACT]], 0, 0 +// CHECK-NEXT: [[DOTFCA_0_1_INSERT:%.*]] = insertvalue [[STRUCT_INT8X16X4_T]] [[DOTFCA_0_0_INSERT]], <16 x i8> [[DOTFCA_1_EXTRACT]], 0, 1 +// CHECK-NEXT: [[DOTFCA_0_2_INSERT:%.*]] = insertvalue [[STRUCT_INT8X16X4_T]] [[DOTFCA_0_1_INSERT]], <16 x i8> [[DOTFCA_2_EXTRACT]], 0, 2 +// CHECK-NEXT: [[DOTFCA_0_3_INSERT:%.*]] = insertvalue [[STRUCT_INT8X16X4_T]] [[DOTFCA_0_2_INSERT]], <16 x i8> [[DOTFCA_3_EXTRACT]], 0, 3 +// CHECK-NEXT: call void @llvm.arm.mve.vst4q.p0.v16i8(ptr [[ADDR:%.*]], <16 x i8> [[DOTFCA_0_EXTRACT]], <16 x i8> [[DOTFCA_1_EXTRACT]], <16 x i8> [[DOTFCA_2_EXTRACT]], <16 x i8> [[DOTFCA_3_EXTRACT]], i32 0) +// CHECK-NEXT: call void @llvm.arm.mve.vst4q.p0.v16i8(ptr [[ADDR]], <16 x i8> [[DOTFCA_0_EXTRACT]], <16 x i8> [[DOTFCA_1_EXTRACT]], <16 x i8> [[DOTFCA_2_EXTRACT]], <16 x i8> [[DOTFCA_3_EXTRACT]], i32 1) +// CHECK-NEXT: call void @llvm.arm.mve.vst4q.p0.v16i8(ptr [[ADDR]], <16 x i8> [[DOTFCA_0_EXTRACT]], <16 x i8> [[DOTFCA_1_EXTRACT]], <16 x i8> [[DOTFCA_2_EXTRACT]], <16 x i8> [[DOTFCA_3_EXTRACT]], i32 2) +// CHECK-NEXT: call void @llvm.arm.mve.vst4q.p0.v16i8(ptr [[ADDR]], <16 x i8> [[DOTFCA_0_EXTRACT]], <16 x i8> [[DOTFCA_1_EXTRACT]], <16 x i8> [[DOTFCA_2_EXTRACT]], <16 x i8> [[DOTFCA_3_EXTRACT]], i32 3) // CHECK-NEXT: ret void // void test_vst4q_s8(int8_t *addr, int8x16x4_t value) @@ -86,10 +94,13 @@ void test_vst4q_s8(int8_t *addr, int8x16x4_t value) // CHECK-LABEL: @test_vst2q_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VALUE_COERCE_FCA_0_0_EXTRACT:%.*]] = extractvalue [[STRUCT_FLOAT16X8X2_T:%.*]] [[VALUE_COERCE:%.*]], 0, 0 -// CHECK-NEXT: [[VALUE_COERCE_FCA_0_1_EXTRACT:%.*]] = extractvalue [[STRUCT_FLOAT16X8X2_T]] [[VALUE_COERCE]], 0, 1 -// CHECK-NEXT: call void @llvm.arm.mve.vst2q.p0.v8f16(ptr [[ADDR:%.*]], <8 x half> [[VALUE_COERCE_FCA_0_0_EXTRACT]], <8 x half> [[VALUE_COERCE_FCA_0_1_EXTRACT]], i32 0) -// CHECK-NEXT: call void @llvm.arm.mve.vst2q.p0.v8f16(ptr [[ADDR]], <8 x half> [[VALUE_COERCE_FCA_0_0_EXTRACT]], <8 x half> [[VALUE_COERCE_FCA_0_1_EXTRACT]], i32 1) +// CHECK-NEXT: [[TMP0:%.*]] = extractvalue [[STRUCT_FLOAT16X8X2_T:%.*]] [[VALUE_COERCE:%.*]], 0 +// CHECK-NEXT: [[DOTFCA_0_EXTRACT:%.*]] = extractvalue [2 x <8 x half>] [[TMP0]], 0 +// CHECK-NEXT: [[DOTFCA_1_EXTRACT:%.*]] = extractvalue [2 x <8 x half>] [[TMP0]], 1 +// CHECK-NEXT: [[DOTFCA_0_0_INSERT:%.*]] = insertvalue [[STRUCT_FLOAT16X8X2_T]] poison, <8 x half> [[DOTFCA_0_EXTRACT]], 0, 0 +// CHECK-NEXT: [[DOTFCA_0_1_INSERT:%.*]] = insertvalue [[STRUCT_FLOAT16X8X2_T]] [[DOTFCA_0_0_INSERT]], <8 x half> [[DOTFCA_1_EXTRACT]], 0, 1 +// CHECK-NEXT: call void @llvm.arm.mve.vst2q.p0.v8f16(ptr [[ADDR:%.*]], <8 x half> [[DOTFCA_0_EXTRACT]], <8 x half> [[DOTFCA_1_EXTRACT]], i32 0) +// CHECK-NEXT: call void @llvm.arm.mve.vst2q.p0.v8f16(ptr [[ADDR]], <8 x half> [[DOTFCA_0_EXTRACT]], <8 x half> [[DOTFCA_1_EXTRACT]], i32 1) // CHECK-NEXT: ret void // void test_vst2q_f16(float16_t *addr, float16x8x2_t value) diff --git a/clang/test/CodeGen/arm-vfp16-arguments2.cpp b/clang/test/CodeGen/arm-vfp16-arguments2.cpp index 6221e85e856b4..b7c6852c47b7f 100644 --- a/clang/test/CodeGen/arm-vfp16-arguments2.cpp +++ b/clang/test/CodeGen/arm-vfp16-arguments2.cpp @@ -44,20 +44,20 @@ struct S1 f1(struct S1 s1) { return s1; } // CHECK-SOFT: define{{.*}} void @_Z2f22S2(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.S2) align 8 %agg.result, [4 x i32] %s2.coerce) // CHECK-HARD: define{{.*}} arm_aapcs_vfpcc [2 x <2 x i32>] @_Z2f22S2([2 x <2 x i32>] returned %s2.coerce) -// CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S2 @_Z2f22S2(%struct.S2 returned %s2.coerce) +// CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S2 @_Z2f22S2(%struct.S2 %s2.coerce) struct S2 f2(struct S2 s2) { return s2; } // CHECK-SOFT: define{{.*}} void @_Z2f32S3(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.S3) align 8 %agg.result, [2 x i64] %s3.coerce) // CHECK-HARD: define{{.*}} arm_aapcs_vfpcc [2 x <2 x i32>] @_Z2f32S3([2 x <2 x i32>] returned %s3.coerce) -// CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S3 @_Z2f32S3(%struct.S3 returned %s3.coerce) +// CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S3 @_Z2f32S3(%struct.S3 %s3.coerce) struct S3 f3(struct S3 s3) { return s3; } // CHECK-SOFT: define{{.*}} void @_Z2f42S4(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.S4) align 8 %agg.result, [2 x i64] %s4.coerce) // CHECK-HARD: define{{.*}} arm_aapcs_vfpcc [2 x <2 x i32>] @_Z2f42S4([2 x <2 x i32>] returned %s4.coerce) -// CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S4 @_Z2f42S4(%struct.S4 returned %s4.coerce) +// CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S4 @_Z2f42S4(%struct.S4 %s4.coerce) struct S4 f4(struct S4 s4) { return s4; } // CHECK-SOFT: define{{.*}} void @_Z2f52S5(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.S5) align 8 %agg.result, [2 x i64] %s5.coerce) -// CHECK-HARD: define{{.*}} arm_aapcs_vfpcc %struct.S5 @_Z2f52S5(%struct.S5 returned %s5.coerce) -// CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S5 @_Z2f52S5(%struct.S5 returned %s5.coerce) +// CHECK-HARD: define{{.*}} arm_aapcs_vfpcc %struct.S5 @_Z2f52S5(%struct.S5 %s5.coerce) +// CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S5 @_Z2f52S5(%struct.S5 %s5.coerce) struct S5 f5(struct S5 s5) { return s5; } diff --git a/clang/test/CodeGen/arm64ec-hybrid-patchable.c b/clang/test/CodeGen/arm64ec-hybrid-patchable.c new file mode 100644 index 0000000000000..4d1fa12afd2aa --- /dev/null +++ b/clang/test/CodeGen/arm64ec-hybrid-patchable.c @@ -0,0 +1,34 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple arm64ec-pc-windows -fms-extensions -emit-llvm -o - %s -verify | FileCheck %s + +// CHECK: ; Function Attrs: hybrid_patchable noinline nounwind optnone +// CHECK-NEXT: define dso_local i32 @func() #0 { +int __attribute__((hybrid_patchable)) func(void) { return 1; } + +// CHECK: ; Function Attrs: hybrid_patchable noinline nounwind optnone +// CHECK-NEXT: define dso_local i32 @func2() #0 { +int __declspec(hybrid_patchable) func2(void) { return 2; } + +// CHECK: ; Function Attrs: hybrid_patchable noinline nounwind optnone +// CHECK-NEXT: define dso_local i32 @func3() #0 { +int __declspec(hybrid_patchable) func3(void); +int func3(void) { return 3; } + +// CHECK: ; Function Attrs: hybrid_patchable noinline nounwind optnone +// CHECK-NEXT: define dso_local i32 @func4() #0 { +[[clang::hybrid_patchable]] int func4(void); +int func4(void) { return 3; } + +// CHECK: ; Function Attrs: hybrid_patchable noinline nounwind optnone +// CHECK-NEXT: define internal void @static_func() #0 { +// expected-warning@+1 {{'hybrid_patchable' is ignored on functions without external linkage}} +static void __declspec(hybrid_patchable) static_func(void) {} + +// CHECK: ; Function Attrs: hybrid_patchable noinline nounwind optnone +// CHECK-NEXT: define linkonce_odr dso_local i32 @func5() #0 comdat { +int inline __declspec(hybrid_patchable) func5(void) { return 4; } + +void caller(void) { + static_func(); + func5(); +} diff --git a/clang/test/CodeGen/asm-inout.c b/clang/test/CodeGen/asm-inout.c index 1383a421efbc2..6d40451b778d9 100644 --- a/clang/test/CodeGen/asm-inout.c +++ b/clang/test/CodeGen/asm-inout.c @@ -38,11 +38,11 @@ int test4(volatile int *addr) { return (int)oldval; } -// This should have both inputs be of type x86_mmx. +// This should have both inputs be of type <1 x i64>. // CHECK: @test5 typedef long long __m64 __attribute__((__vector_size__(8))); __m64 test5(__m64 __A, __m64 __B) { - // CHECK: call x86_mmx asm "pmulhuw $1, $0\0A\09", "=y,y,0,~{dirflag},~{fpsr},~{flags}"(x86_mmx %{{.*}}, x86_mmx %{{.*}}) + // CHECK: call <1 x i64> asm "pmulhuw $1, $0\0A\09", "=y,y,0,~{dirflag},~{fpsr},~{flags}"(<1 x i64> %{{.*}}, <1 x i64> %{{.*}}) asm ("pmulhuw %1, %0\n\t" : "+y" (__A) : "y" (__B)); return __A; } @@ -51,7 +51,7 @@ __m64 test5(__m64 __A, __m64 __B) { int test6(void) { typedef unsigned char __attribute__((vector_size(8))) _m64u8; _m64u8 __attribute__((aligned(16))) Mu8_0, __attribute__((aligned(16))) Mu8_1; - // CHECK: call x86_mmx asm "nop", "=y,0,~{dirflag},~{fpsr},~{flags}"(x86_mmx %1) + // CHECK: call <8 x i8> asm "nop", "=y,0,~{dirflag},~{fpsr},~{flags}"(<8 x i8> %0) asm ("nop" : "=y"(Mu8_1 ) : "0"(Mu8_0 )); return 0; } diff --git a/clang/test/CodeGen/attr-counted-by.c b/clang/test/CodeGen/attr-counted-by.c index 79922eb4159f1..f5032ded971a8 100644 --- a/clang/test/CodeGen/attr-counted-by.c +++ b/clang/test/CodeGen/attr-counted-by.c @@ -754,11 +754,11 @@ size_t test7_bdos(struct union_of_fams *p) { // 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 [[CONT9:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !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]]) #[[ATTR10]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont9: +// 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: store i8 [[DOT_COUNTED_BY_LOAD]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] @@ -908,11 +908,11 @@ size_t test9_bdos(struct union_of_fams *p) { // 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 [[CONT9:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !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]]) #[[ATTR10]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont9: +// 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: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) @@ -1852,3 +1852,105 @@ struct annotated_struct_array { void test29(struct annotated_struct_array *ann, int idx1, int idx2) { ann->ann_array[idx1]->array[idx2] = __builtin_dynamic_object_size(ann->ann_array[idx1]->array, 1); } + +typedef struct { + char __padding[0]; +} test30_spinlock_t; + +struct test30_struct { + struct test30_decl *name_node; + int priv_len; + test30_spinlock_t pcpu_refcnt; + char priv[] __counted_by(priv_len); +}; + +// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test30( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR5]] { +// 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]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test30( +// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[PTR]], 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 4) +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[DOT_COUNTED_BY_LOAD]], 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], 12 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i8 0, i8 [[TMP2]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[PCPU_REFCNT:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 12 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[PCPU_REFCNT]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] +// NO-SANITIZE-WITH-ATTR-NEXT: ret void +// +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test30( +// 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: unreachable, !nosanitize [[META9]] +// +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test30( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[PCPU_REFCNT:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 12 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[PCPU_REFCNT]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void +// +void test30(struct test30_struct *ptr, int idx) { + ptr->pcpu_refcnt.__padding[idx] = __builtin_dynamic_object_size(ptr, 1); +} + +struct test31_empty {}; + +struct test31_struct { + struct test31_empty y; + int s; + int x[] __counted_by(s); +}; + +// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test31( +// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[PTR]], 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 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i64 @llvm.smax.i64(i64 [[TMP1]], i64 0) +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = trunc i64 [[TMP2]] to i32 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = add i32 [[TMP3]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[DOT_COUNTED_BY_LOAD]], 0 +// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP4]] +// SANITIZE-WITH-ATTR-NEXT: ret i32 [[CONV]] +// +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test31( +// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR2]] { +// NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[PTR]], 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 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i64 @llvm.smax.i64(i64 [[TMP1]], i64 0) +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = trunc i64 [[TMP2]] to i32 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = add i32 [[TMP3]], 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[DOT_COUNTED_BY_LOAD]], 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP4]] +// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[CONV]] +// +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test31( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITHOUT-ATTR-NEXT: entry: +// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 -1 +// +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test31( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 -1 +// +int test31(struct test31_struct *ptr, int idx) { + return __builtin_dynamic_object_size(ptr, 0); +} diff --git a/clang/test/CodeGen/attr-nomerge.cpp b/clang/test/CodeGen/attr-nomerge.cpp index 7305fb73cf1dc..1cf5bb1619b31 100644 --- a/clang/test/CodeGen/attr-nomerge.cpp +++ b/clang/test/CodeGen/attr-nomerge.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -fms-extensions -o - | FileCheck %s class A { public: @@ -42,6 +42,9 @@ void foo(int i, A *ap, B *bp) { A *newA = new B(); delete newA; + [[clang::nomerge]] __builtin_trap(); + [[clang::nomerge]] __debugbreak(); + [[clang::nomerge]] __builtin_verbose_trap("check null", "Argument must not be null."); } int g(int i); @@ -62,22 +65,22 @@ void something_else_again() { g(1); } -// CHECK: call noundef zeroext i1 @_Z3barv() #[[ATTR0:[0-9]+]] -// CHECK: call noundef zeroext i1 @_Z3barv() #[[ATTR0]] -// CHECK: call noundef zeroext i1 @_Z3barv() #[[ATTR0]] -// CHECK: call noundef zeroext i1 @_Z3barv(){{$}} -// CHECK: call noundef zeroext i1 @_Z3barv(){{$}} +// CHECK: call noundef{{.*}} i1 @_Z3barv() #[[ATTR0:[0-9]+]] +// CHECK: call noundef{{.*}} i1 @_Z3barv() #[[ATTR0]] +// CHECK: call noundef{{.*}} i1 @_Z3barv() #[[ATTR0]] +// CHECK: call noundef{{.*}} i1 @_Z3barv(){{$}} +// CHECK: call noundef{{.*}} i1 @_Z3barv(){{$}} // CHECK: call void @_Z1fbb({{.*}}) #[[ATTR0]] // CHECK: %[[FPTR:.*]] = load ptr, ptr @fptr // CHECK-NEXT: call void %[[FPTR]]() #[[ATTR0]] // CHECK: call void @"_ZZ3fooiP1AP1BENK3$_0clEv"{{.*}} #[[ATTR0]] -// CHECK: call noundef zeroext i1 @_Z3barv() #[[ATTR0]] +// CHECK: call noundef{{.*}} i1 @_Z3barv() #[[ATTR0]] // CHECK-LABEL: for.cond: -// CHECK: call noundef zeroext i1 @_Z3barv() #[[ATTR0]] +// CHECK: call noundef{{.*}} i1 @_Z3barv() #[[ATTR0]] // CHECK-LABEL: for.inc: -// CHECK: call noundef zeroext i1 @_Z3barv() #[[ATTR0]] +// CHECK: call noundef{{.*}} i1 @_Z3barv() #[[ATTR0]] // CHECK: call void asm sideeffect "nop"{{.*}} #[[ATTR1:[0-9]+]] -// CHECK: call noundef zeroext i1 @_Z3barv(){{$}} +// CHECK: call noundef{{.*}} i1 @_Z3barv(){{$}} // CHECK: load ptr, ptr // CHECK: load ptr, ptr // CHECK: %[[AG:.*]] = load ptr, ptr @@ -97,6 +100,9 @@ void something_else_again() { // CHECK: load ptr, ptr // CHECK: %[[AG:.*]] = load ptr, ptr // CHECK-NEXT: call void %[[AG]](ptr {{.*}}) #[[ATTR1]] +// CHECK: call void @llvm.trap() #[[ATTR0]] +// CHECK: call void @llvm.debugtrap() #[[ATTR0]] +// CHECK: call void @llvm.trap() #[[ATTR0]] // CHECK: call void @_ZN1AD1Ev(ptr {{.*}}) #[[ATTR1]] // CHECK-DAG: attributes #[[ATTR0]] = {{{.*}}nomerge{{.*}}} diff --git a/clang/test/CodeGen/attr-target-clones-aarch64.c b/clang/test/CodeGen/attr-target-clones-aarch64.c index 60f9c7f1fc24e..274e05de594b8 100644 --- a/clang/test/CodeGen/attr-target-clones-aarch64.c +++ b/clang/test/CodeGen/attr-target-clones-aarch64.c @@ -32,8 +32,8 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK: @ftc_dup1 = weak_odr ifunc i32 (), ptr @ftc_dup1.resolver // CHECK: @ftc_dup2 = weak_odr ifunc i32 (), ptr @ftc_dup2.resolver // CHECK: @ftc_dup3 = weak_odr ifunc i32 (), ptr @ftc_dup3.resolver -// CHECK: @ftc_inline1 = weak_odr ifunc i32 (), ptr @ftc_inline1.resolver // CHECK: @ftc_inline2 = weak_odr ifunc i32 (), ptr @ftc_inline2.resolver +// CHECK: @ftc_inline1 = weak_odr ifunc i32 (), ptr @ftc_inline1.resolver // CHECK: @ftc_inline3 = weak_odr ifunc i32 (), ptr @ftc_inline3.resolver //. // CHECK-MTE-BTI: @__aarch64_cpu_features = external dso_local global { i64 } @@ -42,8 +42,8 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-MTE-BTI: @ftc_dup1 = weak_odr ifunc i32 (), ptr @ftc_dup1.resolver // CHECK-MTE-BTI: @ftc_dup2 = weak_odr ifunc i32 (), ptr @ftc_dup2.resolver // CHECK-MTE-BTI: @ftc_dup3 = weak_odr ifunc i32 (), ptr @ftc_dup3.resolver -// CHECK-MTE-BTI: @ftc_inline1 = weak_odr ifunc i32 (), ptr @ftc_inline1.resolver // CHECK-MTE-BTI: @ftc_inline2 = weak_odr ifunc i32 (), ptr @ftc_inline2.resolver +// CHECK-MTE-BTI: @ftc_inline1 = weak_odr ifunc i32 (), ptr @ftc_inline1.resolver // CHECK-MTE-BTI: @ftc_inline3 = weak_odr ifunc i32 (), ptr @ftc_inline3.resolver //. // CHECK: Function Attrs: noinline nounwind optnone @@ -157,7 +157,15 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK: resolver_return: // CHECK-NEXT: ret ptr @ftc_dup2._McrcMdotprod // CHECK: resolver_else: +// CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 256 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 256 +// 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 @ftc_dup2._Mfp +// CHECK: resolver_else2: +// CHECK-NEXT: ret ptr @ftc_dup2.default // // // CHECK: Function Attrs: noinline nounwind optnone @@ -210,12 +218,6 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: @ftc_inline2._Mfp16( -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 2 -// -// -// CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: @ftc_direct( // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 4 @@ -236,86 +238,6 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-NEXT: ret i32 [[ADD5]] // // -// CHECK-LABEL: @ftc_inline1.resolver( -// 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]], 18014535948435456 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 18014535948435456 -// 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_inline1._Msve2-aesMwfxt -// CHECK: resolver_else: -// CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 140737492549632 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 140737492549632 -// 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 @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: [[TMP11:%.*]] = and i1 true, [[TMP10]] -// CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] -// CHECK: resolver_return3: -// CHECK-NEXT: ret ptr @ftc_inline1._MrngMsimd -// CHECK: resolver_else4: -// CHECK-NEXT: ret ptr @ftc_inline1.default -// -// -// CHECK-LABEL: @ftc_inline2.resolver( -// 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: [[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: [[TMP7:%.*]] = and i1 true, [[TMP6]] -// CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] -// CHECK: resolver_return1: -// CHECK-NEXT: ret ptr @ftc_inline2._Mfp16 -// CHECK: resolver_else2: -// CHECK-NEXT: ret ptr @ftc_inline2.default -// -// -// CHECK-LABEL: @ftc_inline3.resolver( -// 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: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: -// CHECK-NEXT: ret ptr @ftc_inline3._MsbMsve -// CHECK: resolver_else: -// CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 1125899906842624 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 1125899906842624 -// 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 @ftc_inline3._Mbti -// CHECK: resolver_else2: -// CHECK-NEXT: ret ptr @ftc_inline3.default -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: @ftc_inline2._MfcmaMsve2-bitperm( -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 2 -// -// // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: @ftc.default( // CHECK-NEXT: entry: @@ -347,11 +269,45 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // // // CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: @ftc_inline2._Mfp16( +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 2 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: @ftc_inline2._MfcmaMsve2-bitperm( +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 2 +// +// +// CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: @ftc_inline2.default( // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 2 // // +// CHECK-LABEL: @ftc_inline2.resolver( +// 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: [[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: [[TMP7:%.*]] = and i1 true, [[TMP6]] +// CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] +// CHECK: resolver_return1: +// CHECK-NEXT: ret ptr @ftc_inline2._Mfp16 +// CHECK: resolver_else2: +// CHECK-NEXT: ret ptr @ftc_inline2.default +// +// // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: @ftc_inline1._MrngMsimd( // CHECK-NEXT: entry: @@ -376,6 +332,36 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-NEXT: ret i32 1 // // +// CHECK-LABEL: @ftc_inline1.resolver( +// 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]], 18014535948435456 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 18014535948435456 +// 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_inline1._Msve2-aesMwfxt +// CHECK: resolver_else: +// CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 140737492549632 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 140737492549632 +// 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 @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: [[TMP11:%.*]] = and i1 true, [[TMP10]] +// CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] +// CHECK: resolver_return3: +// CHECK-NEXT: ret ptr @ftc_inline1._MrngMsimd +// CHECK: resolver_else4: +// CHECK-NEXT: ret ptr @ftc_inline1.default +// +// // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: @ftc_inline3._Mbti( // CHECK-NEXT: entry: @@ -394,6 +380,28 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-NEXT: ret i32 3 // // +// CHECK-LABEL: @ftc_inline3.resolver( +// 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: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @ftc_inline3._MsbMsve +// CHECK: resolver_else: +// CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 1125899906842624 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 1125899906842624 +// 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 @ftc_inline3._Mbti +// CHECK: resolver_else2: +// CHECK-NEXT: ret ptr @ftc_inline3.default +// +// // CHECK-NOFMV: Function Attrs: noinline nounwind optnone // CHECK-NOFMV-LABEL: @ftc( // CHECK-NOFMV-NEXT: entry: @@ -571,7 +579,15 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-MTE-BTI: resolver_return: // CHECK-MTE-BTI-NEXT: ret ptr @ftc_dup2._McrcMdotprod // 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]], 256 +// CHECK-MTE-BTI-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 256 +// 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: // CHECK-MTE-BTI-NEXT: ret ptr @ftc_dup2._Mfp +// CHECK-MTE-BTI: resolver_else2: +// CHECK-MTE-BTI-NEXT: ret ptr @ftc_dup2.default // // // CHECK-MTE-BTI: Function Attrs: noinline nounwind optnone @@ -624,12 +640,6 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // // // CHECK-MTE-BTI: Function Attrs: noinline nounwind optnone -// CHECK-MTE-BTI-LABEL: @ftc_inline2._Mfp16( -// CHECK-MTE-BTI-NEXT: entry: -// CHECK-MTE-BTI-NEXT: ret i32 2 -// -// -// CHECK-MTE-BTI: Function Attrs: noinline nounwind optnone // CHECK-MTE-BTI-LABEL: @ftc_direct( // CHECK-MTE-BTI-NEXT: entry: // CHECK-MTE-BTI-NEXT: ret i32 4 @@ -650,86 +660,6 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-MTE-BTI-NEXT: ret i32 [[ADD5]] // // -// CHECK-MTE-BTI-LABEL: @ftc_inline1.resolver( -// 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]], 18014535948435456 -// CHECK-MTE-BTI-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 18014535948435456 -// 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_inline1._Msve2-aesMwfxt -// 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]], 140737492549632 -// CHECK-MTE-BTI-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 140737492549632 -// 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: -// 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: [[TMP11:%.*]] = and i1 true, [[TMP10]] -// CHECK-MTE-BTI-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] -// CHECK-MTE-BTI: resolver_return3: -// CHECK-MTE-BTI-NEXT: ret ptr @ftc_inline1._MrngMsimd -// CHECK-MTE-BTI: resolver_else4: -// CHECK-MTE-BTI-NEXT: ret ptr @ftc_inline1.default -// -// -// CHECK-MTE-BTI-LABEL: @ftc_inline2.resolver( -// 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: [[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: [[TMP7:%.*]] = and i1 true, [[TMP6]] -// CHECK-MTE-BTI-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] -// CHECK-MTE-BTI: resolver_return1: -// CHECK-MTE-BTI-NEXT: ret ptr @ftc_inline2._Mfp16 -// CHECK-MTE-BTI: resolver_else2: -// CHECK-MTE-BTI-NEXT: ret ptr @ftc_inline2.default -// -// -// CHECK-MTE-BTI-LABEL: @ftc_inline3.resolver( -// 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: [[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_inline3._MsbMsve -// 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]], 1125899906842624 -// CHECK-MTE-BTI-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 1125899906842624 -// 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: -// CHECK-MTE-BTI-NEXT: ret ptr @ftc_inline3._Mbti -// CHECK-MTE-BTI: resolver_else2: -// CHECK-MTE-BTI-NEXT: ret ptr @ftc_inline3.default -// -// -// CHECK-MTE-BTI: Function Attrs: noinline nounwind optnone -// CHECK-MTE-BTI-LABEL: @ftc_inline2._MfcmaMsve2-bitperm( -// CHECK-MTE-BTI-NEXT: entry: -// CHECK-MTE-BTI-NEXT: ret i32 2 -// -// // CHECK-MTE-BTI: Function Attrs: noinline nounwind optnone // CHECK-MTE-BTI-LABEL: @ftc.default( // CHECK-MTE-BTI-NEXT: entry: @@ -761,11 +691,45 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // // // CHECK-MTE-BTI: Function Attrs: noinline nounwind optnone +// CHECK-MTE-BTI-LABEL: @ftc_inline2._Mfp16( +// CHECK-MTE-BTI-NEXT: entry: +// CHECK-MTE-BTI-NEXT: ret i32 2 +// +// +// CHECK-MTE-BTI: Function Attrs: noinline nounwind optnone +// CHECK-MTE-BTI-LABEL: @ftc_inline2._MfcmaMsve2-bitperm( +// CHECK-MTE-BTI-NEXT: entry: +// CHECK-MTE-BTI-NEXT: ret i32 2 +// +// +// CHECK-MTE-BTI: Function Attrs: noinline nounwind optnone // CHECK-MTE-BTI-LABEL: @ftc_inline2.default( // CHECK-MTE-BTI-NEXT: entry: // CHECK-MTE-BTI-NEXT: ret i32 2 // // +// CHECK-MTE-BTI-LABEL: @ftc_inline2.resolver( +// 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: [[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: [[TMP7:%.*]] = and i1 true, [[TMP6]] +// CHECK-MTE-BTI-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] +// CHECK-MTE-BTI: resolver_return1: +// CHECK-MTE-BTI-NEXT: ret ptr @ftc_inline2._Mfp16 +// CHECK-MTE-BTI: resolver_else2: +// CHECK-MTE-BTI-NEXT: ret ptr @ftc_inline2.default +// +// // CHECK-MTE-BTI: Function Attrs: noinline nounwind optnone // CHECK-MTE-BTI-LABEL: @ftc_inline1._MrngMsimd( // CHECK-MTE-BTI-NEXT: entry: @@ -790,6 +754,36 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-MTE-BTI-NEXT: ret i32 1 // // +// CHECK-MTE-BTI-LABEL: @ftc_inline1.resolver( +// 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]], 18014535948435456 +// CHECK-MTE-BTI-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 18014535948435456 +// 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_inline1._Msve2-aesMwfxt +// 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]], 140737492549632 +// CHECK-MTE-BTI-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 140737492549632 +// 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: +// 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: [[TMP11:%.*]] = and i1 true, [[TMP10]] +// CHECK-MTE-BTI-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] +// CHECK-MTE-BTI: resolver_return3: +// CHECK-MTE-BTI-NEXT: ret ptr @ftc_inline1._MrngMsimd +// CHECK-MTE-BTI: resolver_else4: +// CHECK-MTE-BTI-NEXT: ret ptr @ftc_inline1.default +// +// // CHECK-MTE-BTI: Function Attrs: noinline nounwind optnone // CHECK-MTE-BTI-LABEL: @ftc_inline3._Mbti( // CHECK-MTE-BTI-NEXT: entry: @@ -807,6 +801,28 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-MTE-BTI-NEXT: entry: // CHECK-MTE-BTI-NEXT: ret i32 3 // +// +// CHECK-MTE-BTI-LABEL: @ftc_inline3.resolver( +// 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: [[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_inline3._MsbMsve +// 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]], 1125899906842624 +// CHECK-MTE-BTI-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 1125899906842624 +// 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: +// CHECK-MTE-BTI-NEXT: ret ptr @ftc_inline3._Mbti +// CHECK-MTE-BTI: resolver_else2: +// CHECK-MTE-BTI-NEXT: ret ptr @ftc_inline3.default +// //. // CHECK: attributes #[[ATTR0:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+lse,+neon" } // CHECK: attributes #[[ATTR1:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2" } diff --git a/clang/test/CodeGen/attr-target-version.c b/clang/test/CodeGen/attr-target-version.c index 4edfc5408fae7..b058f84f78baa 100644 --- a/clang/test/CodeGen/attr-target-version.c +++ b/clang/test/CodeGen/attr-target-version.c @@ -1,5 +1,5 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals --include-generated-funcs -// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -v9.5a -target-feature -fp-armv8 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fmv -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-NOFMV int __attribute__((target_version("rng+flagm+fp16fml"))) fmv(void) { return 1; } @@ -11,15 +11,15 @@ int __attribute__((target_version("fp+aes"))) fmv(void) { return 6; } int __attribute__((target_version("crc+ls64_v"))) fmv(void) { return 7; } int __attribute__((target_version("bti"))) fmv(void) { return 8; } int __attribute__((target_version("sme2"))) fmv(void) { return 9; } -int __attribute__((target_version("default"))) fmv(void); +int __attribute__((target_version("default"))) fmv(void) { return 0; } int __attribute__((target_version("ls64+simd"))) fmv_one(void) { return 1; } int __attribute__((target_version("dpb"))) fmv_one(void) { return 2; } -int __attribute__((target_version("default"))) fmv_one(void); +int __attribute__((target_version("default"))) fmv_one(void) { return 0; } int __attribute__((target_version("fp"))) fmv_two(void) { return 1; } int __attribute__((target_version("simd"))) fmv_two(void) { return 2; } int __attribute__((target_version("dgh"))) fmv_two(void) { return 3; } int __attribute__((target_version("fp16+simd"))) fmv_two(void) { return 4; } -int __attribute__((target_version("default"))) fmv_two(void); +int __attribute__((target_version("default"))) fmv_two(void) { return 0; } int foo() { return fmv()+fmv_one()+fmv_two(); } @@ -124,11 +124,11 @@ __attribute__((target_version("rdma"))) int default_def_with_version_decls(void) // The following is guarded because in NOFMV we get errors for calling undeclared functions. #ifdef __HAVE_FUNCTION_MULTI_VERSIONING -// This should generate a default declaration, two target versions and the resolver. +// This should generate a default declaration, two target versions but no resolver. __attribute__((target_version("jscvt"))) int used_def_without_default_decl(void) { return 1; } __attribute__((target_version("rdma"))) int used_def_without_default_decl(void) { return 2; } -// This should generate a default declaration and the resolver. +// This should generate a default declaration but no resolver. __attribute__((target_version("jscvt"))) int used_decl_without_default_decl(void); __attribute__((target_version("rdma"))) int used_decl_without_default_decl(void); @@ -140,12 +140,10 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK: @fmv = weak_odr ifunc i32 (), ptr @fmv.resolver // CHECK: @fmv_one = weak_odr ifunc i32 (), ptr @fmv_one.resolver // CHECK: @fmv_two = weak_odr ifunc i32 (), ptr @fmv_two.resolver -// CHECK: @fmv_inline = weak_odr ifunc i32 (), ptr @fmv_inline.resolver // CHECK: @fmv_e = weak_odr ifunc i32 (), ptr @fmv_e.resolver // CHECK: @fmv_d = internal ifunc i32 (), ptr @fmv_d.resolver // CHECK: @fmv_c = weak_odr ifunc void (), ptr @fmv_c.resolver -// CHECK: @used_def_without_default_decl = weak_odr ifunc i32 (), ptr @used_def_without_default_decl.resolver -// CHECK: @used_decl_without_default_decl = weak_odr ifunc i32 (), ptr @used_decl_without_default_decl.resolver +// CHECK: @fmv_inline = weak_odr ifunc i32 (), ptr @fmv_inline.resolver // CHECK: @unused_with_default_def = weak_odr ifunc i32 (), ptr @unused_with_default_def.resolver // CHECK: @unused_with_implicit_default_def = weak_odr ifunc i32 (), ptr @unused_with_implicit_default_def.resolver // CHECK: @unused_with_implicit_forward_default_def = weak_odr ifunc i32 (), ptr @unused_with_implicit_forward_default_def.resolver @@ -215,6 +213,13 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // // // CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv.default +// CHECK-SAME: () #[[ATTR9:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 0 +// +// +// CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_one._Mls64Msimd // CHECK-SAME: () #[[ATTR5]] { // CHECK-NEXT: entry: @@ -229,6 +234,13 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // // // CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_one.default +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 0 +// +// +// CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_two._Mfp // CHECK-SAME: () #[[ATTR5]] { // CHECK-NEXT: entry: @@ -244,21 +256,28 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_two._Mdgh -// CHECK-SAME: () #[[ATTR11:[0-9]+]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 3 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_two._Mfp16Msimd -// CHECK-SAME: () #[[ATTR12:[0-9]+]] { +// CHECK-SAME: () #[[ATTR11:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 4 // // // CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_two.default +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 0 +// +// +// CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@foo -// CHECK-SAME: () #[[ATTR11]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[CALL:%.*]] = call i32 @fmv() // CHECK-NEXT: [[CALL1:%.*]] = call i32 @fmv_one() @@ -268,6 +287,183 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: ret i32 [[ADD3]] // // +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_e.default +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 20 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_c._Mssbs +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret void +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_c.default +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret void +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@goo +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[CALL:%.*]] = call i32 @fmv_inline() +// CHECK-NEXT: [[CALL1:%.*]] = call i32 @fmv_e() +// CHECK-NEXT: [[CALL2:%.*]] = call i32 @fmv_d() +// CHECK-NEXT: call void @fmv_c() +// CHECK-NEXT: [[CALL3:%.*]] = call i32 @fmv_default() +// CHECK-NEXT: ret i32 [[CALL3]] +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_default +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 111 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@recur +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @reca() +// CHECK-NEXT: ret void +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@hoo +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[FP1:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[FP2:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: call void @f(ptr noundef @fmv) +// CHECK-NEXT: store ptr @fmv, ptr [[FP1]], align 8 +// CHECK-NEXT: store ptr @fmv, ptr [[FP2]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[FP1]], align 8 +// CHECK-NEXT: [[CALL:%.*]] = call i32 [[TMP0]]() +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[FP2]], align 8 +// CHECK-NEXT: [[CALL1:%.*]] = call i32 [[TMP1]]() +// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] +// CHECK-NEXT: ret i32 [[ADD]] +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@unused_with_forward_default_decl._Mmops +// CHECK-SAME: () #[[ATTR13:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 0 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_extern_forward_default_decl._Mdotprod +// CHECK-SAME: () #[[ATTR14:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 0 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@unused_with_default_decl._Maes +// CHECK-SAME: () #[[ATTR5]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 0 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@unused_with_default_def._Msve +// CHECK-SAME: () #[[ATTR15:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 0 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@unused_with_default_def.default +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 1 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_default_def._Mfp16 +// CHECK-SAME: () #[[ATTR11]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 0 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_default_def.default +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 1 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def.default +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 0 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def._Mlse +// CHECK-SAME: () #[[ATTR16:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 1 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@unused_without_default._Mrdm +// CHECK-SAME: () #[[ATTR17:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 0 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@default_def_with_version_decls.default +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 0 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@used_def_without_default_decl._Mjscvt +// CHECK-SAME: () #[[ATTR19:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 1 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@used_def_without_default_decl._Mrdm +// CHECK-SAME: () #[[ATTR17]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 2 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@caller +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[CALL:%.*]] = call i32 @used_def_without_default_decl() +// CHECK-NEXT: [[CALL1:%.*]] = call i32 @used_decl_without_default_decl() +// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] +// CHECK-NEXT: ret i32 [[ADD]] +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@main +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK-NEXT: call void @recur() +// CHECK-NEXT: [[CALL:%.*]] = call i32 @goo() +// CHECK-NEXT: ret i32 [[CALL]] +// +// // CHECK-LABEL: define {{[^@]+}}@fmv.resolver() comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() @@ -406,57 +602,185 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: ret ptr @fmv_two.default // // -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_e.default -// CHECK-SAME: () #[[ATTR11]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 20 +// CHECK-LABEL: define {{[^@]+}}@fmv_e.resolver() comdat { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 2251799813685248 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 2251799813685248 +// 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_e._Mls64 +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @fmv_e.default // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_d._Msb -// CHECK-SAME: () #[[ATTR13:[0-9]+]] { +// CHECK-SAME: () #[[ATTR20:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_d.default -// CHECK-SAME: () #[[ATTR11]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 1 // // +// CHECK-LABEL: define {{[^@]+}}@fmv_d.resolver() { +// 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]], 70368744177664 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 70368744177664 +// 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_d._Msb +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @fmv_d.default +// +// +// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 281474976710656 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 281474976710656 +// 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_c._Mssbs +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @fmv_c.default +// +// // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_c._Mssbs -// CHECK-SAME: () #[[ATTR11]] { +// CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mf64mmMpmullMsha1 +// CHECK-SAME: () #[[ATTR21:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret void +// CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_c.default -// CHECK-SAME: () #[[ATTR11]] { +// CHECK-LABEL: define {{[^@]+}}@fmv_inline._MfcmaMfp16MrdmMsme +// CHECK-SAME: () #[[ATTR22:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret void +// CHECK-NEXT: ret i32 2 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@goo -// CHECK-SAME: () #[[ATTR11]] { +// CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mf32mmMi8mmMsha3 +// CHECK-SAME: () #[[ATTR23:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[CALL:%.*]] = call i32 @fmv_inline() -// CHECK-NEXT: [[CALL1:%.*]] = call i32 @fmv_e() -// CHECK-NEXT: [[CALL2:%.*]] = call i32 @fmv_d() -// CHECK-NEXT: call void @fmv_c() -// CHECK-NEXT: [[CALL3:%.*]] = call i32 @fmv_default() -// CHECK-NEXT: ret i32 [[CALL3]] +// CHECK-NEXT: ret i32 12 // // -// CHECK-LABEL: define {{[^@]+}}@fmv_inline.resolver() comdat { -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_inline._MditMsve-ebf16 +// CHECK-SAME: () #[[ATTR24:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 8 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_inline._MdpbMrcpc2 +// CHECK-SAME: () #[[ATTR25:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 6 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mdpb2Mjscvt +// CHECK-SAME: () #[[ATTR26:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 7 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_inline._MfrinttsMrcpc +// CHECK-SAME: () #[[ATTR27:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 3 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_inline._MsveMsve-bf16 +// CHECK-SAME: () #[[ATTR28:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 4 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_inline._Msve2-aesMsve2-sha3 +// CHECK-SAME: () #[[ATTR29:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 5 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_inline._Msve2Msve2-bitpermMsve2-pmull128 +// CHECK-SAME: () #[[ATTR30:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 9 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mmemtag2Msve2-sm4 +// CHECK-SAME: () #[[ATTR31:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 10 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mmemtag3MmopsMrcpc3 +// CHECK-SAME: () #[[ATTR32:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 11 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_inline._MaesMdotprod +// CHECK-SAME: () #[[ATTR14]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 13 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mfp16fmlMsimd +// CHECK-SAME: () #[[ATTR4]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 14 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_inline._MfpMsm4 +// CHECK-SAME: () #[[ATTR33:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 15 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_inline._MlseMrdm +// CHECK-SAME: () #[[ATTR34:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 16 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_inline.default +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 3 +// +// +// CHECK-LABEL: define {{[^@]+}}@fmv_inline.resolver() comdat { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4398048673856 // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4398048673856 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] @@ -587,355 +911,6 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: ret ptr @fmv_inline.default // // -// CHECK-LABEL: define {{[^@]+}}@fmv_e.resolver() comdat { -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 2251799813685248 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 2251799813685248 -// 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_e._Mls64 -// CHECK: resolver_else: -// CHECK-NEXT: ret ptr @fmv_e.default -// -// -// CHECK-LABEL: define {{[^@]+}}@fmv_d.resolver() { -// 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]], 70368744177664 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 70368744177664 -// 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_d._Msb -// CHECK: resolver_else: -// CHECK-NEXT: ret ptr @fmv_d.default -// -// -// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat { -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 281474976710656 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 281474976710656 -// 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_c._Mssbs -// CHECK: resolver_else: -// CHECK-NEXT: ret ptr @fmv_c.default -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_default -// CHECK-SAME: () #[[ATTR11]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 111 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@recur -// CHECK-SAME: () #[[ATTR11]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: call void @reca() -// CHECK-NEXT: ret void -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@hoo -// CHECK-SAME: () #[[ATTR11]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: [[FP1:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: [[FP2:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: call void @f(ptr noundef @fmv) -// CHECK-NEXT: store ptr @fmv, ptr [[FP1]], align 8 -// CHECK-NEXT: store ptr @fmv, ptr [[FP2]], align 8 -// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[FP1]], align 8 -// CHECK-NEXT: [[CALL:%.*]] = call i32 [[TMP0]]() -// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[FP2]], align 8 -// CHECK-NEXT: [[CALL1:%.*]] = call i32 [[TMP1]]() -// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] -// CHECK-NEXT: ret i32 [[ADD]] -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_forward_default_decl._Mmops -// CHECK-SAME: () #[[ATTR14:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 0 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_extern_forward_default_decl._Mdotprod -// CHECK-SAME: () #[[ATTR15:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 0 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_default_decl._Maes -// CHECK-SAME: () #[[ATTR5]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 0 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_default_def._Msve -// CHECK-SAME: () #[[ATTR16:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 0 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_default_def.default -// CHECK-SAME: () #[[ATTR11]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_default_def._Mfp16 -// CHECK-SAME: () #[[ATTR12]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 0 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_default_def.default -// CHECK-SAME: () #[[ATTR11]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def.default -// CHECK-SAME: () #[[ATTR11]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 0 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def._Mlse -// CHECK-SAME: () #[[ATTR17:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_without_default._Mrdm -// CHECK-SAME: () #[[ATTR18:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 0 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@default_def_with_version_decls.default -// CHECK-SAME: () #[[ATTR11]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 0 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@used_def_without_default_decl._Mjscvt -// CHECK-SAME: () #[[ATTR21:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@used_def_without_default_decl._Mrdm -// CHECK-SAME: () #[[ATTR18]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 2 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@caller -// CHECK-SAME: () #[[ATTR11]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: [[CALL:%.*]] = call i32 @used_def_without_default_decl() -// CHECK-NEXT: [[CALL1:%.*]] = call i32 @used_decl_without_default_decl() -// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] -// CHECK-NEXT: ret i32 [[ADD]] -// -// -// CHECK-LABEL: define {{[^@]+}}@used_def_without_default_decl.resolver() comdat { -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1048576 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1048576 -// 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 @used_def_without_default_decl._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: [[TMP7:%.*]] = and i1 true, [[TMP6]] -// CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] -// CHECK: resolver_return1: -// CHECK-NEXT: ret ptr @used_def_without_default_decl._Mrdm -// CHECK: resolver_else2: -// CHECK-NEXT: ret ptr @used_def_without_default_decl.default -// -// -// CHECK-LABEL: define {{[^@]+}}@used_decl_without_default_decl.resolver() comdat { -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1048576 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1048576 -// 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 @used_decl_without_default_decl._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: [[TMP7:%.*]] = and i1 true, [[TMP6]] -// CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] -// CHECK: resolver_return1: -// CHECK-NEXT: ret ptr @used_decl_without_default_decl._Mrdm -// CHECK: resolver_else2: -// CHECK-NEXT: ret ptr @used_decl_without_default_decl.default -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@main -// CHECK-SAME: () #[[ATTR11]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 -// CHECK-NEXT: call void @recur() -// CHECK-NEXT: [[CALL:%.*]] = call i32 @goo() -// CHECK-NEXT: ret i32 [[CALL]] -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mf64mmMpmullMsha1 -// CHECK-SAME: () #[[ATTR22:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline._MfcmaMfp16MrdmMsme -// CHECK-SAME: () #[[ATTR23:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 2 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mf32mmMi8mmMsha3 -// CHECK-SAME: () #[[ATTR24:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 12 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline._MditMsve-ebf16 -// CHECK-SAME: () #[[ATTR25:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 8 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline._MdpbMrcpc2 -// CHECK-SAME: () #[[ATTR26:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 6 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mdpb2Mjscvt -// CHECK-SAME: () #[[ATTR27:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 7 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline._MfrinttsMrcpc -// CHECK-SAME: () #[[ATTR28:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 3 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline._MsveMsve-bf16 -// CHECK-SAME: () #[[ATTR29:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 4 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline._Msve2-aesMsve2-sha3 -// CHECK-SAME: () #[[ATTR30:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 5 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline._Msve2Msve2-bitpermMsve2-pmull128 -// CHECK-SAME: () #[[ATTR31:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 9 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mmemtag2Msve2-sm4 -// CHECK-SAME: () #[[ATTR32:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 10 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mmemtag3MmopsMrcpc3 -// CHECK-SAME: () #[[ATTR33:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 11 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline._MaesMdotprod -// CHECK-SAME: () #[[ATTR15]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 13 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mfp16fmlMsimd -// CHECK-SAME: () #[[ATTR4]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 14 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline._MfpMsm4 -// CHECK-SAME: () #[[ATTR34:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 15 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline._MlseMrdm -// CHECK-SAME: () #[[ATTR35:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 16 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_inline.default -// CHECK-SAME: () #[[ATTR11]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 3 -// -// // CHECK-LABEL: define {{[^@]+}}@unused_with_default_def.resolver() comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() @@ -1013,6 +988,27 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // // // CHECK-NOFMV: Function Attrs: noinline nounwind optnone +// CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv +// CHECK-NOFMV-SAME: () #[[ATTR0]] { +// CHECK-NOFMV-NEXT: entry: +// CHECK-NOFMV-NEXT: ret i32 0 +// +// +// CHECK-NOFMV: Function Attrs: noinline nounwind optnone +// CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv_one +// CHECK-NOFMV-SAME: () #[[ATTR0]] { +// CHECK-NOFMV-NEXT: entry: +// CHECK-NOFMV-NEXT: ret i32 0 +// +// +// CHECK-NOFMV: Function Attrs: noinline nounwind optnone +// CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv_two +// CHECK-NOFMV-SAME: () #[[ATTR0]] { +// CHECK-NOFMV-NEXT: entry: +// CHECK-NOFMV-NEXT: ret i32 0 +// +// +// CHECK-NOFMV: Function Attrs: noinline nounwind optnone // CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv_e // CHECK-NOFMV-SAME: () #[[ATTR0]] { // CHECK-NOFMV-NEXT: entry: @@ -1116,42 +1112,42 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NOFMV-NEXT: ret i32 1 // //. -// CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+flagm,+fp-armv8,+fp16fml,+fullfp16,+neon,+rand,-v9.5a" } -// CHECK: attributes #[[ATTR1]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+altnzcv,+bf16,+flagm,+sme,+sme-i16i64,-fp-armv8,-v9.5a" } -// CHECK: attributes #[[ATTR2]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+lse,+neon,+sha2,-v9.5a" } -// CHECK: attributes #[[ATTR3]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+ls64,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR4]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fp16fml,+fullfp16,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR5]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR6]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc,-fp-armv8,-v9.5a" } -// CHECK: attributes #[[ATTR7]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bti,-fp-armv8,-v9.5a" } -// CHECK: attributes #[[ATTR8]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme2,-fp-armv8,-v9.5a" } -// CHECK: attributes #[[ATTR9:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fp-armv8,-v9.5a" } -// CHECK: attributes #[[ATTR10]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,-fp-armv8,-v9.5a" } -// CHECK: attributes #[[ATTR11]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fp-armv8,-v9.5a" } -// CHECK: attributes #[[ATTR12]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR13]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+sb,-fp-armv8,-v9.5a" } -// CHECK: attributes #[[ATTR14]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops,-fp-armv8,-v9.5a" } -// CHECK: attributes #[[ATTR15]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR16]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,-v9.5a" } -// CHECK: attributes #[[ATTR17]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse,-fp-armv8,-v9.5a" } -// CHECK: attributes #[[ATTR18]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rdm,-v9.5a" } -// CHECK: attributes #[[ATTR19:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+jsconv,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR20:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rdm,-v9.5a" } -// CHECK: attributes #[[ATTR21]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+jsconv,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR22]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+aes,+f64mm,+fp-armv8,+fullfp16,+neon,+sve,-v9.5a" } -// CHECK: attributes #[[ATTR23]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+complxnum,+fp-armv8,+fullfp16,+neon,+rdm,+sme,-v9.5a" } -// CHECK: attributes #[[ATTR24]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+f32mm,+fp-armv8,+fullfp16,+i8mm,+neon,+sha2,+sha3,+sve,-v9.5a" } -// CHECK: attributes #[[ATTR25]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+dit,+fp-armv8,+fullfp16,+neon,+sve,-v9.5a" } -// CHECK: attributes #[[ATTR26]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,+rcpc,-fp-armv8,-v9.5a" } -// CHECK: attributes #[[ATTR27]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccdp,+ccpp,+fp-armv8,+jsconv,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR28]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fptoint,+rcpc,-fp-armv8,-v9.5a" } -// CHECK: attributes #[[ATTR29]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+fullfp16,+neon,+sve,-v9.5a" } -// CHECK: attributes #[[ATTR30]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2,+sve2-aes,+sve2-sha3,-v9.5a" } -// CHECK: attributes #[[ATTR31]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2,+sve2-aes,+sve2-bitperm,-v9.5a" } -// CHECK: attributes #[[ATTR32]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+mte,+neon,+sve,+sve2,+sve2-sm4,-v9.5a" } -// CHECK: attributes #[[ATTR33]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops,+mte,+rcpc,+rcpc3,-fp-armv8,-v9.5a" } -// CHECK: attributes #[[ATTR34]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+sm4,-v9.5a" } -// CHECK: attributes #[[ATTR35]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+lse,+neon,+rdm,-v9.5a" } +// CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+flagm,+fp-armv8,+fp16fml,+fullfp16,+neon,+rand" } +// CHECK: attributes #[[ATTR1]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+altnzcv,+bf16,+flagm,+sme,+sme-i16i64" } +// CHECK: attributes #[[ATTR2]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+lse,+neon,+sha2" } +// CHECK: attributes #[[ATTR3]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+ls64,+neon" } +// CHECK: attributes #[[ATTR4]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fp16fml,+fullfp16,+neon" } +// CHECK: attributes #[[ATTR5]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon" } +// CHECK: attributes #[[ATTR6]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc" } +// CHECK: attributes #[[ATTR7]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bti" } +// CHECK: attributes #[[ATTR8]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme2" } +// CHECK: attributes #[[ATTR9]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// CHECK: attributes #[[ATTR10]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp" } +// CHECK: attributes #[[ATTR11]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon" } +// CHECK: attributes #[[ATTR12:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// CHECK: attributes #[[ATTR13]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops" } +// CHECK: attributes #[[ATTR14]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon" } +// CHECK: attributes #[[ATTR15]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" } +// CHECK: attributes #[[ATTR16]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse" } +// CHECK: attributes #[[ATTR17]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rdm" } +// CHECK: attributes #[[ATTR18:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+jsconv,+neon" } +// CHECK: attributes #[[ATTR19]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+jsconv,+neon" } +// CHECK: attributes #[[ATTR20]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+sb" } +// CHECK: attributes #[[ATTR21]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+aes,+f64mm,+fp-armv8,+fullfp16,+neon,+sve" } +// CHECK: attributes #[[ATTR22]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+complxnum,+fp-armv8,+fullfp16,+neon,+rdm,+sme" } +// CHECK: attributes #[[ATTR23]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+f32mm,+fp-armv8,+fullfp16,+i8mm,+neon,+sha2,+sha3,+sve" } +// CHECK: attributes #[[ATTR24]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+dit,+fp-armv8,+fullfp16,+neon,+sve" } +// CHECK: attributes #[[ATTR25]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,+rcpc" } +// CHECK: attributes #[[ATTR26]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccdp,+ccpp,+fp-armv8,+jsconv,+neon" } +// CHECK: attributes #[[ATTR27]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fptoint,+rcpc" } +// CHECK: attributes #[[ATTR28]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+fullfp16,+neon,+sve" } +// CHECK: attributes #[[ATTR29]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2,+sve2-aes,+sve2-sha3" } +// CHECK: attributes #[[ATTR30]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2,+sve2-aes,+sve2-bitperm" } +// CHECK: attributes #[[ATTR31]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+mte,+neon,+sve,+sve2,+sve2-sm4" } +// CHECK: attributes #[[ATTR32]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops,+mte,+rcpc,+rcpc3" } +// CHECK: attributes #[[ATTR33]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+sm4" } +// CHECK: attributes #[[ATTR34]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+lse,+neon,+rdm" } +// CHECK: attributes #[[ATTR35:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rdm" } //. // CHECK-NOFMV: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fmv" } // CHECK-NOFMV: attributes #[[ATTR1:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fmv" } diff --git a/clang/test/CodeGen/attr-target-x86-mmx.c b/clang/test/CodeGen/attr-target-x86-mmx.c index 01663766d9842..39b26619475af 100644 --- a/clang/test/CodeGen/attr-target-x86-mmx.c +++ b/clang/test/CodeGen/attr-target-x86-mmx.c @@ -1,12 +1,11 @@ // RUN: %clang_cc1 -triple i386-linux-gnu -emit-llvm %s -o - | FileCheck %s -// Picking a cpu that doesn't have mmx or sse by default so we can enable it later. +// Picking a cpu that doesn't have sse by default so we can enable it later. #define __MM_MALLOC_H #include -// Verify that when we turn on sse that we also turn on mmx. -void __attribute__((target("sse"))) shift(__m64 a, __m64 b, int c) { +void __attribute__((target("sse2"))) shift(__m64 a, __m64 b, int c) { _mm_slli_pi16(a, c); _mm_slli_pi32(a, c); _mm_slli_si64(a, c); @@ -19,4 +18,4 @@ void __attribute__((target("sse"))) shift(__m64 a, __m64 b, int c) { _mm_srai_pi32(a, c); } -// CHECK: "target-features"="+cx8,+mmx,+sse,+x87" +// CHECK: "target-features"="+cx8,+mmx,+sse,+sse2,+x87" diff --git a/clang/test/CodeGen/attr-target-x86.c b/clang/test/CodeGen/attr-target-x86.c index 3c2b511157f99..b1ae6678531b9 100644 --- a/clang/test/CodeGen/attr-target-x86.c +++ b/clang/test/CodeGen/attr-target-x86.c @@ -64,7 +64,7 @@ void __attribute__((target("avx10.1-512"))) avx10_1_512(void) {} // CHECK: #4 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87,-avx,-avx10.1-256,-avx10.1-512,-avx2,-avx512bf16,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512f,-avx512fp16,-avx512ifma,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vp2intersect,-avx512vpopcntdq,-avxifma,-avxneconvert,-avxvnni,-avxvnniint16,-avxvnniint8,-f16c,-fma,-fma4,-sha512,-sm3,-sm4,-sse4.1,-sse4.2,-vaes,-vpclmulqdq,-xop" "tune-cpu"="i686" // CHECK: #5 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cmov,+crc32,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt,-aes,-avx10.1-256,-avx10.1-512,-vaes" // CHECK-NOT: tune-cpu -// CHECK: #6 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87,-3dnow,-3dnowa,-mmx" +// CHECK: #6 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87,-mmx" // CHECK: #7 = {{.*}}"target-cpu"="lakemont" "target-features"="+cx8,+mmx" // CHECK-NOT: tune-cpu // CHECK: #8 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87" "tune-cpu"="sandybridge" diff --git a/clang/test/CodeGen/builtin-cpu-supports.c b/clang/test/CodeGen/builtin-cpu-supports.c index 88eb7b0fa786e..92c407653e660 100644 --- a/clang/test/CodeGen/builtin-cpu-supports.c +++ b/clang/test/CodeGen/builtin-cpu-supports.c @@ -3,8 +3,11 @@ // RUN: FileCheck %s --check-prefix=CHECK-X86 // RUN: %clang_cc1 -triple ppc64le-linux-gnu -emit-llvm -o - %s | FileCheck %s \ // RUN: --check-prefix=CHECK-PPC - -#ifndef __PPC__ +// RUN: %clang_cc1 -triple riscv32-linux-gnu -emit-llvm -o - %s | FileCheck %s \ +// RUN: --check-prefix=CHECK-RV32 +// RUN: %clang_cc1 -triple riscv64-linux-gnu -emit-llvm -o - %s | FileCheck %s \ +// RUN: --check-prefix=CHECK-RV64 +#ifdef __x86_64__ // Test that we have the structure definition, the gep offsets, the name of the // global, the bit grab, and the icmp correct. @@ -101,8 +104,10 @@ int v3() { return __builtin_cpu_supports("x86-64-v3"); } // CHECK-X86-NEXT: ret i32 [[CONV]] // int v4() { return __builtin_cpu_supports("x86-64-v4"); } -#else -// CHECK-PPC-LABEL: define dso_local signext i32 @test( +#endif + +#ifdef __PPC__ +// CHECK-PPC-LABEL: define dso_local signext i32 @test_ppc( // CHECK-PPC-SAME: i32 noundef signext [[A:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-PPC-NEXT: entry: // CHECK-PPC-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 @@ -129,33 +134,206 @@ int v4() { return __builtin_cpu_supports("x86-64-v4"); } // CHECK-PPC: if.else3: // CHECK-PPC-NEXT: [[CPU_IS:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 3) // CHECK-PPC-NEXT: [[TMP6:%.*]] = icmp eq i32 [[CPU_IS]], 39 -// CHECK-PPC-NEXT: br i1 [[TMP6]], label [[IF_THEN4:%.*]], label [[IF_END:%.*]] +// CHECK-PPC-NEXT: br i1 [[TMP6]], label [[IF_THEN4:%.*]], label [[IF_ELSE5:%.*]] // CHECK-PPC: if.then4: // CHECK-PPC-NEXT: [[TMP7:%.*]] = load i32, ptr [[A_ADDR]], align 4 // CHECK-PPC-NEXT: [[TMP8:%.*]] = load i32, ptr [[A_ADDR]], align 4 // CHECK-PPC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP7]], [[TMP8]] // CHECK-PPC-NEXT: store i32 [[ADD]], ptr [[RETVAL]], align 4 // CHECK-PPC-NEXT: br label [[RETURN]] +// CHECK-PPC: if.else5: +// CHECK-PPC-NEXT: [[CPU_IS6:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 3) +// CHECK-PPC-NEXT: [[TMP9:%.*]] = icmp eq i32 [[CPU_IS6]], 39 +// CHECK-PPC-NEXT: br i1 [[TMP9]], label [[IF_THEN7:%.*]], label [[IF_ELSE8:%.*]] +// CHECK-PPC: if.then7: +// CHECK-PPC-NEXT: [[TMP10:%.*]] = load i32, ptr [[A_ADDR]], align 4 +// CHECK-PPC-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 3 +// CHECK-PPC-NEXT: store i32 [[MUL]], ptr [[RETVAL]], align 4 +// CHECK-PPC-NEXT: br label [[RETURN]] +// CHECK-PPC: if.else8: +// CHECK-PPC-NEXT: [[CPU_IS9:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 3) +// CHECK-PPC-NEXT: [[TMP11:%.*]] = icmp eq i32 [[CPU_IS9]], 33 +// CHECK-PPC-NEXT: br i1 [[TMP11]], label [[IF_THEN10:%.*]], label [[IF_ELSE12:%.*]] +// CHECK-PPC: if.then10: +// CHECK-PPC-NEXT: [[TMP12:%.*]] = load i32, ptr [[A_ADDR]], align 4 +// CHECK-PPC-NEXT: [[MUL11:%.*]] = mul nsw i32 [[TMP12]], 4 +// CHECK-PPC-NEXT: store i32 [[MUL11]], ptr [[RETVAL]], align 4 +// CHECK-PPC-NEXT: br label [[RETURN]] +// CHECK-PPC: if.else12: +// CHECK-PPC-NEXT: [[CPU_IS13:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 3) +// CHECK-PPC-NEXT: [[TMP13:%.*]] = icmp eq i32 [[CPU_IS13]], 45 +// CHECK-PPC-NEXT: br i1 [[TMP13]], label [[IF_THEN14:%.*]], label [[IF_ELSE16:%.*]] +// CHECK-PPC: if.then14: +// CHECK-PPC-NEXT: [[TMP14:%.*]] = load i32, ptr [[A_ADDR]], align 4 +// CHECK-PPC-NEXT: [[ADD15:%.*]] = add nsw i32 [[TMP14]], 3 +// CHECK-PPC-NEXT: store i32 [[ADD15]], ptr [[RETVAL]], align 4 +// CHECK-PPC-NEXT: br label [[RETURN]] +// CHECK-PPC: if.else16: +// CHECK-PPC-NEXT: [[CPU_IS17:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 3) +// CHECK-PPC-NEXT: [[TMP15:%.*]] = icmp eq i32 [[CPU_IS17]], 46 +// CHECK-PPC-NEXT: br i1 [[TMP15]], label [[IF_THEN18:%.*]], label [[IF_ELSE20:%.*]] +// CHECK-PPC: if.then18: +// CHECK-PPC-NEXT: [[TMP16:%.*]] = load i32, ptr [[A_ADDR]], align 4 +// CHECK-PPC-NEXT: [[SUB19:%.*]] = sub nsw i32 [[TMP16]], 3 +// CHECK-PPC-NEXT: store i32 [[SUB19]], ptr [[RETVAL]], align 4 +// CHECK-PPC-NEXT: br label [[RETURN]] +// CHECK-PPC: if.else20: +// CHECK-PPC-NEXT: [[CPU_IS21:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 3) +// CHECK-PPC-NEXT: [[TMP17:%.*]] = icmp eq i32 [[CPU_IS21]], 47 +// CHECK-PPC-NEXT: br i1 [[TMP17]], label [[IF_THEN22:%.*]], label [[IF_ELSE24:%.*]] +// CHECK-PPC: if.then22: +// CHECK-PPC-NEXT: [[TMP18:%.*]] = load i32, ptr [[A_ADDR]], align 4 +// CHECK-PPC-NEXT: [[ADD23:%.*]] = add nsw i32 [[TMP18]], 7 +// CHECK-PPC-NEXT: store i32 [[ADD23]], ptr [[RETVAL]], align 4 +// CHECK-PPC-NEXT: br label [[RETURN]] +// CHECK-PPC: if.else24: +// CHECK-PPC-NEXT: [[CPU_IS25:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 3) +// CHECK-PPC-NEXT: [[TMP19:%.*]] = icmp eq i32 [[CPU_IS25]], 48 +// CHECK-PPC-NEXT: br i1 [[TMP19]], label [[IF_THEN26:%.*]], label [[IF_END:%.*]] +// CHECK-PPC: if.then26: +// CHECK-PPC-NEXT: [[TMP20:%.*]] = load i32, ptr [[A_ADDR]], align 4 +// CHECK-PPC-NEXT: [[SUB27:%.*]] = sub nsw i32 [[TMP20]], 7 +// CHECK-PPC-NEXT: store i32 [[SUB27]], ptr [[RETVAL]], align 4 +// CHECK-PPC-NEXT: br label [[RETURN]] // CHECK-PPC: if.end: -// CHECK-PPC-NEXT: br label [[IF_END5:%.*]] -// CHECK-PPC: if.end5: -// CHECK-PPC-NEXT: br label [[IF_END6:%.*]] -// CHECK-PPC: if.end6: -// CHECK-PPC-NEXT: [[TMP9:%.*]] = load i32, ptr [[A_ADDR]], align 4 -// CHECK-PPC-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP9]], 5 -// CHECK-PPC-NEXT: store i32 [[ADD7]], ptr [[RETVAL]], align 4 +// CHECK-PPC-NEXT: br label [[IF_END28:%.*]] +// CHECK-PPC: if.end28: +// CHECK-PPC-NEXT: br label [[IF_END29:%.*]] +// CHECK-PPC: if.end29: +// CHECK-PPC-NEXT: br label [[IF_END30:%.*]] +// CHECK-PPC: if.end30: +// CHECK-PPC-NEXT: br label [[IF_END31:%.*]] +// CHECK-PPC: if.end31: +// CHECK-PPC-NEXT: br label [[IF_END32:%.*]] +// CHECK-PPC: if.end32: +// CHECK-PPC-NEXT: br label [[IF_END33:%.*]] +// CHECK-PPC: if.end33: +// CHECK-PPC-NEXT: br label [[IF_END34:%.*]] +// CHECK-PPC: if.end34: +// CHECK-PPC-NEXT: br label [[IF_END35:%.*]] +// CHECK-PPC: if.end35: +// CHECK-PPC-NEXT: [[TMP21:%.*]] = load i32, ptr [[A_ADDR]], align 4 +// CHECK-PPC-NEXT: [[ADD36:%.*]] = add nsw i32 [[TMP21]], 5 +// CHECK-PPC-NEXT: store i32 [[ADD36]], ptr [[RETVAL]], align 4 // CHECK-PPC-NEXT: br label [[RETURN]] // CHECK-PPC: return: -// CHECK-PPC-NEXT: [[TMP10:%.*]] = load i32, ptr [[RETVAL]], align 4 -// CHECK-PPC-NEXT: ret i32 [[TMP10]] +// CHECK-PPC-NEXT: [[TMP22:%.*]] = load i32, ptr [[RETVAL]], align 4 +// CHECK-PPC-NEXT: ret i32 [[TMP22]] // -int test(int a) { +int test_ppc(int a) { if (__builtin_cpu_supports("arch_3_00")) // HWCAP2 return a; else if (__builtin_cpu_supports("mmu")) // HWCAP return a - 5; else if (__builtin_cpu_is("power7")) // CPUID return a + a; + else if (__builtin_cpu_is("pwr7")) // CPUID + return a * 3; + else if (__builtin_cpu_is("ppc970")) // CPUID + return a * 4; + else if (__builtin_cpu_is("power8")) + return a + 3; + else if (__builtin_cpu_is("power9")) + return a - 3; + else if (__builtin_cpu_is("power10")) + return a + 7; + else if (__builtin_cpu_is("power11")) + return a - 7; return a + 5; } #endif + +#ifdef __riscv +// CHECK-RV32-LABEL: define dso_local i32 @test_riscv( +// CHECK-RV32-SAME: i32 noundef [[A:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV32-NEXT: entry: +// CHECK-RV32-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV32-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 +// CHECK-RV32-NEXT: call void @__init_riscv_feature_bits() +// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 +// CHECK-RV32-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1 +// CHECK-RV32-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1 +// CHECK-RV32-NEXT: br i1 [[TMP2]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +// CHECK-RV32: if.then: +// CHECK-RV32-NEXT: store i32 3, ptr [[RETVAL]], align 4 +// CHECK-RV32-NEXT: br label [[RETURN:%.*]] +// CHECK-RV32: if.else: +// CHECK-RV32-NEXT: [[TMP3:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 +// CHECK-RV32-NEXT: [[TMP4:%.*]] = and i64 [[TMP3]], 4 +// CHECK-RV32-NEXT: [[TMP5:%.*]] = icmp eq i64 [[TMP4]], 4 +// CHECK-RV32-NEXT: br i1 [[TMP5]], label [[IF_THEN1:%.*]], label [[IF_ELSE2:%.*]] +// CHECK-RV32: if.then1: +// CHECK-RV32-NEXT: store i32 7, ptr [[RETVAL]], align 4 +// CHECK-RV32-NEXT: br label [[RETURN]] +// CHECK-RV32: if.else2: +// CHECK-RV32-NEXT: [[TMP6:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 +// CHECK-RV32-NEXT: [[TMP7:%.*]] = and i64 [[TMP6]], 2097152 +// CHECK-RV32-NEXT: [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 2097152 +// CHECK-RV32-NEXT: br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_END:%.*]] +// CHECK-RV32: if.then3: +// CHECK-RV32-NEXT: store i32 11, ptr [[RETVAL]], align 4 +// CHECK-RV32-NEXT: br label [[RETURN]] +// CHECK-RV32: if.end: +// CHECK-RV32-NEXT: br label [[IF_END4:%.*]] +// CHECK-RV32: if.end4: +// CHECK-RV32-NEXT: br label [[IF_END5:%.*]] +// CHECK-RV32: if.end5: +// CHECK-RV32-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK-RV32-NEXT: br label [[RETURN]] +// CHECK-RV32: return: +// CHECK-RV32-NEXT: [[TMP9:%.*]] = load i32, ptr [[RETVAL]], align 4 +// CHECK-RV32-NEXT: ret i32 [[TMP9]] +// +// CHECK-RV64-LABEL: define dso_local signext i32 @test_riscv( +// CHECK-RV64-SAME: i32 noundef signext [[A:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK-RV64-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 +// CHECK-RV64-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 +// CHECK-RV64-NEXT: call void @__init_riscv_feature_bits() +// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1 +// CHECK-RV64-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1 +// CHECK-RV64-NEXT: br i1 [[TMP2]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +// CHECK-RV64: if.then: +// CHECK-RV64-NEXT: store i32 3, ptr [[RETVAL]], align 4 +// CHECK-RV64-NEXT: br label [[RETURN:%.*]] +// CHECK-RV64: if.else: +// CHECK-RV64-NEXT: [[TMP3:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 +// CHECK-RV64-NEXT: [[TMP4:%.*]] = and i64 [[TMP3]], 4 +// CHECK-RV64-NEXT: [[TMP5:%.*]] = icmp eq i64 [[TMP4]], 4 +// CHECK-RV64-NEXT: br i1 [[TMP5]], label [[IF_THEN1:%.*]], label [[IF_ELSE2:%.*]] +// CHECK-RV64: if.then1: +// CHECK-RV64-NEXT: store i32 7, ptr [[RETVAL]], align 4 +// CHECK-RV64-NEXT: br label [[RETURN]] +// CHECK-RV64: if.else2: +// CHECK-RV64-NEXT: [[TMP6:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 +// CHECK-RV64-NEXT: [[TMP7:%.*]] = and i64 [[TMP6]], 2097152 +// CHECK-RV64-NEXT: [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 2097152 +// CHECK-RV64-NEXT: br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_END:%.*]] +// CHECK-RV64: if.then3: +// CHECK-RV64-NEXT: store i32 11, ptr [[RETVAL]], align 4 +// CHECK-RV64-NEXT: br label [[RETURN]] +// CHECK-RV64: if.end: +// CHECK-RV64-NEXT: br label [[IF_END4:%.*]] +// CHECK-RV64: if.end4: +// CHECK-RV64-NEXT: br label [[IF_END5:%.*]] +// CHECK-RV64: if.end5: +// CHECK-RV64-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK-RV64-NEXT: br label [[RETURN]] +// CHECK-RV64: return: +// CHECK-RV64-NEXT: [[TMP9:%.*]] = load i32, ptr [[RETVAL]], align 4 +// CHECK-RV64-NEXT: ret i32 [[TMP9]] +// +int test_riscv(int a) { + __builtin_cpu_init(); + if (__builtin_cpu_supports("a")) + return 3; + else if (__builtin_cpu_supports("c")) + return 7; + else if (__builtin_cpu_supports("v")) + return 11; + return 0; +} +#endif diff --git a/clang/test/CodeGen/builtins-wasm.c b/clang/test/CodeGen/builtins-wasm.c index 75861b1b4bd6d..f494aeada0157 100644 --- a/clang/test/CodeGen/builtins-wasm.c +++ b/clang/test/CodeGen/builtins-wasm.c @@ -840,6 +840,12 @@ float extract_lane_f16x8(f16x8 a, int i) { return __builtin_wasm_extract_lane_f16x8(a, i); } +f16x8 replace_lane_f16x8(f16x8 a, int i, float v) { + // WEBASSEMBLY: %0 = tail call <8 x half> @llvm.wasm.replace.lane.f16x8(<8 x half> %a, i32 %i, float %v) + // WEBASSEMBLY-NEXT: ret <8 x half> %0 + return __builtin_wasm_replace_lane_f16x8(a, i, v); +} + f16x8 min_f16x8(f16x8 a, f16x8 b) { // WEBASSEMBLY: %0 = tail call <8 x half> @llvm.minimum.v8f16(<8 x half> %a, <8 x half> %b) // WEBASSEMBLY-NEXT: ret <8 x half> %0 diff --git a/clang/test/CodeGen/builtins-x86.c b/clang/test/CodeGen/builtins-x86.c index de31a4db5b0c1..c42c3216ec53c 100644 --- a/clang/test/CodeGen/builtins-x86.c +++ b/clang/test/CodeGen/builtins-x86.c @@ -168,26 +168,6 @@ void f0(void) { tmp_V4f = __builtin_ia32_minss(tmp_V4f, tmp_V4f); tmp_V4f = __builtin_ia32_maxss(tmp_V4f, tmp_V4f); - tmp_V8c = __builtin_ia32_paddsb(tmp_V8c, tmp_V8c); - tmp_V4s = __builtin_ia32_paddsw(tmp_V4s, tmp_V4s); - tmp_V8c = __builtin_ia32_psubsb(tmp_V8c, tmp_V8c); - tmp_V4s = __builtin_ia32_psubsw(tmp_V4s, tmp_V4s); - tmp_V8c = __builtin_ia32_paddusb(tmp_V8c, tmp_V8c); - tmp_V4s = __builtin_ia32_paddusw(tmp_V4s, tmp_V4s); - tmp_V8c = __builtin_ia32_psubusb(tmp_V8c, tmp_V8c); - tmp_V4s = __builtin_ia32_psubusw(tmp_V4s, tmp_V4s); - tmp_V4s = __builtin_ia32_pmulhw(tmp_V4s, tmp_V4s); - tmp_V4s = __builtin_ia32_pmulhuw(tmp_V4s, tmp_V4s); - tmp_V8c = __builtin_ia32_pcmpeqb(tmp_V8c, tmp_V8c); - tmp_V4s = __builtin_ia32_pcmpeqw(tmp_V4s, tmp_V4s); - tmp_V2i = __builtin_ia32_pcmpeqd(tmp_V2i, tmp_V2i); - tmp_V8c = __builtin_ia32_pcmpgtb(tmp_V8c, tmp_V8c); - tmp_V4s = __builtin_ia32_pcmpgtw(tmp_V4s, tmp_V4s); - tmp_V2i = __builtin_ia32_pcmpgtd(tmp_V2i, tmp_V2i); - tmp_V8c = __builtin_ia32_pmaxub(tmp_V8c, tmp_V8c); - tmp_V4s = __builtin_ia32_pmaxsw(tmp_V4s, tmp_V4s); - tmp_V8c = __builtin_ia32_pminub(tmp_V8c, tmp_V8c); - tmp_V4s = __builtin_ia32_pminsw(tmp_V4s, tmp_V4s); tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 0); tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 1); tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 2); @@ -220,45 +200,17 @@ void f0(void) { tmp_V4f = __builtin_ia32_hsubps(tmp_V4f, tmp_V4f); tmp_V2d = __builtin_ia32_hsubpd(tmp_V2d, tmp_V2d); tmp_V8s = __builtin_ia32_phaddw128(tmp_V8s, tmp_V8s); - tmp_V4s = __builtin_ia32_phaddw(tmp_V4s, tmp_V4s); tmp_V4i = __builtin_ia32_phaddd128(tmp_V4i, tmp_V4i); - tmp_V2i = __builtin_ia32_phaddd(tmp_V2i, tmp_V2i); tmp_V8s = __builtin_ia32_phaddsw128(tmp_V8s, tmp_V8s); - tmp_V4s = __builtin_ia32_phaddsw(tmp_V4s, tmp_V4s); tmp_V8s = __builtin_ia32_phsubw128(tmp_V8s, tmp_V8s); - tmp_V4s = __builtin_ia32_phsubw(tmp_V4s, tmp_V4s); tmp_V4i = __builtin_ia32_phsubd128(tmp_V4i, tmp_V4i); - tmp_V2i = __builtin_ia32_phsubd(tmp_V2i, tmp_V2i); tmp_V8s = __builtin_ia32_phsubsw128(tmp_V8s, tmp_V8s); - tmp_V4s = __builtin_ia32_phsubsw(tmp_V4s, tmp_V4s); tmp_V8s = __builtin_ia32_pmaddubsw128(tmp_V16c, tmp_V16c); - tmp_V8c = __builtin_ia32_pmaddubsw(tmp_V8c, tmp_V8c); tmp_V8s = __builtin_ia32_pmulhrsw128(tmp_V8s, tmp_V8s); - tmp_V4s = __builtin_ia32_pmulhrsw(tmp_V4s, tmp_V4s); tmp_V16c = __builtin_ia32_pshufb128(tmp_V16c, tmp_V16c); - tmp_V8c = __builtin_ia32_pshufb(tmp_V8c, tmp_V8c); tmp_V16c = __builtin_ia32_psignb128(tmp_V16c, tmp_V16c); - tmp_V8c = __builtin_ia32_psignb(tmp_V8c, tmp_V8c); tmp_V8s = __builtin_ia32_psignw128(tmp_V8s, tmp_V8s); - tmp_V4s = __builtin_ia32_psignw(tmp_V4s, tmp_V4s); tmp_V4i = __builtin_ia32_psignd128(tmp_V4i, tmp_V4i); - tmp_V2i = __builtin_ia32_psignd(tmp_V2i, tmp_V2i); - tmp_V8c = __builtin_ia32_pabsb(tmp_V8c); - tmp_V4s = __builtin_ia32_pabsw(tmp_V4s); - tmp_V2i = __builtin_ia32_pabsd(tmp_V2i); - tmp_V4s = __builtin_ia32_psllw(tmp_V4s, tmp_V1LLi); - tmp_V2i = __builtin_ia32_pslld(tmp_V2i, tmp_V1LLi); - tmp_V1LLi = __builtin_ia32_psllq(tmp_V1LLi, tmp_V1LLi); - tmp_V4s = __builtin_ia32_psrlw(tmp_V4s, tmp_V1LLi); - tmp_V2i = __builtin_ia32_psrld(tmp_V2i, tmp_V1LLi); - tmp_V1LLi = __builtin_ia32_psrlq(tmp_V1LLi, tmp_V1LLi); - tmp_V4s = __builtin_ia32_psraw(tmp_V4s, tmp_V1LLi); - tmp_V2i = __builtin_ia32_psrad(tmp_V2i, tmp_V1LLi); - tmp_V2i = __builtin_ia32_pmaddwd(tmp_V4s, tmp_V4s); - tmp_V8c = __builtin_ia32_packsswb(tmp_V4s, tmp_V4s); - tmp_V4s = __builtin_ia32_packssdw(tmp_V2i, tmp_V2i); - tmp_V8c = __builtin_ia32_packuswb(tmp_V4s, tmp_V4s); - tmp_i = __builtin_ia32_vec_ext_v2si(tmp_V2i, 0); __builtin_ia32_incsspd(tmp_Ui); __builtin_ia32_incsspq(tmp_ULLi); @@ -306,8 +258,6 @@ void f0(void) { (void) __builtin_ia32_clzero(tmp_vp); (void) __builtin_ia32_cldemote(tmp_vp); - tmp_V4f = __builtin_ia32_cvtpi2ps(tmp_V4f, tmp_V2i); - tmp_V2i = __builtin_ia32_cvtps2pi(tmp_V4f); tmp_i = __builtin_ia32_cvtss2si(tmp_V4f); tmp_i = __builtin_ia32_cvttss2si(tmp_V4f); @@ -320,17 +270,12 @@ void f0(void) { tmp_LLi = __builtin_ia32_cvtss2si64(tmp_V4f); tmp_LLi = __builtin_ia32_cvttss2si64(tmp_V4f); #endif - tmp_V2i = __builtin_ia32_cvttps2pi(tmp_V4f); - (void) __builtin_ia32_maskmovq(tmp_V8c, tmp_V8c, tmp_cp); tmp_i = __builtin_ia32_movmskps(tmp_V4f); - tmp_i = __builtin_ia32_pmovmskb(tmp_V8c); - (void) __builtin_ia32_movntq(tmp_V1LLip, tmp_V1LLi); (void) __builtin_ia32_sfence(); #ifndef OPENCL (void) _mm_sfence(); #endif - tmp_V4s = __builtin_ia32_psadbw(tmp_V8c, tmp_V8c); tmp_V4f = __builtin_ia32_rcpps(tmp_V4f); tmp_V4f = __builtin_ia32_rcpss(tmp_V4f); tmp_V4f = __builtin_ia32_rsqrtps(tmp_V4f); @@ -348,11 +293,8 @@ void f0(void) { tmp_V2d = __builtin_ia32_sqrtpd(tmp_V2d); tmp_V2d = __builtin_ia32_sqrtsd(tmp_V2d); tmp_V2LLi = __builtin_ia32_cvtpd2dq(tmp_V2d); - tmp_V2i = __builtin_ia32_cvtpd2pi(tmp_V2d); tmp_V4f = __builtin_ia32_cvtpd2ps(tmp_V2d); tmp_V4i = __builtin_ia32_cvttpd2dq(tmp_V2d); - tmp_V2i = __builtin_ia32_cvttpd2pi(tmp_V2d); - tmp_V2d = __builtin_ia32_cvtpi2pd(tmp_V2i); tmp_i = __builtin_ia32_cvtsd2si(tmp_V2d); tmp_i = __builtin_ia32_cvttsd2si(tmp_V2d); tmp_V4f = __builtin_ia32_cvtsd2ss(tmp_V4f, tmp_V2d); @@ -379,26 +321,9 @@ void f0(void) { (void) _mm_pause(); #endif - tmp_V4s = __builtin_ia32_psllwi(tmp_V4s, imm_i_0_8); - tmp_V2i = __builtin_ia32_pslldi(tmp_V2i, imm_i_0_8); - tmp_V1LLi = __builtin_ia32_psllqi(tmp_V1LLi, imm_i_0_8); - tmp_V4s = __builtin_ia32_psrawi(tmp_V4s, imm_i_0_8); - tmp_V2i = __builtin_ia32_psradi(tmp_V2i, imm_i_0_8); - tmp_V4s = __builtin_ia32_psrlwi(tmp_V4s, imm_i_0_8); - tmp_V2i = __builtin_ia32_psrldi(tmp_V2i, imm_i_0_8); - tmp_V1LLi = __builtin_ia32_psrlqi(tmp_V1LLi, imm_i_0_8); // Using non-immediate argument supported for gcc compatibility - tmp_V4s = __builtin_ia32_psllwi(tmp_V4s, tmp_i); - tmp_V2i = __builtin_ia32_pslldi(tmp_V2i, tmp_i); - tmp_V1LLi = __builtin_ia32_psllqi(tmp_V1LLi, tmp_i); - tmp_V4s = __builtin_ia32_psrawi(tmp_V4s, tmp_i); - tmp_V2i = __builtin_ia32_psradi(tmp_V2i, tmp_i); - tmp_V4s = __builtin_ia32_psrlwi(tmp_V4s, tmp_i); - tmp_V2i = __builtin_ia32_psrldi(tmp_V2i, tmp_i); - tmp_V1LLi = __builtin_ia32_psrlqi(tmp_V1LLi, tmp_i); - - tmp_V1LLi = __builtin_ia32_pmuludq(tmp_V2i, tmp_V2i); + tmp_V2LLi = __builtin_ia32_pmuludq128(tmp_V4i, tmp_V4i); tmp_V8s = __builtin_ia32_psraw128(tmp_V8s, tmp_V8s); tmp_V4i = __builtin_ia32_psrad128(tmp_V4i, tmp_V4i); @@ -433,7 +358,6 @@ void f0(void) { (void) __builtin_ia32_mwait(tmp_Ui, tmp_Ui); tmp_V16c = __builtin_ia32_lddqu(tmp_cCp); tmp_V16c = __builtin_ia32_palignr128(tmp_V16c, tmp_V16c, imm_i); - tmp_V8c = __builtin_ia32_palignr(tmp_V8c, tmp_V8c, imm_i); #ifdef USE_SSE4 tmp_V16c = __builtin_ia32_pblendvb128(tmp_V16c, tmp_V16c, tmp_V16c); tmp_V2d = __builtin_ia32_blendvpd(tmp_V2d, tmp_V2d, tmp_V2d); diff --git a/clang/test/CodeGen/constrained-math-builtins.c b/clang/test/CodeGen/constrained-math-builtins.c index 42c9e3c5008a3..aa77620b44535 100644 --- a/clang/test/CodeGen/constrained-math-builtins.c +++ b/clang/test/CodeGen/constrained-math-builtins.c @@ -36,6 +36,27 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c, _ // CHECK: call float @llvm.experimental.constrained.ldexp.f32.i32(float %{{.*}}, i32 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") // CHECK: call x86_fp80 @llvm.experimental.constrained.ldexp.f80.i32(x86_fp80 %{{.*}}, i32 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + __builtin_acos(f); __builtin_acosf(f); __builtin_acosl(f); __builtin_acosf128(f); + +// CHECK: call double @llvm.experimental.constrained.acos.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call float @llvm.experimental.constrained.acos.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call x86_fp80 @llvm.experimental.constrained.acos.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call fp128 @llvm.experimental.constrained.acos.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + +__builtin_asin(f); __builtin_asinf(f); __builtin_asinl(f); __builtin_asinf128(f); + +// CHECK: call double @llvm.experimental.constrained.asin.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call float @llvm.experimental.constrained.asin.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call x86_fp80 @llvm.experimental.constrained.asin.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call fp128 @llvm.experimental.constrained.asin.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + +__builtin_atan(f); __builtin_atanf(f); __builtin_atanl(f); __builtin_atanf128(f); + +// CHECK: call double @llvm.experimental.constrained.atan.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call float @llvm.experimental.constrained.atan.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call x86_fp80 @llvm.experimental.constrained.atan.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call fp128 @llvm.experimental.constrained.atan.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + __builtin_ceil(f); __builtin_ceilf(f); __builtin_ceill(f); __builtin_ceilf128(f); // CHECK: call double @llvm.experimental.constrained.ceil.f64(double %{{.*}}, metadata !"fpexcept.strict") @@ -50,6 +71,13 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c, _ // CHECK: call x86_fp80 @llvm.experimental.constrained.cos.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") // CHECK: call fp128 @llvm.experimental.constrained.cos.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + __builtin_cosh(f); __builtin_coshf(f); __builtin_coshl(f); __builtin_coshf128(f); + +// CHECK: call double @llvm.experimental.constrained.cosh.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call float @llvm.experimental.constrained.cosh.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call x86_fp80 @llvm.experimental.constrained.cosh.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call fp128 @llvm.experimental.constrained.cosh.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + __builtin_exp(f); __builtin_expf(f); __builtin_expl(f); __builtin_expf128(f); // CHECK: call double @llvm.experimental.constrained.exp.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") @@ -177,6 +205,13 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c, _ // CHECK: call x86_fp80 @llvm.experimental.constrained.sin.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") // CHECK: call fp128 @llvm.experimental.constrained.sin.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + __builtin_sinh(f); __builtin_sinhf(f); __builtin_sinhl(f); __builtin_sinhf128(f); + +// CHECK: call double @llvm.experimental.constrained.sinh.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call float @llvm.experimental.constrained.sinh.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call x86_fp80 @llvm.experimental.constrained.sinh.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call fp128 @llvm.experimental.constrained.sinh.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + __builtin_sqrt(f); __builtin_sqrtf(f); __builtin_sqrtl(f); __builtin_sqrtf128(f); // CHECK: call double @llvm.experimental.constrained.sqrt.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") @@ -191,6 +226,12 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c, _ // CHECK: call x86_fp80 @llvm.experimental.constrained.tan.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") // CHECK: call fp128 @llvm.experimental.constrained.tan.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + __builtin_tanh(f); __builtin_tanhf(f); __builtin_tanhl(f); __builtin_tanhf128(f); + +// CHECK: call double @llvm.experimental.constrained.tanh.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call float @llvm.experimental.constrained.tanh.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call x86_fp80 @llvm.experimental.constrained.tanh.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call fp128 @llvm.experimental.constrained.tanh.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") __builtin_trunc(f); __builtin_truncf(f); __builtin_truncl(f); __builtin_truncf128(f); diff --git a/clang/test/CodeGen/finite-math.c b/clang/test/CodeGen/finite-math.c index d1a2956b69feb..9cddba99ddf63 100644 --- a/clang/test/CodeGen/finite-math.c +++ b/clang/test/CodeGen/finite-math.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -ffinite-math-only -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=FINITE +// RUN: %clang_cc1 -menable-no-infs -menable-no-nans -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=FINITE // RUN: %clang_cc1 -fno-signed-zeros -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=NSZ // RUN: %clang_cc1 -freciprocal-math -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=RECIP // RUN: %clang_cc1 -mreassociate -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=REASSOC diff --git a/clang/test/CodeGen/fp-accuracy.c b/clang/test/CodeGen/fp-accuracy.c index c5a26849b4b3d..71606c95e620c 100644 --- a/clang/test/CodeGen/fp-accuracy.c +++ b/clang/test/CodeGen/fp-accuracy.c @@ -97,15 +97,15 @@ double rsqrt(double); // CHECK: call double @llvm.fpbuiltin.tanh.f64(double {{.*}}) #[[ATTR_HIGH]] // CHECK-F1-LABEL: define dso_local void @f1 -// CHECK-F1: call double @acos(double {{.*}}) +// CHECK-F1: call double @llvm.acos.f64(double {{.*}}) // CHECK-F1: call double @acosh(double {{.*}}) -// CHECK-F1: call double @asin(double {{.*}}) +// CHECK-F1: call double @llvm.asin.f64(double {{.*}}) // CHECK-F1: call double @asinh(double {{.*}}) -// CHECK-F1: call double @atan(double {{.*}}) +// CHECK-F1: call double @llvm.atan.f64(double {{.*}}) // CHECK-F1: call double @atan2(double {{.*}}, double {{.*}}) // CHECK-F1: call double @atanh(double {{.*}}) // CHECK-F1: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F1_HIGH:[0-9]+]] -// CHECK-F1: call double @cosh(double {{.*}}) +// CHECK-F1: call double @llvm.cosh.f64(double {{.*}}) // CHECK-F1: call double @erf(double {{.*}}) // CHECK-F1: call double @erfc(double {{.*}}) // CHECK-F1: call i32 (double, ...) @exp10(double {{.*}}) @@ -126,10 +126,10 @@ double rsqrt(double); // CHECK-F1: call i32 (double, ...) @rsqrt(double {{.*}}) // CHECK-F1: call double @llvm.sin.f64(double {{.*}}) // CHECK-F1: call void @llvm.fpbuiltin.sincos.f64(double {{.*}}, ptr {{.*}}, ptr {{.*}}) #[[ATTR_F1_MEDIUM]] -// CHECK-F1: call double @sinh(double {{.*}}) +// CHECK-F1: call double @llvm.sinh.f64(double {{.*}}) // CHECK-F1: call double @llvm.sqrt.f64(double {{.*}}) // CHECK-F1: call double @llvm.fpbuiltin.tan.f64(double {{.*}}) #[[ATTR_F1_LOW:[0-9]+]] -// CHECK-F1: call double @tanh(double {{.*}}) +// CHECK-F1: call double @llvm.tanh.f64(double {{.*}}) // // CHECK-F2-LABEL: define dso_local void @f1 // CHECK-F2: call double @llvm.fpbuiltin.acos.f64(double {{.*}}) #[[ATTR_F2_MEDIUM:[0-9]+]] @@ -259,15 +259,15 @@ double rsqrt(double); // CHECK-F4: call double @llvm.fpbuiltin.tanh.f64(double {{.*}}) #[[ATTR_F4_MEDIUM]] // // CHECK-F5-LABEL: define dso_local void @f1 -// CHECK-F5: call double @acos(double {{.*}}) +// CHECK-F5: call double @llvm.acos.f64(double {{.*}}) // CHECK-F5: call double @acosh(double {{.*}}) -// CHECK-F5: call double @asin(double {{.*}}) +// CHECK-F5: call double @llvm.asin.f64(double {{.*}}) // CHECK-F5: call double @asinh(double {{.*}}) -// CHECK-F5: call double @atan(double {{.*}}) +// CHECK-F5: call double @llvm.atan.f64(double {{.*}}) // CHECK-F5: call double @atan2(double {{.*}}, double {{.*}}) // CHECK-F5: call double @atanh(double {{.*}}) // CHECK-F5: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F5_MEDIUM:[0-9]+]] -// CHECK-F5: call double @cosh(double {{.*}}) +// CHECK-F5: call double @llvm.cosh.f64(double {{.*}}) // CHECK-F5: call double @erf(double {{.*}}) // CHECK-F5: call double @erfc(double {{.*}}) // CHECK-F5: call double @llvm.exp.f64(double {{.*}}) @@ -289,10 +289,10 @@ double rsqrt(double); // CHECK-F5: call i32 (double, ...) @rsqrt(double {{.*}}) // CHECK-F5: call double @llvm.fpbuiltin.sin.f64(double {{.*}}) #[[ATTR_F5_HIGH:[0-9]+]] // CHECK-F5: call i32 (double, ptr, ptr, ...) @sincos(double {{.*}}, ptr {{.*}}, ptr {{.*}}) -// CHECK-F5: call double @sinh(double {{.*}}) +// CHECK-F5: call double @llvm.sinh.f64(double {{.*}}) // CHECK-F5: call double @llvm.sqrt.f64(double {{.*}}) // CHECK-F5: call double @llvm.fpbuiltin.tan.f64(double {{.*}}) #[[ATTR_F5_HIGH]] -// CHECK-F5: call double @tanh(double {{.*}}) +// CHECK-F5: call double @llvm.tanh.f64(double {{.*}}) // // // CHECK-F6-LABEL: define dso_local void @f1 @@ -560,15 +560,15 @@ void f1(float a, float b) { // CHECK-SPIR: attributes #[[ATTR_SYCL8]] = {{.*}}"fpbuiltin-max-error"="2.0" // CHECK-DEFAULT-LABEL: define dso_local void @f1 -// CHECK-DEFAULT: call double @acos(double {{.*}}) +// CHECK-DEFAULT: call double @llvm.acos.f64(double {{.*}}) // CHECK-DEFAULT: call double @acosh(double {{.*}}) -// CHECK-DEFAULT: call double @asin(double {{.*}}) +// CHECK-DEFAULT: call double @llvm.asin.f64(double {{.*}}) // CHECK-DEFAULT: call double @asinh(double {{.*}}) -// CHECK-DEFAULT: call double @atan(double {{.*}}) +// CHECK-DEFAULT: call double @llvm.atan.f64(double {{.*}}) // CHECK-DEFAULT: call double @atan2(double {{.*}}, double {{.*}}) // CHECK-DEFAULT: call double @atanh(double {{.*}}) // CHECK-DEFAULT: call double @llvm.cos.f64(double {{.*}}) -// CHECK-DEFAULT: call double @cosh(double {{.*}}) +// CHECK-DEFAULT: call double @llvm.cosh.f64(double {{.*}}) // CHECK-DEFAULT: call double @erf(double {{.*}}) // CHECK-DEFAULT: call double @erfc(double {{.*}}) // CHECK-DEFAULT: call double @llvm.exp.f64(double {{.*}}) @@ -590,10 +590,10 @@ void f1(float a, float b) { // CHECK-DEFAULT: call i32 (double, ...) @rsqrt(double {{.*}}) // CHECK-DEFAULT: call double @llvm.sin.f64(double {{.*}}) // CHECK-DEFAULT: call i32 (double, ptr, ptr, ...) @sincos(double {{.*}}, ptr {{.*}}, ptr {{.*}}) -// CHECK-DEFAULT: call double @sinh(double {{.*}}) +// CHECK-DEFAULT: call double @llvm.sinh.f64(double {{.*}}) // CHECK-DEFAULT: call double @llvm.sqrt.f64(double {{.*}}) // CHECK-DEFAULT: call double @llvm.tan.f64(double {{.*}}) -// CHECK-DEFAULT: call double @tanh(double {{.*}}) +// CHECK-DEFAULT: call double @llvm.tanh.f64(double {{.*}}) // // CHECK-DEFAULT-LABEL: define dso_local void @f2 // CHECK-DEFAULT: call float @llvm.cos.f32(float {{.*}}) diff --git a/clang/test/CodeGen/fp-floatcontrol-stack.cpp b/clang/test/CodeGen/fp-floatcontrol-stack.cpp index 090da25d21207..237c9d4f9a37e 100644 --- a/clang/test/CodeGen/fp-floatcontrol-stack.cpp +++ b/clang/test/CodeGen/fp-floatcontrol-stack.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DDEFAULT=1 -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DDEFAULT %s // RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DEBSTRICT=1 -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DEBSTRICT %s // RUN: %clang_cc1 -triple x86_64-linux-gnu -DFAST=1 -ffast-math -ffp-contract=fast -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-FAST %s -// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DNOHONOR=1 -menable-no-infs -menable-no-nans -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-NOHONOR %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DNOHONOR=1 -ffinite-math-only -menable-no-infs -menable-no-nans -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-NOHONOR %s #define FUN(n) \ (float z) { return n * z + n; } diff --git a/clang/test/CodeGen/fp-options-to-fast-math-flags.c b/clang/test/CodeGen/fp-options-to-fast-math-flags.c index abdcf8541f225..6aa62266d9898 100644 --- a/clang/test/CodeGen/fp-options-to-fast-math-flags.c +++ b/clang/test/CodeGen/fp-options-to-fast-math-flags.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck -check-prefix CHECK-PRECISE %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -menable-no-nans -emit-llvm -o - %s | FileCheck -check-prefix CHECK-NO-NANS %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -menable-no-infs -emit-llvm -o - %s | FileCheck -check-prefix CHECK-NO-INFS %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ffinite-math-only -emit-llvm -o - %s | FileCheck -check-prefix CHECK-FINITE %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -menable-no-infs -menable-no-nans -emit-llvm -o - %s | FileCheck -check-prefix CHECK-FINITE %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fno-signed-zeros -emit-llvm -o - %s | FileCheck -check-prefix CHECK-NO-SIGNED-ZEROS %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -mreassociate -emit-llvm -o - %s | FileCheck -check-prefix CHECK-REASSOC %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -freciprocal-math -emit-llvm -o - %s | FileCheck -check-prefix CHECK-RECIP %s diff --git a/clang/test/CodeGen/inline-asm-size-zero.c b/clang/test/CodeGen/inline-asm-size-zero.c new file mode 100644 index 0000000000000..564f5207d1e71 --- /dev/null +++ b/clang/test/CodeGen/inline-asm-size-zero.c @@ -0,0 +1,6 @@ +// RUN: not %clang_cc1 -S %s -verify -o - + +void foo(void) { + extern long bar[]; + asm ("" : "=r"(bar)); // expected-error{{output size should not be zero}} +} diff --git a/clang/test/CodeGen/libcalls.c b/clang/test/CodeGen/libcalls.c index 645fa016f3f77..b1637121127c5 100644 --- a/clang/test/CodeGen/libcalls.c +++ b/clang/test/CodeGen/libcalls.c @@ -85,9 +85,9 @@ void test_builtins(double d, float f, long double ld) { double atan_ = atan(d); long double atanl_ = atanl(ld); float atanf_ = atanf(f); -// CHECK-NO: declare double @atan(double noundef) [[NUW_RN:#[0-9]+]] -// CHECK-NO: declare x86_fp80 @atanl(x86_fp80 noundef) [[NUW_RN]] -// CHECK-NO: declare float @atanf(float noundef) [[NUW_RN]] +// CHECK-NO: declare double @llvm.atan.f64(double) [[NUW_RNI:#[0-9]+]] +// CHECK-NO: declare x86_fp80 @llvm.atan.f80(x86_fp80) [[NUW_RNI]] +// CHECK-NO: declare float @llvm.atan.f32(float) [[NUW_RNI]] // CHECK-YES: declare double @atan(double noundef) [[NUW:#[0-9]+]] // CHECK-YES: declare x86_fp80 @atanl(x86_fp80 noundef) [[NUW]] // CHECK-YES: declare float @atanf(float noundef) [[NUW]] @@ -95,7 +95,7 @@ void test_builtins(double d, float f, long double ld) { double atan2_ = atan2(d, 2); long double atan2l_ = atan2l(ld, ld); float atan2f_ = atan2f(f, f); -// CHECK-NO: declare double @atan2(double noundef, double noundef) [[NUW_RN]] +// CHECK-NO: declare double @atan2(double noundef, double noundef) [[NUW_RN:#[0-9]+]] // CHECK-NO: declare x86_fp80 @atan2l(x86_fp80 noundef, x86_fp80 noundef) [[NUW_RN]] // CHECK-NO: declare float @atan2f(float noundef, float noundef) [[NUW_RN]] // CHECK-YES: declare double @atan2(double noundef, double noundef) [[NUW]] diff --git a/clang/test/CodeGen/math-libcalls-tbaa.c b/clang/test/CodeGen/math-libcalls-tbaa.c new file mode 100644 index 0000000000000..9c86eea67d14d --- /dev/null +++ b/clang/test/CodeGen/math-libcalls-tbaa.c @@ -0,0 +1,170 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 + +// RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,NONEWSTRUCTPATHTBAA +// RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -new-struct-path-tbaa -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,NEWSTRUCTPATHTBAA + +float expf(float); +double remainder(double, double); +double fabs(double); +double frexp(double, int *exp); +void sincos(float a, float *s, float *c); +float _Complex cacoshf(float _Complex); +float crealf(float _Complex); + +// Emit int TBAA metadata on FP math libcalls, which is useful for alias analysis + +// 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: [[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]] +// CHECK-NEXT: ret float [[MUL]] +// +float test_expf (float num[]) { + const float expm2 = expf(num[10]); // Emit TBAA metadata on @expf + float tmp = expm2 * num[10]; + return tmp; +} + +// 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: [[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]] +// CHECK-NEXT: ret float [[MUL]] +// +float test_builtin_expf (float num[]) { + const float expm2 = __builtin_expf(num[10]); // Emit TBAA metadata on @expf + float tmp = expm2 * num[10]; + return tmp; +} + +// +// Negative test: fabs cannot set errno +// 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: [[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]] +// CHECK-NEXT: ret double [[MUL]] +// +double test_fabs (double num[]) { + const double expm2 = fabs(num[10]); // Don't emit TBAA metadata + double tmp = expm2 * num[10]; + return tmp; +} + +// 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: [[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]] +// CHECK-NEXT: ret double [[MUL]] +// +double test_remainder (double num[], double a) { + const double expm2 = remainder(num[10], a); // Emit TBAA metadata + double tmp = expm2 * num[10]; + return tmp; +} + +// +// TODO: frexp is not subject to any errors, but also writes to +// its int pointer out argument, so it could emit int TBAA metadata. +// CHECK-LABEL: define dso_local double @test_frexp( +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] { +// 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: [[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]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[E]]) #[[ATTR9]] +// CHECK-NEXT: ret double [[MUL]] +// +double test_frexp (double num[]) { + int e; + double expm2 = frexp(num[2], &e); // Don't emit TBAA metadata + double tmp = expm2 * num[2]; + return tmp; +} + +// +// Negative test: sincos is a library function, but is not a builtin function +// checked in CodeGenFunction::EmitCallExpr. +// CHECK-LABEL: define dso_local float @test_sincos( +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[SIN:%.*]] = alloca float, align 4 +// 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: [[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]] +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[COS]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP1]], [[TMP2]] +// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[ADD:%.*]] = fadd float [[MUL]], [[TMP3]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[COS]]) #[[ATTR9]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[SIN]]) #[[ATTR9]] +// CHECK-NEXT: ret float [[ADD]] +// +float test_sincos (float num[]) { + float sin, cos; + sincos(num[2], &sin, &cos); // Don't emit TBAA metadata + float tmp = sin * cos + num[2]; + return tmp; +} + +// TODO: The builtin return a complex type +// 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: [[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 +// CHECK-NEXT: [[CALL:%.*]] = tail call { float, float } @cacoshf([2 x float] noundef alignstack(8) [[DOTFCA_1_INSERT]]) #[[ATTR9]] +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { float, float } [[CALL]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[ADD:%.*]] = fadd float [[TMP1]], [[TMP2]] +// CHECK-NEXT: ret float [[ADD]] +// +float test_cacoshf (float num[]) { + float _Complex z = cacoshf(num[2]); // Don't emit TBAA metadata + float tmp = crealf(z) + num[2]; + return tmp; +} + +//. +// NONEWSTRUCTPATHTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0} +// NONEWSTRUCTPATHTBAA: [[META3]] = !{!"float", [[META4:![0-9]+]], i64 0} +// NONEWSTRUCTPATHTBAA: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0} +// NONEWSTRUCTPATHTBAA: [[META5]] = !{!"Simple C/C++ TBAA"} +// NONEWSTRUCTPATHTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0} +// NONEWSTRUCTPATHTBAA: [[META7]] = !{!"int", [[META4]], i64 0} +// NONEWSTRUCTPATHTBAA: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0} +// NONEWSTRUCTPATHTBAA: [[META9]] = !{!"double", [[META4]], i64 0} +//. +// NEWSTRUCTPATHTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0, i64 4} +// NEWSTRUCTPATHTBAA: [[META3]] = !{[[META4:![0-9]+]], i64 4, !"float"} +// NEWSTRUCTPATHTBAA: [[META4]] = !{[[META5:![0-9]+]], i64 1, !"omnipotent char"} +// NEWSTRUCTPATHTBAA: [[META5]] = !{!"Simple C/C++ TBAA"} +// NEWSTRUCTPATHTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0, i64 4} +// NEWSTRUCTPATHTBAA: [[META7]] = !{[[META4]], i64 4, !"int"} +// NEWSTRUCTPATHTBAA: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0, i64 8} +// NEWSTRUCTPATHTBAA: [[META9]] = !{[[META4]], i64 8, !"double"} +//. +//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +// NEWSTRUCTPATHTBAA: {{.*}} +// NONEWSTRUCTPATHTBAA: {{.*}} diff --git a/clang/test/CodeGen/math-libcalls-tbaa.cpp b/clang/test/CodeGen/math-libcalls-tbaa.cpp deleted file mode 100644 index 0b231d474df77..0000000000000 --- a/clang/test/CodeGen/math-libcalls-tbaa.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 - -// RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefixes=CHECK,NoNewStructPathTBAA -// RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -new-struct-path-tbaa -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefixes=CHECK,NewStructPathTBAA - -extern "C" float expf(float); - -// Emit int TBAA metadata on FP math libcalls, which is useful for alias analysis - -// CHECK-LABEL: define dso_local float @foo( -// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]], float noundef [[R2INV:%.*]], i32 noundef [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds 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]]) #[[ATTR2:[0-9]+]] -// CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// CHECK-NEXT: [[MUL:%.*]] = fmul float [[CALL]], [[TMP1]] -// CHECK-NEXT: ret float [[MUL]] -// -extern "C" float foo (float num[], float r2inv, int n) { - const float expm2 = expf(num[10]); // Emit TBAA metadata on @expf - float tmp = expm2 * num[10]; - return tmp; -} -//. -// NoNewStructPathTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0} -// NoNewStructPathTBAA: [[META3]] = !{!"float", [[META4:![0-9]+]], i64 0} -// NoNewStructPathTBAA: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0} -// NoNewStructPathTBAA: [[META5]] = !{!"Simple C++ TBAA"} -//. -// NewStructPathTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0, i64 4} -// NewStructPathTBAA: [[META3]] = !{[[META4:![0-9]+]], i64 4, !"float"} -// NewStructPathTBAA: [[META4]] = !{[[META5:![0-9]+]], i64 1, !"omnipotent char"} -// NewStructPathTBAA: [[META5]] = !{!"Simple C++ TBAA"} -//. -//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -// NewStructPathTBAA: {{.*}} -// NoNewStructPathTBAA: {{.*}} diff --git a/clang/test/CodeGen/math-libcalls.c b/clang/test/CodeGen/math-libcalls.c index a249182692762..5b23a4a3faef3 100644 --- a/clang/test/CodeGen/math-libcalls.c +++ b/clang/test/CodeGen/math-libcalls.c @@ -121,15 +121,15 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { /* math */ acos(f); acosf(f); acosl(f); -// NO__ERRNO: declare double @acos(double noundef) [[READNONE]] -// NO__ERRNO: declare float @acosf(float noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @acosl(x86_fp80 noundef) [[READNONE]] +// NO__ERRNO: declare double @llvm.acos.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.acos.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.acos.f80(x86_fp80) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare double @acos(double noundef) [[NOT_READNONE]] // HAS_ERRNO: declare float @acosf(float noundef) [[NOT_READNONE]] // HAS_ERRNO: declare x86_fp80 @acosl(x86_fp80 noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare double @acos(double noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare float @acosf(float noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare x86_fp80 @acosl(x86_fp80 noundef) [[NOT_READNONE]] +// HAS_MAYTRAP: declare double @llvm.experimental.constrained.acos.f64( +// HAS_MAYTRAP: declare float @llvm.experimental.constrained.acos.f32( +// HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.acos.f80( acosh(f); acoshf(f); acoshl(f); @@ -146,15 +146,15 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { asin(f); asinf(f); asinl(f); -// NO__ERRNO: declare double @asin(double noundef) [[READNONE]] -// NO__ERRNO: declare float @asinf(float noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @asinl(x86_fp80 noundef) [[READNONE]] +// NO__ERRNO: declare double @llvm.asin.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.asin.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.asin.f80(x86_fp80) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare double @asin(double noundef) [[NOT_READNONE]] // HAS_ERRNO: declare float @asinf(float noundef) [[NOT_READNONE]] // HAS_ERRNO: declare x86_fp80 @asinl(x86_fp80 noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare double @asin(double noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare float @asinf(float noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare x86_fp80 @asinl(x86_fp80 noundef) [[NOT_READNONE]] +// HAS_MAYTRAP: declare double @llvm.experimental.constrained.asin.f64( +// HAS_MAYTRAP: declare float @llvm.experimental.constrained.asin.f32( +// HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.asin.f80( asinh(f); asinhf(f); asinhl(f); @@ -170,15 +170,15 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { atan(f); atanf(f); atanl(f); -// NO__ERRNO: declare double @atan(double noundef) [[READNONE]] -// NO__ERRNO: declare float @atanf(float noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @atanl(x86_fp80 noundef) [[READNONE]] +// NO__ERRNO: declare double @llvm.atan.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.atan.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.atan.f80(x86_fp80) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare double @atan(double noundef) [[NOT_READNONE]] // HAS_ERRNO: declare float @atanf(float noundef) [[NOT_READNONE]] // HAS_ERRNO: declare x86_fp80 @atanl(x86_fp80 noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare double @atan(double noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare float @atanf(float noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare x86_fp80 @atanl(x86_fp80 noundef) [[NOT_READNONE]] +// HAS_MAYTRAP: declare double @llvm.experimental.constrained.atan.f64( +// HAS_MAYTRAP: declare float @llvm.experimental.constrained.atan.f32( +// HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.atan.f80( atanh(f); atanhf(f); atanhl(f); @@ -230,15 +230,15 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { cosh(f); coshf(f); coshl(f); -// NO__ERRNO: declare double @cosh(double noundef) [[READNONE]] -// NO__ERRNO: declare float @coshf(float noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @coshl(x86_fp80 noundef) [[READNONE]] +// NO__ERRNO: declare double @llvm.cosh.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.cosh.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.cosh.f80(x86_fp80) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare double @cosh(double noundef) [[NOT_READNONE]] // HAS_ERRNO: declare float @coshf(float noundef) [[NOT_READNONE]] // HAS_ERRNO: declare x86_fp80 @coshl(x86_fp80 noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare double @cosh(double noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare float @coshf(float noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare x86_fp80 @coshl(x86_fp80 noundef) [[NOT_READNONE]] +// HAS_MAYTRAP: declare double @llvm.experimental.constrained.cosh.f64( +// HAS_MAYTRAP: declare float @llvm.experimental.constrained.cosh.f32( +// HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.cosh.f80( erf(f); erff(f); erfl(f); @@ -638,15 +638,16 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { sinh(f); sinhf(f); sinhl(f); -// NO__ERRNO: declare double @sinh(double noundef) [[READNONE]] -// NO__ERRNO: declare float @sinhf(float noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @sinhl(x86_fp80 noundef) [[READNONE]] +// NO__ERRNO: declare double @llvm.sinh.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.sinh.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.sinh.f80(x86_fp80) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare double @sinh(double noundef) [[NOT_READNONE]] // HAS_ERRNO: declare float @sinhf(float noundef) [[NOT_READNONE]] // HAS_ERRNO: declare x86_fp80 @sinhl(x86_fp80 noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare double @sinh(double noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare float @sinhf(float noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare x86_fp80 @sinhl(x86_fp80 noundef) [[NOT_READNONE]] +// HAS_MAYTRAP: declare double @llvm.experimental.constrained.sinh.f64( +// HAS_MAYTRAP: declare float @llvm.experimental.constrained.sinh.f32( +// HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.sinh.f80( + sqrt(f); sqrtf(f); sqrtl(f); @@ -674,15 +675,15 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { tanh(f); tanhf(f); tanhl(f); -// NO__ERRNO: declare double @tanh(double noundef) [[READNONE]] -// NO__ERRNO: declare float @tanhf(float noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @tanhl(x86_fp80 noundef) [[READNONE]] +// NO__ERRNO: declare double @llvm.tanh.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.tanh.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.tanh.f80(x86_fp80) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare double @tanh(double noundef) [[NOT_READNONE]] // HAS_ERRNO: declare float @tanhf(float noundef) [[NOT_READNONE]] // HAS_ERRNO: declare x86_fp80 @tanhl(x86_fp80 noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare double @tanh(double noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare float @tanhf(float noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare x86_fp80 @tanhl(x86_fp80 noundef) [[NOT_READNONE]] +// HAS_MAYTRAP: declare double @llvm.experimental.constrained.tanh.f64( +// HAS_MAYTRAP: declare float @llvm.experimental.constrained.tanh.f32( +// HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.tanh.f80( tgamma(f); tgammaf(f); tgammal(f); diff --git a/clang/test/CodeGen/ms_mangler_templatearg_opte.cpp b/clang/test/CodeGen/ms_mangler_templatearg_opte.cpp new file mode 100644 index 0000000000000..b17d97bb04cad --- /dev/null +++ b/clang/test/CodeGen/ms_mangler_templatearg_opte.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -emit-llvm -std=c++20 -x c++ < %s | FileCheck -check-prefix=WIN64 %s + +struct A { + const int* ptr; +}; + +template void tfn() {}; + +// WIN64: ??$tfn@$2UA@@PEBH5CE?ints@@3QBHB06@@@@@YAXXZ +constexpr int ints[] = { 1, 2, 7, 8, 9, -17, -10 }; + +// WIN64: ??$tfn@$2UA@@PEBH5E?one_int@@3HB@@@@YAXXZ +constexpr int one_int = 7; + +void template_instance() { + tfn(); + tfn(); +} + diff --git a/clang/test/CodeGen/nofpclass.c b/clang/test/CodeGen/nofpclass.c index fc4c64f9b921b..23470914d0ab4 100644 --- a/clang/test/CodeGen/nofpclass.c +++ b/clang/test/CodeGen/nofpclass.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes --version 2 // REQUIRES: x86-registered-target -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -ffinite-math-only -emit-llvm -o - %s | FileCheck -check-prefixes=CFINITEONLY %s -// RUN: %clang_cc1 -x cl -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -cl-finite-math-only -emit-llvm -o - %s | FileCheck -check-prefixes=CLFINITEONLY %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -menable-no-infs -menable-no-nans -emit-llvm -o - %s | FileCheck -check-prefixes=CFINITEONLY %s +// RUN: %clang_cc1 -x cl -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -menable-no-nans -menable-no-infs -emit-llvm -o - %s | FileCheck -check-prefixes=CLFINITEONLY %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -menable-no-nans -emit-llvm -o - %s | FileCheck -check-prefixes=NONANS %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -menable-no-infs -emit-llvm -o - %s | FileCheck -check-prefixes=NOINFS %s diff --git a/clang/test/CodeGen/palignr.c b/clang/test/CodeGen/palignr.c index 5a77597c34031..092937ac115de 100644 --- a/clang/test/CodeGen/palignr.c +++ b/clang/test/CodeGen/palignr.c @@ -14,18 +14,3 @@ int4 align2(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 16); } int4 align3(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 17); } // CHECK: xor int4 align4(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 32); } - -#define _mm_alignr_pi8(a, b, n) (__builtin_ia32_palignr((a), (b), (n))) -typedef __attribute__((vector_size(8))) int int2; - -// CHECK: palignr -int2 align5(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 8); } - -// CHECK: palignr -int2 align6(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 9); } - -// CHECK: palignr -int2 align7(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 16); } - -// CHECK: palignr -int2 align8(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 7); } diff --git a/clang/test/CodeGen/pr26099.c b/clang/test/CodeGen/pr26099.c deleted file mode 100644 index 15b73b832e9d8..0000000000000 --- a/clang/test/CodeGen/pr26099.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %clang_cc1 -ffreestanding %s -triple=i686-apple-darwin -target-feature +mmx -emit-llvm -o - -Wall -Werror -// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +mmx -emit-llvm -o - -Wall -Werror -// REQUIRES: asserts - -#include - -int __attribute__ ((__vector_size__ (8))) b; - -void bar(int a) -{ - b = __builtin_ia32_vec_init_v2si (0, a); -} \ No newline at end of file diff --git a/clang/test/CodeGen/pr3518.c b/clang/test/CodeGen/pr3518.c index f888add986258..a3cd866e92201 100644 --- a/clang/test/CodeGen/pr3518.c +++ b/clang/test/CodeGen/pr3518.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -fexperimental-new-constant-interpreter -emit-llvm -o - | FileCheck %s // PR 3518 // Some of the objects were coming out as uninitialized (external) before 3518 // was fixed. Internal names are different between llvm-gcc and clang so they diff --git a/clang/test/CodeGen/ptrauth-function-attributes.c b/clang/test/CodeGen/ptrauth-function-attributes.c index 7ec30498b9d35..6a09cd37bf485 100644 --- a/clang/test/CodeGen/ptrauth-function-attributes.c +++ b/clang/test/CodeGen/ptrauth-function-attributes.c @@ -4,10 +4,16 @@ // RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,CALLS // RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,CALLS +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-indirect-gotos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,GOTOS +// RUN: %clang_cc1 -triple arm64e-apple-ios -fptrauth-indirect-gotos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,GOTOS +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-indirect-gotos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,GOTOS + // ALL: define {{(dso_local )?}}void @test() #0 void test() { } // CALLS: attributes #0 = {{{.*}} "ptrauth-calls" {{.*}}} +// GOTOS: attributes #0 = {{{.*}} "ptrauth-indirect-gotos" {{.*}}} + // OFF-NOT: attributes {{.*}} "ptrauth- diff --git a/clang/test/CodeGen/ptrauth-function-lvalue-cast-disc.c b/clang/test/CodeGen/ptrauth-function-lvalue-cast-disc.c new file mode 100644 index 0000000000000..40bba99478192 --- /dev/null +++ b/clang/test/CodeGen/ptrauth-function-lvalue-cast-disc.c @@ -0,0 +1,70 @@ +// RUN: %clang_cc1 %s -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics -emit-llvm -o- -fptrauth-function-pointer-type-discrimination | FileCheck -check-prefixes CHECK,TYPE %s +// RUN: %clang_cc1 %s -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -o- -fptrauth-function-pointer-type-discrimination | FileCheck -check-prefixes CHECK,TYPE %s +// RUN: %clang_cc1 %s -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics -emit-llvm -o- | FileCheck -check-prefixes CHECK,ZERO %s +// RUN: %clang_cc1 %s -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -o- | FileCheck -check-prefixes CHECK,ZERO %s + +typedef void (*fptr_t)(void); + +char *cptr; +void (*fptr)(void); + +// CHECK-LABEL: define{{.*}} void @test1 +void test1() { + // TYPE: [[LOAD:%.*]] = load ptr, ptr @cptr + // TYPE: [[TOINT:%.*]] = ptrtoint ptr [[LOAD]] to i64 + // TYPE: call i64 @llvm.ptrauth.resign(i64 [[TOINT]], i32 0, i64 0, i32 0, i64 18983) + // TYPE: call void {{.*}}() [ "ptrauth"(i32 0, i64 18983) ] + // ZERO-NOT: @llvm.ptrauth.resign + + (*(fptr_t)cptr)(); +} + +// CHECK-LABEL: define{{.*}} i8 @test2 +char test2() { + return *(char *)fptr; + + // TYPE: [[LOAD:%.*]] = load ptr, ptr @fptr + // TYPE: [[CMP:%.*]] = icmp ne ptr [[LOAD]], null + // TYPE-NEXT: br i1 [[CMP]], label %[[NONNULL:.*]], label %[[CONT:.*]] + + // TYPE: [[NONNULL]]: + // TYPE: [[TOINT:%.*]] = ptrtoint ptr [[LOAD]] to i64 + // TYPE: [[CALL:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[TOINT]], i32 0, i64 18983, i32 0, i64 0) + // TYPE: [[TOPTR:%.*]] = inttoptr i64 [[CALL]] to ptr + + // TYPE: [[CONT]]: + // TYPE: phi ptr [ null, {{.*}} ], [ [[TOPTR]], %[[NONNULL]] ] + // ZERO-NOT: @llvm.ptrauth.resign +} + +// CHECK-LABEL: define{{.*}} void @test4 +void test4() { + (*((fptr_t)(&*((char *)(&*(fptr_t)cptr)))))(); + + // CHECK: [[LOAD:%.*]] = load ptr, ptr @cptr + // TYPE-NEXT: [[CAST4:%.*]] = ptrtoint ptr [[LOAD]] to i64 + // TYPE-NEXT: [[RESIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[CAST4]], i32 0, i64 0, i32 0, i64 18983) + // TYPE-NEXT: [[CAST5:%.*]] = inttoptr i64 [[RESIGN]] to ptr + // TYPE-NEXT: call void [[CAST5]]() [ "ptrauth"(i32 0, i64 18983) ] + // ZERO-NOT: @llvm.ptrauth.resign + // ZERO: call void [[LOAD]]() [ "ptrauth"(i32 0, i64 0) ] +} + +void *vptr; +// CHECK-LABEL: define{{.*}} void @test5 +void test5() { + vptr = &*(char *)fptr; + + // TYPE: [[LOAD:%.*]] = load ptr, ptr @fptr + // TYPE-NEXT: [[CMP]] = icmp ne ptr [[LOAD]], null + // TYPE-NEXT: br i1 [[CMP]], label %[[NONNULL:.*]], label %[[CONT:.*]] + + // TYPE: [[NONNULL]]: + // TYPE: [[RESIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 {{.*}}, i32 0, i64 18983, i32 0, i64 0) + // TYPE: [[CAST:%.*]] = inttoptr i64 [[RESIGN]] to ptr + + // TYPE: [[CONT]]: + // TYPE: [[PHI:%.*]] = phi ptr [ null, {{.*}} ], [ [[CAST]], %[[NONNULL]] ] + // TYPE: store ptr [[PHI]], ptr @vptr + // ZERO-NOT: @llvm.ptrauth.resign +} diff --git a/clang/test/CodeGen/ptrauth-function-type-discriminator-cast.c b/clang/test/CodeGen/ptrauth-function-type-discriminator-cast.c new file mode 100644 index 0000000000000..1a1dce6f4a66e --- /dev/null +++ b/clang/test/CodeGen/ptrauth-function-type-discriminator-cast.c @@ -0,0 +1,108 @@ +// RUN: %clang_cc1 %s -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -disable-llvm-passes -emit-llvm -o- | FileCheck %s --check-prefixes=CHECK,TYPE + +// RUN: %clang_cc1 %s -fptrauth-function-pointer-type-discrimination -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -disable-llvm-passes -emit-llvm -o- | FileCheck %s --check-prefixes=CHECK,TYPE + +// RUN: %clang_cc1 %s -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -disable-llvm-passes -emit-llvm -o- | FileCheck %s --check-prefixes=CHECK,ZERO + +// RUN: %clang_cc1 %s -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -disable-llvm-passes -emit-llvm -o- | FileCheck %s --check-prefixes=CHECK,ZERO + +// RUN: %clang_cc1 %s -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -disable-llvm-passes -emit-llvm -xc++ -o- | FileCheck %s --check-prefixes=CHECK,CHECKCXX,TYPE,TYPECXX + +// RUN: %clang_cc1 %s -fptrauth-function-pointer-type-discrimination -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -disable-llvm-passes -emit-llvm -xc++ -o- | FileCheck %s --check-prefixes=CHECK,CHECKCXX,TYPE,TYPECXX + +#ifdef __cplusplus +extern "C" { +#endif + +void f(void); +void f2(int); +void (*fptr)(void); +void *opaque; +unsigned long uintptr; + +#ifdef __cplusplus +struct ptr_member { + void (*fptr_)(int) = 0; +}; +ptr_member pm; +void (*test_member)() = (void (*)())pm.fptr_; + +// CHECKCXX-LABEL: define{{.*}} internal void @__cxx_global_var_init +// TYPECXX: call i64 @llvm.ptrauth.resign(i64 {{.*}}, i32 0, i64 2712, i32 0, i64 18983) +#endif + + +// CHECK-LABEL: define{{.*}} void @test_cast_to_opaque +void test_cast_to_opaque() { + opaque = (void *)f; + + // TYPE: [[RESIGN_VAL:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @f, i32 0, i64 18983) to i64), i32 0, i64 18983, i32 0, i64 0) + // TYPE: [[RESIGN_PTR:%.*]] = inttoptr i64 [[RESIGN_VAL]] to ptr + // ZERO-NOT: @llvm.ptrauth.resign +} + +// CHECK-LABEL: define{{.*}} void @test_cast_from_opaque +void test_cast_from_opaque() { + fptr = (void (*)(void))opaque; + + // TYPE: [[LOAD:%.*]] = load ptr, ptr @opaque + // TYPE: [[CMP:%.*]] = icmp ne ptr [[LOAD]], null + // TYPE: br i1 [[CMP]], label %[[RESIGN_LAB:.*]], label + + // TYPE: [[RESIGN_LAB]]: + // TYPE: [[INT:%.*]] = ptrtoint ptr [[LOAD]] to i64 + // TYPE: [[RESIGN_INT:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[INT]], i32 0, i64 0, i32 0, i64 18983) + + // ZERO-NOT: @llvm.ptrauth.resign +} + +// CHECK-LABEL: define{{.*}} void @test_cast_to_intptr +void test_cast_to_intptr() { + uintptr = (unsigned long)fptr; + + // TYPE: [[ENTRY:.*]]: + // TYPE: [[LOAD:%.*]] = load ptr, ptr @fptr + // TYPE: [[CMP:%.*]] = icmp ne ptr [[LOAD]], null + // TYPE: br i1 [[CMP]], label %[[RESIGN_LAB:.*]], label %[[RESIGN_CONT:.*]] + + // TYPE: [[RESIGN_LAB]]: + // TYPE: [[INT:%.*]] = ptrtoint ptr [[LOAD]] to i64 + // TYPE: [[RESIGN_INT:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[INT]], i32 0, i64 18983, i32 0, i64 0) + // TYPE: [[RESIGN:%.*]] = inttoptr i64 [[RESIGN_INT]] to ptr + // TYPE: br label %[[RESIGN_CONT]] + + // TYPE: [[RESIGN_CONT]]: + // TYPE: phi ptr [ null, %[[ENTRY]] ], [ [[RESIGN]], %[[RESIGN_LAB]] ] + + // ZERO-NOT: @llvm.ptrauth.resign +} + +// CHECK-LABEL: define{{.*}} void @test_function_to_function_cast +void test_function_to_function_cast() { + void (*fptr2)(int) = (void (*)(int))fptr; + // TYPE: call i64 @llvm.ptrauth.resign(i64 {{.*}}, i32 0, i64 18983, i32 0, i64 2712) + // ZERO-NOT: @llvm.ptrauth.resign +} + +// CHECK-LABEL: define{{.*}} void @test_call_lvalue_cast +void test_call_lvalue_cast() { + (*(void (*)(int))f)(42); + + // TYPE: entry: + // TYPE-NEXT: [[RESIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @f, i32 0, i64 18983) to i64), i32 0, i64 18983, i32 0, i64 2712) + // TYPE-NEXT: [[RESIGN_INT:%.*]] = inttoptr i64 [[RESIGN]] to ptr + // TYPE-NEXT: call void [[RESIGN_INT]](i32 noundef 42) [ "ptrauth"(i32 0, i64 2712) ] + // ZERO-NOT: @llvm.ptrauth.resign + // ZERO: call void ptrauth (ptr @f, i32 0)(i32 noundef 42) [ "ptrauth"(i32 0, i64 0) ] +} + + +#ifdef __cplusplus +} +#endif diff --git a/clang/test/CodeGen/ptrauth-function-type-discriminator.c b/clang/test/CodeGen/ptrauth-function-type-discriminator.c index 5dea48fe5915b..0952c1abf6c07 100644 --- a/clang/test/CodeGen/ptrauth-function-type-discriminator.c +++ b/clang/test/CodeGen/ptrauth-function-type-discriminator.c @@ -1,7 +1,18 @@ -// RUN: %clang_cc1 %s -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics -disable-llvm-passes -emit-llvm -o- | FileCheck %s --check-prefix=CHECK --check-prefix=CHECKC -// RUN: %clang_cc1 -xc++ %s -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics -disable-llvm-passes -emit-llvm -o- | FileCheck %s --check-prefix=CHECK -// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-pch %s -o %t.ast -// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -x ast -o - %t.ast | FileCheck -check-prefix=CHECK --check-prefix=CHECKC %s +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -disable-llvm-passes -emit-llvm %s -o- | FileCheck --check-prefixes=CHECK,CHECKC %s +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -disable-llvm-passes -emit-llvm -xc++ %s -o- | FileCheck --check-prefix=CHECK %s +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-pch %s -o %t.ast +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -emit-llvm -x ast -o - %t.ast | FileCheck --check-prefixes=CHECK,CHECKC %s + +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -disable-llvm-passes -emit-llvm %s -o- | FileCheck --check-prefixes=CHECK,CHECKC %s +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -disable-llvm-passes -emit-llvm -xc++ %s -o- | FileCheck --check-prefix=CHECK %s +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-pch %s -o %t.ast +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -emit-llvm -x ast -o - %t.ast | FileCheck --check-prefixes=CHECK,CHECKC %s #ifdef __cplusplus extern "C" { @@ -19,6 +30,13 @@ void (*test_constant_null)(int) = 0; // CHECK: @test_constant_cast = global ptr ptrauth (ptr @f, i32 0, i64 2712) void (*test_constant_cast)(int) = (void (*)(int))f; +#ifndef __cplusplus +// CHECKC: @enum_func_ptr = global ptr ptrauth (ptr @enum_func, i32 0, i64 2712) +enum Enum0; +void enum_func(enum Enum0); +void (*enum_func_ptr)(enum Enum0) = enum_func; +#endif + // CHECK: @test_opaque = global ptr ptrauth (ptr @f, i32 0) void *test_opaque = #ifdef __cplusplus @@ -47,14 +65,14 @@ void (*fptr3)(void) = __builtin_ptrauth_sign_constant(&external_function, 2, 26) // CHECK: @fptr4 = global ptr ptrauth (ptr @external_function, i32 2, i64 26, ptr @fptr4) void (*fptr4)(void) = __builtin_ptrauth_sign_constant(&external_function, 2, __builtin_ptrauth_blend_discriminator(&fptr4, 26)); -// CHECK-LABEL: define void @test_call() +// CHECK-LABEL: define{{.*}} void @test_call() void test_call() { // CHECK: [[T0:%.*]] = load ptr, ptr @fnptr, // CHECK-NEXT: call void [[T0]]() [ "ptrauth"(i32 0, i64 18983) ] fnptr(); } -// CHECK-LABEL: define ptr @test_function_pointer() +// CHECK-LABEL: define{{.*}} ptr @test_function_pointer() // CHECK: ret ptr ptrauth (ptr @external_function, i32 0, i64 18983) void (*test_function_pointer())(void) { return external_function; @@ -62,14 +80,14 @@ void (*test_function_pointer())(void) { struct InitiallyIncomplete; extern struct InitiallyIncomplete returns_initially_incomplete(void); -// CHECK-LABEL: define void @use_while_incomplete() +// CHECK-LABEL: define{{.*}} void @use_while_incomplete() void use_while_incomplete() { // CHECK: [[VAR:%.*]] = alloca ptr, // CHECK-NEXT: store ptr ptrauth (ptr @returns_initially_incomplete, i32 0, i64 25106), ptr [[VAR]] struct InitiallyIncomplete (*fnptr)(void) = &returns_initially_incomplete; } struct InitiallyIncomplete { int x; }; -// CHECK-LABEL: define void @use_while_complete() +// CHECK-LABEL: define{{.*}} void @use_while_complete() void use_while_complete() { // CHECK: [[VAR:%.*]] = alloca ptr, // CHECK-NEXT: store ptr ptrauth (ptr @returns_initially_incomplete, i32 0, i64 25106), ptr [[VAR]] @@ -83,7 +101,7 @@ void knr(param) int param; {} -// CHECKC-LABEL: define void @test_knr +// CHECKC-LABEL: define{{.*}} void @test_knr void test_knr() { void (*p)() = knr; p(0); @@ -94,7 +112,7 @@ void test_knr() { // CHECKC: call void [[LOAD]](i32 noundef 0) [ "ptrauth"(i32 0, i64 18983) ] } -// CHECKC-LABEL: define void @test_redeclaration +// CHECKC-LABEL: define{{.*}} void @test_redeclaration void test_redeclaration() { void redecl(); void (*ptr)() = redecl; @@ -113,7 +131,7 @@ void knr2(param) int param; {} -// CHECKC-LABEL: define void @test_redecl_knr +// CHECKC-LABEL: define{{.*}} void @test_redecl_knr void test_redecl_knr() { void (*p)() = knr2; p(); diff --git a/clang/test/CodeGen/ptrauth-ubsan-vptr.cpp b/clang/test/CodeGen/ptrauth-ubsan-vptr.cpp index 6c36004641477..8045e7bdc7460 100644 --- a/clang/test/CodeGen/ptrauth-ubsan-vptr.cpp +++ b/clang/test/CodeGen/ptrauth-ubsan-vptr.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -triple arm64e-apple-ios15 -fsanitize=vptr -O0 -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple arm64e-apple-ios15 -fsanitize=vptr -O2 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fsanitize=vptr -O0 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fsanitize=vptr -O2 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s + struct S { S() {} ~S() {} diff --git a/clang/test/CodeGen/sanitize-metadata-nosanitize.c b/clang/test/CodeGen/sanitize-metadata-nosanitize.c index 388a3df547a73..da0c809148018 100644 --- a/clang/test/CodeGen/sanitize-metadata-nosanitize.c +++ b/clang/test/CodeGen/sanitize-metadata-nosanitize.c @@ -12,7 +12,7 @@ //. // CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) // CHECK-LABEL: define dso_local void @escape -// CHECK-SAME: (ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !pcsections !2 { +// CHECK-SAME: (ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !pcsections [[META2:![0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret void // @@ -23,13 +23,13 @@ __attribute__((noinline, not_tail_called)) void escape(const volatile void *p) { // CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) // CHECK-LABEL: define dso_local i32 @normal_function -// CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !pcsections !4 { +// CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !pcsections [[META4:![0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[X_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8, !tbaa [[TBAA6:![0-9]+]] -// CHECK-NEXT: store atomic i32 1, ptr [[X]] monotonic, align 4, !pcsections !10 +// CHECK-NEXT: store atomic i32 1, ptr [[X]] monotonic, align 4, !pcsections [[META11:![0-9]+]] // CHECK-NEXT: notail call void @escape(ptr noundef nonnull [[X_ADDR]]) -// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA11:![0-9]+]] +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA12:![0-9]+]] // CHECK-NEXT: ret i32 [[TMP0]] // int normal_function(int *x, int *y) { @@ -46,7 +46,7 @@ int normal_function(int *x, int *y) { // CHECK-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8, !tbaa [[TBAA6]] // CHECK-NEXT: store atomic i32 1, ptr [[X]] monotonic, align 4 // CHECK-NEXT: notail call void @escape(ptr noundef nonnull [[X_ADDR]]) -// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA11]] +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA12]] // CHECK-NEXT: ret i32 [[TMP0]] // __attribute__((disable_sanitizer_instrumentation)) int test_disable_sanitize_instrumentation(int *x, int *y) { @@ -57,13 +57,13 @@ __attribute__((disable_sanitizer_instrumentation)) int test_disable_sanitize_ins // CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) // CHECK-LABEL: define dso_local i32 @test_no_sanitize_thread -// CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] !pcsections !13 { +// CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] !pcsections [[META14:![0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[X_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8, !tbaa [[TBAA6]] -// CHECK-NEXT: store atomic i32 1, ptr [[X]] monotonic, align 4, !pcsections !10 +// CHECK-NEXT: store atomic i32 1, ptr [[X]] monotonic, align 4, !pcsections [[META11]] // CHECK-NEXT: notail call void @escape(ptr noundef nonnull [[X_ADDR]]) -// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA11]] +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA12]] // CHECK-NEXT: ret i32 [[TMP0]] // __attribute__((no_sanitize("thread"))) int test_no_sanitize_thread(int *x, int *y) { @@ -74,13 +74,13 @@ __attribute__((no_sanitize("thread"))) int test_no_sanitize_thread(int *x, int * // CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) // CHECK-LABEL: define dso_local i32 @test_no_sanitize_all -// CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR3]] !pcsections !13 { +// CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR3]] !pcsections [[META14]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[X_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8, !tbaa [[TBAA6]] -// CHECK-NEXT: store atomic i32 1, ptr [[X]] monotonic, align 4, !pcsections !10 +// CHECK-NEXT: store atomic i32 1, ptr [[X]] monotonic, align 4, !pcsections [[META11]] // CHECK-NEXT: notail call void @escape(ptr noundef nonnull [[X_ADDR]]) -// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA11]] +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA12]] // CHECK-NEXT: ret i32 [[TMP0]] // __attribute__((no_sanitize("all"))) int test_no_sanitize_all(int *x, int *y) { @@ -89,23 +89,9 @@ __attribute__((no_sanitize("all"))) int test_no_sanitize_all(int *x, int *y) { return *y; } //. -// CHECK: attributes #0 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } -// CHECK: attributes #1 = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } -// CHECK: attributes #2 = { disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } -// CHECK: attributes #3 = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "no_sanitize_thread" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } -// CHECK: attributes #4 = { nounwind "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } -//. -// CHECK: !2 = !{!"sanmd_covered2!C", !3} -// CHECK: !3 = !{i64 0} -// CHECK: !4 = !{!"sanmd_covered2!C", !5} -// CHECK: !5 = !{i64 3} -// CHECK: !6 = !{!7, !7, i64 0} -// CHECK: !7 = !{!"any pointer", !8, i64 0} -// CHECK: !8 = !{!"omnipotent char", !9, i64 0} -// CHECK: !9 = !{!"Simple C/C++ TBAA"} -// CHECK: !10 = !{!"sanmd_atomics2!C"} -// CHECK: !11 = !{!12, !12, i64 0} -// CHECK: !12 = !{!"int", !8, i64 0} -// CHECK: !13 = !{!"sanmd_covered2!C", !14} -// CHECK: !14 = !{i64 2} +// CHECK: attributes #[[ATTR0]] = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } +// CHECK: attributes #[[ATTR1]] = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } +// CHECK: attributes #[[ATTR2]] = { disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } +// CHECK: attributes #[[ATTR3]] = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "no_sanitize_thread" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } +// CHECK: attributes #[[ATTR4:[0-9]+]] = { nounwind "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } //. diff --git a/clang/test/CodeGen/tbaa-pointers.c b/clang/test/CodeGen/tbaa-pointers.c index b9ebe87982001..75d8c3d501750 100644 --- a/clang/test/CodeGen/tbaa-pointers.c +++ b/clang/test/CodeGen/tbaa-pointers.c @@ -1,80 +1,108 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck --check-prefixes=COMMON,DEFAULT %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes -pointer-tbaa %s -emit-llvm -o - | FileCheck --check-prefixes=COMMON,ENABLED %s +// RUN: %clang --target=x86_64-apple-darwin -O1 %s -emit-llvm -S -mllvm -disable-llvm-optzns -o - | FileCheck --check-prefixes=COMMON,DEFAULT %s +// RUN: %clang --target=x86_64-apple-darwin -O1 -fpointer-tbaa %s -emit-llvm -S -mllvm -disable-llvm-optzns -o - | FileCheck --check-prefixes=COMMON,ENABLED %s void p2unsigned(unsigned **ptr) { - // CHECK-LABEL: define void @p2unsigned(ptr noundef %ptr) - // CHECK-NEXT: entry: - // CHECK-NEXT: %ptr.addr = alloca ptr, align 8 - // CHECK-NEXT: store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0:!.+]] - // CHECK-NEXT: [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: ret void + // COMMON-LABEL: define void @p2unsigned( + // COMMON-SAME: ptr noundef [[PTR:%.+]]) + // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8 + // ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P2INT_0:!.+]] + // ENABLED-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P2INT_0]] + // ENABLED-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[P1INT_0:!.+]] + // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR:!.+]] + // DEFAULT-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[ANYPTR]] + // COMMON-NEXT: ret void // *ptr = 0; } void p2unsigned_volatile(unsigned *volatile *ptr) { - // CHECK-LABEL: define void @p2unsigned_volatile(ptr noundef %ptr) - // CHECK-NEXT: entry: - // CHECK-NEXT: %ptr.addr = alloca ptr, align 8 - // CHECK-NEXT: store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: store volatile ptr null, ptr [[BASE]], align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: ret void + // COMMON-LABEL: define void @p2unsigned_volatile( + // COMMON-SAME: ptr noundef [[PTR:%.+]]) + // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8 + // ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P2INT_0]] + // ENABLED-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P2INT_0]] + // ENABLED-NEXT: store volatile ptr null, ptr [[BASE]], align 8, !tbaa [[P1INT_0]] + // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: store volatile ptr null, ptr [[BASE]], align 8, !tbaa [[ANYPTR]] + // COMMON-NEXT: ret void // *ptr = 0; } void p3int(int ***ptr) { - // CHECK-LABEL: define void @p3int(ptr noundef %ptr) - // CHECK-NEXT: entry: - // CHECK-NEXT: %ptr.addr = alloca ptr, align 8 - // CHECK-NEXT: store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: [[BASE_0:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: store ptr null, ptr [[BASE_1]], align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: ret void + // COMMON-LABEL: define void @p3int( + // COMMON-SAME: ptr noundef [[PTR:%.+]]) + // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8 + // ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P3INT_0:!.+]] + // ENABLED-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P3INT_0]] + // ENABLED-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[P2INT_0]] + // ENABLED-NEXT: store ptr null, ptr [[BASE_1]], align 8, !tbaa [[P1INT_0]] + // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: store ptr null, ptr [[BASE_1]], align 8, !tbaa [[ANYPTR]] + // COMMON-NEXT: ret void // **ptr = 0; } void p4char(char ****ptr) { - // CHECK-LABEL: define void @p4char(ptr noundef %ptr) - // CHECK-NEXT: entry: - // CHECK-NEXT: %ptr.addr = alloca ptr, align 8 - // CHECK-NEXT: store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: [[BASE_0:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: ret void + // COMMON-LABEL: define void @p4char( + // COMMON-SAME: ptr noundef [[PTR:%.+]]) + // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8 + // ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0:!.+]] + // ENABLED-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0]] + // ENABLED-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[P3CHAR_0:!.+]] + // ENABLED-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[P2CHAR_0:!.+]] + // ENABLED-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[P1CHAR_0:!.+]] + // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[ANYPTR]] + // COMMON-NEXT: ret void // ***ptr = 0; } void p4char_const1(const char ****ptr) { - // CHECK-LABEL: define void @p4char_const1(ptr noundef %ptr) - // CHECK-NEXT: entry: - // CHECK-NEXT: %ptr.addr = alloca ptr, align 8 - // CHECK-NEXT: store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: [[BASE_0:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: ret void + // COMMON-LABEL: define void @p4char_const1( + // COMMON-SAME: ptr noundef [[PTR:%.+]]) + // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8 + // ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0]] + // ENABLED-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0]] + // ENABLED-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[P3CHAR_0]] + // ENABLED-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[P2CHAR_0]] + // ENABLED-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[P1CHAR_0]] + // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[ANYPTR]] + // COMMON-NEXT: ret void // ***ptr = 0; } void p4char_const2(const char **const **ptr) { - // CHECK-LABEL: define void @p4char_const2(ptr noundef %ptr) - // CHECK-NEXT: entry: - // CHECK-NEXT: %ptr.addr = alloca ptr, align 8 - // CHECK-NEXT: store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: [[BASE_0:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: ret void + // COMMON-LABEL: define void @p4char_const2( + // COMMON-SAME: ptr noundef [[PTR:%.+]]) + // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8 + // ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0]] + // ENABLED-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0]] + // ENABLED-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[P3CHAR_0]] + // ENABLED-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[P2CHAR_0]] + // ENABLED-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[P1CHAR_0]] + // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[ANYPTR]] + // COMMON-NEXT: ret void // ***ptr = 0; } @@ -85,19 +113,35 @@ struct S1 { }; void p2struct(struct S1 **ptr) { - // CHECK-LABEL: define void @p2struct(ptr noundef %ptr) - // CHECK-NEXT: entry: - // CHECK-NEXT: %ptr.addr = alloca ptr, align 8 - // CHECK-NEXT: store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[ANY_POINTER_0]] - // CHECK-NEXT: ret void + // COMMON-LABEL: define void @p2struct( + // COMMON-SAME: ptr noundef [[PTR:%.+]]) + // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8 + // ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P2S1_0:!.+]] + // ENABLED-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P2S1_0]] + // ENABLED-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[P1S1_:!.+]] + // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] + // DEFAULT-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[ANYPTR]] + // COMMON-NEXT: ret void // *ptr = 0; } -// CHECK: [[ANY_POINTER_0]] = !{[[ANY_POINTER:!.+]], [[ANY_POINTER]], i64 0} -// CHECK: [[ANY_POINTER]] = !{!"any pointer", [[CHAR:!.+]], i64 0} -// CHECK: [[CHAR]] = !{!"omnipotent char", [[TBAA_ROOT:!.+]], i64 0} -// CHECK: [[TBAA_ROOT]] = !{!"Simple C/C++ TBAA"} -// +// ENABLED: [[P2INT_0]] = !{[[P2INT:!.+]], [[P2INT]], i64 0} +// ENABLED: [[P2INT]] = !{!"p2 int", [[ANY_POINTER:!.+]], i64 0} +// DEFAULT: [[ANYPTR]] = !{[[ANY_POINTER:!.+]], [[ANY_POINTER]], i64 0} +// COMMON: [[ANY_POINTER]] = !{!"any pointer", [[CHAR:!.+]], i64 0} +// COMMON: [[CHAR]] = !{!"omnipotent char", [[TBAA_ROOT:!.+]], i64 0} +// COMMON: [[TBAA_ROOT]] = !{!"Simple C/C++ TBAA"} +// ENABLED: [[P1INT_0]] = !{[[P1INT:!.+]], [[P1INT]], i64 0} +// ENABLED: [[P1INT]] = !{!"p1 int", [[ANY_POINTER]], i64 0} +// ENABLED: [[P3INT_0]] = !{[[P3INT:!.+]], [[P3INT]], i64 0} +// ENABLED: [[P3INT]] = !{!"p3 int", [[ANY_POINTER]], i64 0} +// ENABLED: [[P4CHAR_0]] = !{[[P4CHAR:!.+]], [[P4CHAR]], i64 0} +// ENABLED: [[P4CHAR]] = !{!"p4 omnipotent char", [[ANY_POINTER]], i64 0} +// ENABLED: [[P3CHAR_0]] = !{[[P3CHAR:!.+]], [[P3CHAR]], i64 0} +// ENABLED: [[P3CHAR]] = !{!"p3 omnipotent char", [[ANY_POINTER]], i64 0} +// ENABLED: [[P2CHAR_0]] = !{[[P2CHAR:!.+]], [[P2CHAR]], i64 0} +// ENABLED: [[P2CHAR]] = !{!"p2 omnipotent char", [[ANY_POINTER]], i64 0} +// ENABLED: [[P1CHAR_0]] = !{[[P1CHAR:!.+]], [[P1CHAR]], i64 0} +// ENABLED: [[P1CHAR]] = !{!"p1 omnipotent char", [[ANY_POINTER]], i64 0} diff --git a/clang/test/CodeGen/ubsan-function.cpp b/clang/test/CodeGen/ubsan-function.cpp index bc37a61c98ee3..76d4237383f83 100644 --- a/clang/test/CodeGen/ubsan-function.cpp +++ b/clang/test/CodeGen/ubsan-function.cpp @@ -4,6 +4,9 @@ // RUN: %clang_cc1 -triple aarch64_be-linux-gnu -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s --check-prefixes=CHECK,GNU,64 // RUN: %clang_cc1 -triple arm-none-eabi -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s --check-prefixes=CHECK,ARM,GNU,32 +// RUN: %clang_cc1 -triple arm64e-apple-ios -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all -fptrauth-calls | FileCheck %s --check-prefixes=CHECK,GNU,64,AUTH +// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all -fptrauth-calls | FileCheck %s --check-prefixes=CHECK,GNU,64,AUTH + // GNU: define{{.*}} void @_Z3funv() #0 !func_sanitize ![[FUNCSAN:.*]] { // MSVC: define{{.*}} void @"?fun@@YAXXZ"() #0 !func_sanitize ![[FUNCSAN:.*]] { void fun() {} @@ -13,6 +16,8 @@ void fun() {} // ARM: ptrtoint ptr {{.*}} to i32, !nosanitize !5 // ARM: and i32 {{.*}}, -2, !nosanitize !5 // ARM: inttoptr i32 {{.*}} to ptr, !nosanitize !5 +// AUTH: %[[STRIPPED:.*]] = ptrtoint ptr {{.*}} to i64, !nosanitize +// AUTH: call i64 @llvm.ptrauth.auth(i64 %[[STRIPPED]], i32 0, i64 0), !nosanitize // CHECK: getelementptr <{ i32, i32 }>, ptr {{.*}}, i32 -1, i32 0, !nosanitize // CHECK: load i32, ptr {{.*}}, align {{.*}}, !nosanitize // CHECK: icmp eq i32 {{.*}}, -1056584962, !nosanitize diff --git a/clang/test/CodeGenCUDA/amdgpu-atomic-ops.cu b/clang/test/CodeGenCUDA/amdgpu-atomic-ops.cu index eeb23bc7e1c01..8bf8241e343e7 100644 --- a/clang/test/CodeGenCUDA/amdgpu-atomic-ops.cu +++ b/clang/test/CodeGenCUDA/amdgpu-atomic-ops.cu @@ -1,6 +1,10 @@ // RUN: %clang_cc1 -x hip %s -emit-llvm -o - -triple=amdgcn-amd-amdhsa \ // RUN: -fcuda-is-device -target-cpu gfx906 -fnative-half-type \ -// RUN: -fnative-half-arguments-and-returns | FileCheck %s +// RUN: -fnative-half-arguments-and-returns | FileCheck -check-prefixes=CHECK,SAFEIR %s + +// RUN: %clang_cc1 -x hip %s -emit-llvm -o - -triple=amdgcn-amd-amdhsa \ +// RUN: -fcuda-is-device -target-cpu gfx906 -fnative-half-type \ +// RUN: -fnative-half-arguments-and-returns -munsafe-fp-atomics | FileCheck -check-prefixes=CHECK,UNSAFEIR %s // RUN: %clang_cc1 -x hip %s -O3 -S -o - -triple=amdgcn-amd-amdhsa \ // RUN: -fcuda-is-device -target-cpu gfx1100 -fnative-half-type \ @@ -18,24 +22,38 @@ __global__ void ffp1(float *p) { // CHECK-LABEL: @_Z4ffp1Pf - // CHECK: atomicrmw fadd ptr {{.*}} monotonic - // CHECK: atomicrmw fmax ptr {{.*}} monotonic - // CHECK: atomicrmw fmin ptr {{.*}} monotonic - // CHECK: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic - // CHECK: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic + // SAFEIR: atomicrmw fadd ptr {{.*}} monotonic, align 4{{$}} + // SAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 4{{$}} + // SAFEIR: atomicrmw fmax ptr {{.*}} monotonic, align 4{{$}} + // SAFEIR: atomicrmw fmin ptr {{.*}} monotonic, align 4{{$}} + // SAFEIR: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic, align 4{{$}} + // SAFEIR: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 4{{$}} + + // UNSAFEIR: atomicrmw fadd ptr {{.*}} monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+}}, !amdgpu.ignore.denormal.mode !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fmax ptr {{.*}} monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fmin ptr {{.*}} monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // SAFE: _Z4ffp1Pf // SAFE: global_atomic_cmpswap // SAFE: global_atomic_cmpswap // SAFE: global_atomic_cmpswap // SAFE: global_atomic_cmpswap // SAFE: global_atomic_cmpswap + // SAFE: global_atomic_cmpswap + // UNSAFE: _Z4ffp1Pf // UNSAFE: global_atomic_add_f32 // UNSAFE: global_atomic_cmpswap // UNSAFE: global_atomic_cmpswap // UNSAFE: global_atomic_cmpswap // UNSAFE: global_atomic_cmpswap + // UNSAFE: global_atomic_cmpswap + __atomic_fetch_add(p, 1.0f, memory_order_relaxed); + __atomic_fetch_sub(p, 1.0f, memory_order_relaxed); __atomic_fetch_max(p, 1.0f, memory_order_relaxed); __atomic_fetch_min(p, 1.0f, memory_order_relaxed); __hip_atomic_fetch_max(p, 1.0f, memory_order_relaxed, __HIP_MEMORY_SCOPE_AGENT); @@ -44,23 +62,36 @@ __global__ void ffp1(float *p) { __global__ void ffp2(double *p) { // CHECK-LABEL: @_Z4ffp2Pd - // CHECK: atomicrmw fsub ptr {{.*}} monotonic - // CHECK: atomicrmw fmax ptr {{.*}} monotonic - // CHECK: atomicrmw fmin ptr {{.*}} monotonic - // CHECK: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic - // CHECK: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic + // SAFEIR: atomicrmw fadd ptr {{.*}} monotonic, align 8{{$}} + // SAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 8{{$}} + // SAFEIR: atomicrmw fmax ptr {{.*}} monotonic, align 8{{$}} + // SAFEIR: atomicrmw fmin ptr {{.*}} monotonic, align 8{{$}} + // SAFEIR: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic, align 8{{$}} + // SAFEIR: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 8{{$}} + + // UNSAFEIR: atomicrmw fadd ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fmax ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fmin ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // SAFE-LABEL: @_Z4ffp2Pd // SAFE: global_atomic_cmpswap_b64 // SAFE: global_atomic_cmpswap_b64 // SAFE: global_atomic_cmpswap_b64 // SAFE: global_atomic_cmpswap_b64 // SAFE: global_atomic_cmpswap_b64 + // SAFE: global_atomic_cmpswap_b64 + // UNSAFE-LABEL: @_Z4ffp2Pd - // UNSAFE: global_atomic_cmpswap_x2 - // UNSAFE: global_atomic_cmpswap_x2 + // UNSAFE: global_atomic_add_f64 // UNSAFE: global_atomic_cmpswap_x2 // UNSAFE: global_atomic_max_f64 // UNSAFE: global_atomic_min_f64 + // UNSAFE: global_atomic_max_f64 + // UNSAFE: global_atomic_min_f64 + __atomic_fetch_add(p, 1.0, memory_order_relaxed); __atomic_fetch_sub(p, 1.0, memory_order_relaxed); __atomic_fetch_max(p, 1.0, memory_order_relaxed); __atomic_fetch_min(p, 1.0, memory_order_relaxed); @@ -71,11 +102,20 @@ __global__ void ffp2(double *p) { // long double is the same as double for amdgcn. __global__ void ffp3(long double *p) { // CHECK-LABEL: @_Z4ffp3Pe - // CHECK: atomicrmw fsub ptr {{.*}} monotonic - // CHECK: atomicrmw fmax ptr {{.*}} monotonic - // CHECK: atomicrmw fmin ptr {{.*}} monotonic - // CHECK: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic - // CHECK: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic + // SAFEIR: atomicrmw fadd ptr {{.*}} monotonic, align 8{{$}} + // SAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 8{{$}} + // SAFEIR: atomicrmw fmax ptr {{.*}} monotonic, align 8{{$}} + // SAFEIR: atomicrmw fmin ptr {{.*}} monotonic, align 8{{$}} + // SAFEIR: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic, align 8{{$}} + // SAFEIR: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 8{{$}} + + // UNSAFEIR: atomicrmw fadd ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fmax ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fmin ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // SAFE-LABEL: @_Z4ffp3Pe // SAFE: global_atomic_cmpswap_b64 // SAFE: global_atomic_cmpswap_b64 @@ -84,10 +124,11 @@ __global__ void ffp3(long double *p) { // SAFE: global_atomic_cmpswap_b64 // UNSAFE-LABEL: @_Z4ffp3Pe // UNSAFE: global_atomic_cmpswap_x2 - // UNSAFE: global_atomic_cmpswap_x2 - // UNSAFE: global_atomic_cmpswap_x2 // UNSAFE: global_atomic_max_f64 // UNSAFE: global_atomic_min_f64 + // UNSAFE: global_atomic_max_f64 + // UNSAFE: global_atomic_min_f64 + __atomic_fetch_add(p, 1.0L, memory_order_relaxed); __atomic_fetch_sub(p, 1.0L, memory_order_relaxed); __atomic_fetch_max(p, 1.0L, memory_order_relaxed); __atomic_fetch_min(p, 1.0L, memory_order_relaxed); @@ -98,37 +139,52 @@ __global__ void ffp3(long double *p) { __device__ double ffp4(double *p, float f) { // CHECK-LABEL: @_Z4ffp4Pdf // CHECK: fpext float {{.*}} to double - // CHECK: atomicrmw fsub ptr {{.*}} monotonic + // SAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 8{{$}} + // UNSAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} return __atomic_fetch_sub(p, f, memory_order_relaxed); } __device__ double ffp5(double *p, int i) { // CHECK-LABEL: @_Z4ffp5Pdi // CHECK: sitofp i32 {{.*}} to double - // CHECK: atomicrmw fsub ptr {{.*}} monotonic + // SAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 8{{$}} + // UNSAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} return __atomic_fetch_sub(p, i, memory_order_relaxed); } __global__ void ffp6(_Float16 *p) { // CHECK-LABEL: @_Z4ffp6PDF16 - // CHECK: atomicrmw fadd ptr {{.*}} monotonic - // CHECK: atomicrmw fmax ptr {{.*}} monotonic - // CHECK: atomicrmw fmin ptr {{.*}} monotonic - // CHECK: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic - // CHECK: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic + // SAFEIR: atomicrmw fadd ptr {{.*}} monotonic, align 2{{$}} + // SAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 2{{$}} + // SAFEIR: atomicrmw fmax ptr {{.*}} monotonic, align 2{{$}} + // SAFEIR: atomicrmw fmin ptr {{.*}} monotonic, align 2{{$}} + // SAFEIR: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic, align 2{{$}} + // SAFEIR: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 2{{$}} + + // UNSAFEIR: atomicrmw fadd ptr {{.*}} monotonic, align 2, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 2, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fmax ptr {{.*}} monotonic, align 2, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fmin ptr {{.*}} monotonic, align 2, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic, align 2, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // UNSAFEIR: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 2, !amdgpu.no.fine.grained.memory !{{[0-9]+$}} + // SAFE: _Z4ffp6PDF16 // SAFE: global_atomic_cmpswap // SAFE: global_atomic_cmpswap // SAFE: global_atomic_cmpswap // SAFE: global_atomic_cmpswap // SAFE: global_atomic_cmpswap + // SAFE: global_atomic_cmpswap + // UNSAFE: _Z4ffp6PDF16 // UNSAFE: global_atomic_cmpswap // UNSAFE: global_atomic_cmpswap // UNSAFE: global_atomic_cmpswap // UNSAFE: global_atomic_cmpswap // UNSAFE: global_atomic_cmpswap + // UNSAFE: global_atomic_cmpswap __atomic_fetch_add(p, 1.0, memory_order_relaxed); + __atomic_fetch_sub(p, 1.0, memory_order_relaxed); __atomic_fetch_max(p, 1.0, memory_order_relaxed); __atomic_fetch_min(p, 1.0, memory_order_relaxed); __hip_atomic_fetch_max(p, 1.0f, memory_order_relaxed, __HIP_MEMORY_SCOPE_AGENT); diff --git a/clang/test/CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu b/clang/test/CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu index a5135ab01f0f3..70c86cbb8c3d4 100644 --- a/clang/test/CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu +++ b/clang/test/CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu @@ -16,9 +16,8 @@ // HOST: define{{.*}} void @_Z22__device_stub__kernel1Pi(ptr noundef %x) // COMMON-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel1Pi(ptr addrspace(1){{.*}} %x.coerce) -// CHECK: ={{.*}} addrspacecast ptr addrspace(1) %{{.*}} to ptr // CHECK-NOT: ={{.*}} addrspacecast ptr addrspace(1) %{{.*}} to ptr -// OPT: [[VAL:%.*]] = load i32, ptr addrspace(1) %x.coerce, align 4, !amdgpu.noclobber ![[MD:[0-9]+]] +// OPT: [[VAL:%.*]] = load i32, ptr addrspace(1) %x.coerce, align 4{{$}} // OPT: [[INC:%.*]] = add nsw i32 [[VAL]], 1 // OPT: store i32 [[INC]], ptr addrspace(1) %x.coerce, align 4 // OPT: ret void @@ -28,9 +27,8 @@ __global__ void kernel1(int *x) { // HOST: define{{.*}} void @_Z22__device_stub__kernel2Ri(ptr noundef nonnull align 4 dereferenceable(4) %x) // COMMON-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel2Ri(ptr addrspace(1){{.*}} nonnull align 4 dereferenceable(4) %x.coerce) -// CHECK: ={{.*}} addrspacecast ptr addrspace(1) %{{.*}} to ptr // CHECK-NOT: ={{.*}} addrspacecast ptr addrspace(1) %{{.*}} to ptr -// OPT: [[VAL:%.*]] = load i32, ptr addrspace(1) %x.coerce, align 4, !amdgpu.noclobber ![[MD]] +// OPT: [[VAL:%.*]] = load i32, ptr addrspace(1) %x.coerce, align 4{{$}} // OPT: [[INC:%.*]] = add nsw i32 [[VAL]], 1 // OPT: store i32 [[INC]], ptr addrspace(1) %x.coerce, align 4 // OPT: ret void @@ -67,7 +65,7 @@ struct S { // OPT: [[R1:%.*]] = getelementptr inbounds i8, ptr addrspace(4) %0, i64 8 // OPT: [[P1:%.*]] = load ptr, ptr addrspace(4) [[R1]], align 8 // OPT: [[G1:%.*]] ={{.*}} addrspacecast ptr [[P1]] to ptr addrspace(1) -// OPT: [[V0:%.*]] = load i32, ptr addrspace(1) [[G0]], align 4, !amdgpu.noclobber ![[MD]] +// OPT: [[V0:%.*]] = load i32, ptr addrspace(1) [[G0]], align 4, !amdgpu.noclobber ![[MD:[0-9]+]] // OPT: [[INC:%.*]] = add nsw i32 [[V0]], 1 // OPT: store i32 [[INC]], ptr addrspace(1) [[G0]], align 4 // OPT: [[V1:%.*]] = load float, ptr addrspace(1) [[G1]], align 4 @@ -126,9 +124,8 @@ struct SS { }; // HOST: define{{.*}} void @_Z22__device_stub__kernel82SS(ptr %a.coerce) // COMMON-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel82SS(ptr addrspace(1){{.*}} %a.coerce) -// CHECK: ={{.*}} addrspacecast ptr addrspace(1) %{{.*}} to ptr // CHECK-NOT: ={{.*}} addrspacecast ptr addrspace(1) %{{.*}} to ptr -// OPT: [[VAL:%.*]] = load float, ptr addrspace(1) %a.coerce, align 4, !amdgpu.noclobber ![[MD]] +// OPT: [[VAL:%.*]] = load float, ptr addrspace(1) %a.coerce, align 4{{$}} // OPT: [[INC:%.*]] = fadd contract float [[VAL]], 3.000000e+00 // OPT: store float [[INC]], ptr addrspace(1) %a.coerce, align 4 // OPT: ret void diff --git a/clang/test/CodeGenCUDA/builtins-amdgcn.cu b/clang/test/CodeGenCUDA/builtins-amdgcn.cu index 2e88afac813f4..4bf23e529c7a5 100644 --- a/clang/test/CodeGenCUDA/builtins-amdgcn.cu +++ b/clang/test/CodeGenCUDA/builtins-amdgcn.cu @@ -17,17 +17,16 @@ // CHECK-NEXT: [[OUT_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[OUT]] to ptr // CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[OUT_ADDR]] to ptr // CHECK-NEXT: [[DISPATCH_PTR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[DISPATCH_PTR]] to ptr -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[OUT_COERCE:%.*]] to ptr -// CHECK-NEXT: store ptr [[TMP0]], ptr [[OUT_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[OUT_COERCE:%.*]], ptr [[OUT_ASCAST]], align 8 // CHECK-NEXT: [[OUT1:%.*]] = load ptr, ptr [[OUT_ASCAST]], align 8 // CHECK-NEXT: store ptr [[OUT1]], ptr [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = call align 4 dereferenceable(64) ptr addrspace(4) @llvm.amdgcn.dispatch.ptr() -// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(4) [[TMP1]] to ptr -// CHECK-NEXT: store ptr [[TMP2]], ptr [[DISPATCH_PTR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DISPATCH_PTR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 -// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: store i32 [[TMP4]], ptr [[TMP5]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = call align 4 dereferenceable(64) ptr addrspace(4) @llvm.amdgcn.dispatch.ptr() +// CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(4) [[TMP0]] to ptr +// CHECK-NEXT: store ptr [[TMP1]], ptr [[DISPATCH_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DISPATCH_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i32 [[TMP3]], ptr [[TMP4]], align 4 // CHECK-NEXT: ret void // __global__ void use_dispatch_ptr(int* out) { @@ -43,17 +42,16 @@ __global__ void use_dispatch_ptr(int* out) { // CHECK-NEXT: [[OUT_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[OUT]] to ptr // CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[OUT_ADDR]] to ptr // CHECK-NEXT: [[QUEUE_PTR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[QUEUE_PTR]] to ptr -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[OUT_COERCE:%.*]] to ptr -// CHECK-NEXT: store ptr [[TMP0]], ptr [[OUT_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[OUT_COERCE:%.*]], ptr [[OUT_ASCAST]], align 8 // CHECK-NEXT: [[OUT1:%.*]] = load ptr, ptr [[OUT_ASCAST]], align 8 // CHECK-NEXT: store ptr [[OUT1]], ptr [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = call ptr addrspace(4) @llvm.amdgcn.queue.ptr() -// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(4) [[TMP1]] to ptr -// CHECK-NEXT: store ptr [[TMP2]], ptr [[QUEUE_PTR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[QUEUE_PTR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 -// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: store i32 [[TMP4]], ptr [[TMP5]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = call ptr addrspace(4) @llvm.amdgcn.queue.ptr() +// CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(4) [[TMP0]] to ptr +// CHECK-NEXT: store ptr [[TMP1]], ptr [[QUEUE_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[QUEUE_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i32 [[TMP3]], ptr [[TMP4]], align 4 // CHECK-NEXT: ret void // __global__ void use_queue_ptr(int* out) { @@ -69,17 +67,16 @@ __global__ void use_queue_ptr(int* out) { // CHECK-NEXT: [[OUT_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[OUT]] to ptr // CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[OUT_ADDR]] to ptr // CHECK-NEXT: [[IMPLICITARG_PTR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[IMPLICITARG_PTR]] to ptr -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[OUT_COERCE:%.*]] to ptr -// CHECK-NEXT: store ptr [[TMP0]], ptr [[OUT_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[OUT_COERCE:%.*]], ptr [[OUT_ASCAST]], align 8 // CHECK-NEXT: [[OUT1:%.*]] = load ptr, ptr [[OUT_ASCAST]], align 8 // CHECK-NEXT: store ptr [[OUT1]], ptr [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr() -// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(4) [[TMP1]] to ptr -// CHECK-NEXT: store ptr [[TMP2]], ptr [[IMPLICITARG_PTR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[IMPLICITARG_PTR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 -// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: store i32 [[TMP4]], ptr [[TMP5]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr() +// CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(4) [[TMP0]] to ptr +// CHECK-NEXT: store ptr [[TMP1]], ptr [[IMPLICITARG_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[IMPLICITARG_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i32 [[TMP3]], ptr [[TMP4]], align 4 // CHECK-NEXT: ret void // __global__ void use_implicitarg_ptr(int* out) { @@ -134,16 +131,15 @@ __global__ void test_ds_fadd(float src) { // CHECK-NEXT: [[SRC_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[SRC_ADDR]] to ptr // CHECK-NEXT: [[SHARED_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[SHARED_ADDR]] to ptr // CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[X]] to ptr -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[SHARED_COERCE:%.*]] to ptr -// CHECK-NEXT: store ptr [[TMP0]], ptr [[SHARED_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[SHARED_COERCE:%.*]], ptr [[SHARED_ASCAST]], align 8 // CHECK-NEXT: [[SHARED1:%.*]] = load ptr, ptr [[SHARED_ASCAST]], align 8 // CHECK-NEXT: store float [[SRC:%.*]], ptr [[SRC_ADDR_ASCAST]], align 4 // CHECK-NEXT: store ptr [[SHARED1]], ptr [[SHARED_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[SHARED_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr [[TMP1]] to ptr addrspace(3) -// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[SRC_ADDR_ASCAST]], align 4 -// CHECK-NEXT: [[TMP4:%.*]] = atomicrmw fmin ptr addrspace(3) [[TMP2]], float [[TMP3]] monotonic, align 4 -// CHECK-NEXT: store volatile float [[TMP4]], ptr [[X_ASCAST]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[SHARED_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[TMP0]] to ptr addrspace(3) +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[SRC_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = atomicrmw fmin ptr addrspace(3) [[TMP1]], float [[TMP2]] monotonic, align 4 +// CHECK-NEXT: store volatile float [[TMP3]], ptr [[X_ASCAST]], align 4 // CHECK-NEXT: ret void // __global__ void test_ds_fmin(float src, float *shared) { @@ -184,17 +180,16 @@ __global__ void endpgm() { // CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[OUT_ADDR]] to ptr // CHECK-NEXT: [[A_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[A_ADDR]] to ptr // CHECK-NEXT: [[B_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[B_ADDR]] to ptr -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[OUT_COERCE:%.*]] to ptr -// CHECK-NEXT: store ptr [[TMP0]], ptr [[OUT_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[OUT_COERCE:%.*]], ptr [[OUT_ASCAST]], align 8 // CHECK-NEXT: [[OUT1:%.*]] = load ptr, ptr [[OUT_ASCAST]], align 8 // CHECK-NEXT: store ptr [[OUT1]], ptr [[OUT_ADDR_ASCAST]], align 8 // CHECK-NEXT: store i64 [[A:%.*]], ptr [[A_ADDR_ASCAST]], align 8 // CHECK-NEXT: store i64 [[B:%.*]], ptr [[B_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[A_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[B_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.amdgcn.icmp.i64.i64(i64 [[TMP1]], i64 [[TMP2]], i32 35) -// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: store i64 [[TMP3]], ptr [[TMP4]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[A_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[B_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.amdgcn.icmp.i64.i64(i64 [[TMP0]], i64 [[TMP1]], i32 35) +// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i64 [[TMP2]], ptr [[TMP3]], align 8 // CHECK-NEXT: ret void // __global__ void test_uicmp_i64(unsigned long long *out, unsigned long long a, unsigned long long b) @@ -210,13 +205,12 @@ __global__ void test_uicmp_i64(unsigned long long *out, unsigned long long a, un // CHECK-NEXT: [[OUT_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) // CHECK-NEXT: [[OUT_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[OUT]] to ptr // CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[OUT_ADDR]] to ptr -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[OUT_COERCE:%.*]] to ptr -// CHECK-NEXT: store ptr [[TMP0]], ptr [[OUT_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[OUT_COERCE:%.*]], ptr [[OUT_ASCAST]], align 8 // CHECK-NEXT: [[OUT1:%.*]] = load ptr, ptr [[OUT_ASCAST]], align 8 // CHECK-NEXT: store ptr [[OUT1]], ptr [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.amdgcn.s.memtime() -// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.amdgcn.s.memtime() +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i64 [[TMP0]], ptr [[TMP1]], align 8 // CHECK-NEXT: ret void // __global__ void test_s_memtime(unsigned long long* out) @@ -237,18 +231,17 @@ __device__ void func(float *x); // CHECK-NEXT: [[SRC_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[SRC_ADDR]] to ptr // CHECK-NEXT: [[SHARED_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[SHARED_ADDR]] to ptr // CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[X]] to ptr -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[SHARED_COERCE:%.*]] to ptr -// CHECK-NEXT: store ptr [[TMP0]], ptr [[SHARED_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[SHARED_COERCE:%.*]], ptr [[SHARED_ASCAST]], align 8 // CHECK-NEXT: [[SHARED1:%.*]] = load ptr, ptr [[SHARED_ASCAST]], align 8 // CHECK-NEXT: store float [[SRC:%.*]], ptr [[SRC_ADDR_ASCAST]], align 4 // CHECK-NEXT: store ptr [[SHARED1]], ptr [[SHARED_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[SHARED_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr [[TMP1]] to ptr addrspace(3) -// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[SRC_ADDR_ASCAST]], align 4 -// CHECK-NEXT: [[TMP4:%.*]] = atomicrmw fmin ptr addrspace(3) [[TMP2]], float [[TMP3]] monotonic, align 4 -// CHECK-NEXT: store volatile float [[TMP4]], ptr [[X_ASCAST]], align 4 -// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[SHARED_ADDR_ASCAST]], align 8 -// CHECK-NEXT: call void @_Z4funcPf(ptr noundef [[TMP5]]) #[[ATTR7:[0-9]+]] +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[SHARED_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[TMP0]] to ptr addrspace(3) +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[SRC_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = atomicrmw fmin ptr addrspace(3) [[TMP1]], float [[TMP2]] monotonic, align 4 +// CHECK-NEXT: store volatile float [[TMP3]], ptr [[X_ASCAST]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[SHARED_ADDR_ASCAST]], align 8 +// CHECK-NEXT: call void @_Z4funcPf(ptr noundef [[TMP4]]) #[[ATTR7:[0-9]+]] // CHECK-NEXT: ret void // __global__ void test_ds_fmin_func(float src, float *__restrict shared) { @@ -264,14 +257,13 @@ __global__ void test_ds_fmin_func(float src, float *__restrict shared) { // CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[X]] to ptr // CHECK-NEXT: [[X_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[X_ADDR]] to ptr // CHECK-NEXT: [[RET_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RET]] to ptr -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[X_COERCE:%.*]] to ptr -// CHECK-NEXT: store ptr [[TMP0]], ptr [[X_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[X_COERCE:%.*]], ptr [[X_ASCAST]], align 8 // CHECK-NEXT: [[X1:%.*]] = load ptr, ptr [[X_ASCAST]], align 8 // CHECK-NEXT: store ptr [[X1]], ptr [[X_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[X_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = call i1 @llvm.amdgcn.is.shared(ptr [[TMP1]]) -// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TMP2]] to i8 -// CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[RET_ASCAST]], align 1 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.is.shared(ptr [[TMP0]]) +// CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[TMP1]] to i8 +// CHECK-NEXT: store i8 [[STOREDV]], ptr [[RET_ASCAST]], align 1 // CHECK-NEXT: ret void // __global__ void test_is_shared(float *x){ @@ -286,14 +278,13 @@ __global__ void test_is_shared(float *x){ // CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[X]] to ptr // CHECK-NEXT: [[X_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[X_ADDR]] to ptr // CHECK-NEXT: [[RET_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RET]] to ptr -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[X_COERCE:%.*]] to ptr -// CHECK-NEXT: store ptr [[TMP0]], ptr [[X_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[X_COERCE:%.*]], ptr [[X_ASCAST]], align 8 // CHECK-NEXT: [[X1:%.*]] = load ptr, ptr [[X_ASCAST]], align 8 // CHECK-NEXT: store ptr [[X1]], ptr [[X_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[X_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[TMP1]]) -// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TMP2]] to i8 -// CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[RET_ASCAST]], align 1 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[TMP0]]) +// CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[TMP1]] to i8 +// CHECK-NEXT: store i8 [[STOREDV]], ptr [[RET_ASCAST]], align 1 // CHECK-NEXT: ret void // __global__ void test_is_private(int *x){ diff --git a/clang/test/CodeGenCUDA/builtins-spirv-amdgcn.cu b/clang/test/CodeGenCUDA/builtins-spirv-amdgcn.cu index 32851805298f1..1cbe358910b85 100644 --- a/clang/test/CodeGenCUDA/builtins-spirv-amdgcn.cu +++ b/clang/test/CodeGenCUDA/builtins-spirv-amdgcn.cu @@ -17,16 +17,15 @@ // CHECK-NEXT: [[OUT_ASCAST:%.*]] = addrspacecast ptr [[OUT]] to ptr addrspace(4) // CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr [[OUT_ADDR]] to ptr addrspace(4) // CHECK-NEXT: [[DISPATCH_PTR_ASCAST:%.*]] = addrspacecast ptr [[DISPATCH_PTR]] to ptr addrspace(4) -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[OUT_COERCE:%.*]] to ptr addrspace(4) -// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[OUT_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[OUT_COERCE:%.*]], ptr addrspace(4) [[OUT_ASCAST]], align 8 // CHECK-NEXT: [[OUT1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ASCAST]], align 8 // CHECK-NEXT: store ptr addrspace(4) [[OUT1]], ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = call align 4 dereferenceable(64) addrspace(4) ptr addrspace(4) @llvm.amdgcn.dispatch.ptr() -// CHECK-NEXT: store ptr addrspace(4) [[TMP1]], ptr addrspace(4) [[DISPATCH_PTR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[DISPATCH_PTR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(4) [[TMP2]], align 4 -// CHECK-NEXT: [[TMP4:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(4) [[TMP4]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = call align 4 dereferenceable(64) addrspace(4) ptr addrspace(4) @llvm.amdgcn.dispatch.ptr() +// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[DISPATCH_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[DISPATCH_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr addrspace(4) [[TMP1]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i32 [[TMP2]], ptr addrspace(4) [[TMP3]], align 4 // CHECK-NEXT: ret void // __global__ void use_dispatch_ptr(int* out) { @@ -42,16 +41,15 @@ __global__ void use_dispatch_ptr(int* out) { // CHECK-NEXT: [[OUT_ASCAST:%.*]] = addrspacecast ptr [[OUT]] to ptr addrspace(4) // CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr [[OUT_ADDR]] to ptr addrspace(4) // CHECK-NEXT: [[QUEUE_PTR_ASCAST:%.*]] = addrspacecast ptr [[QUEUE_PTR]] to ptr addrspace(4) -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[OUT_COERCE:%.*]] to ptr addrspace(4) -// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[OUT_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[OUT_COERCE:%.*]], ptr addrspace(4) [[OUT_ASCAST]], align 8 // CHECK-NEXT: [[OUT1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ASCAST]], align 8 // CHECK-NEXT: store ptr addrspace(4) [[OUT1]], ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = call addrspace(4) ptr addrspace(4) @llvm.amdgcn.queue.ptr() -// CHECK-NEXT: store ptr addrspace(4) [[TMP1]], ptr addrspace(4) [[QUEUE_PTR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[QUEUE_PTR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(4) [[TMP2]], align 4 -// CHECK-NEXT: [[TMP4:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(4) [[TMP4]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = call addrspace(4) ptr addrspace(4) @llvm.amdgcn.queue.ptr() +// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[QUEUE_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[QUEUE_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr addrspace(4) [[TMP1]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i32 [[TMP2]], ptr addrspace(4) [[TMP3]], align 4 // CHECK-NEXT: ret void // __global__ void use_queue_ptr(int* out) { @@ -67,16 +65,15 @@ __global__ void use_queue_ptr(int* out) { // CHECK-NEXT: [[OUT_ASCAST:%.*]] = addrspacecast ptr [[OUT]] to ptr addrspace(4) // CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr [[OUT_ADDR]] to ptr addrspace(4) // CHECK-NEXT: [[IMPLICITARG_PTR_ASCAST:%.*]] = addrspacecast ptr [[IMPLICITARG_PTR]] to ptr addrspace(4) -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[OUT_COERCE:%.*]] to ptr addrspace(4) -// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[OUT_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[OUT_COERCE:%.*]], ptr addrspace(4) [[OUT_ASCAST]], align 8 // CHECK-NEXT: [[OUT1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ASCAST]], align 8 // CHECK-NEXT: store ptr addrspace(4) [[OUT1]], ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = call addrspace(4) ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr() -// CHECK-NEXT: store ptr addrspace(4) [[TMP1]], ptr addrspace(4) [[IMPLICITARG_PTR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[IMPLICITARG_PTR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(4) [[TMP2]], align 4 -// CHECK-NEXT: [[TMP4:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(4) [[TMP4]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = call addrspace(4) ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr() +// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[IMPLICITARG_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[IMPLICITARG_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr addrspace(4) [[TMP1]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i32 [[TMP2]], ptr addrspace(4) [[TMP3]], align 4 // CHECK-NEXT: ret void // __global__ void use_implicitarg_ptr(int* out) { @@ -131,16 +128,15 @@ __global__ void test_ds_fadd(float src) { // CHECK-NEXT: [[SRC_ADDR_ASCAST:%.*]] = addrspacecast ptr [[SRC_ADDR]] to ptr addrspace(4) // CHECK-NEXT: [[SHARED_ADDR_ASCAST:%.*]] = addrspacecast ptr [[SHARED_ADDR]] to ptr addrspace(4) // CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast ptr [[X]] to ptr addrspace(4) -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[SHARED_COERCE:%.*]] to ptr addrspace(4) -// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[SHARED_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[SHARED_COERCE:%.*]], ptr addrspace(4) [[SHARED_ASCAST]], align 8 // CHECK-NEXT: [[SHARED1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[SHARED_ASCAST]], align 8 // CHECK-NEXT: store float [[SRC:%.*]], ptr addrspace(4) [[SRC_ADDR_ASCAST]], align 4 // CHECK-NEXT: store ptr addrspace(4) [[SHARED1]], ptr addrspace(4) [[SHARED_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[SHARED_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(4) [[TMP1]] to ptr addrspace(3) -// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr addrspace(4) [[SRC_ADDR_ASCAST]], align 4 -// CHECK-NEXT: [[TMP4:%.*]] = atomicrmw fmin ptr addrspace(3) [[TMP2]], float [[TMP3]] monotonic, align 4 -// CHECK-NEXT: store volatile float [[TMP4]], ptr addrspace(4) [[X_ASCAST]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[SHARED_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(4) [[TMP0]] to ptr addrspace(3) +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr addrspace(4) [[SRC_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = atomicrmw fmin ptr addrspace(3) [[TMP1]], float [[TMP2]] monotonic, align 4 +// CHECK-NEXT: store volatile float [[TMP3]], ptr addrspace(4) [[X_ASCAST]], align 4 // CHECK-NEXT: ret void // __global__ void test_ds_fmin(float src, float *shared) { @@ -175,17 +171,16 @@ __global__ void endpgm() { // CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr [[OUT_ADDR]] to ptr addrspace(4) // CHECK-NEXT: [[A_ADDR_ASCAST:%.*]] = addrspacecast ptr [[A_ADDR]] to ptr addrspace(4) // CHECK-NEXT: [[B_ADDR_ASCAST:%.*]] = addrspacecast ptr [[B_ADDR]] to ptr addrspace(4) -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[OUT_COERCE:%.*]] to ptr addrspace(4) -// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[OUT_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[OUT_COERCE:%.*]], ptr addrspace(4) [[OUT_ASCAST]], align 8 // CHECK-NEXT: [[OUT1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ASCAST]], align 8 // CHECK-NEXT: store ptr addrspace(4) [[OUT1]], ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 // CHECK-NEXT: store i64 [[A:%.*]], ptr addrspace(4) [[A_ADDR_ASCAST]], align 8 // CHECK-NEXT: store i64 [[B:%.*]], ptr addrspace(4) [[B_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr addrspace(4) [[A_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr addrspace(4) [[B_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP3:%.*]] = call addrspace(4) i64 @llvm.amdgcn.icmp.i64.i64(i64 [[TMP1]], i64 [[TMP2]], i32 35) -// CHECK-NEXT: [[TMP4:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: store i64 [[TMP3]], ptr addrspace(4) [[TMP4]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr addrspace(4) [[A_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr addrspace(4) [[B_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = call addrspace(4) i64 @llvm.amdgcn.icmp.i64.i64(i64 [[TMP0]], i64 [[TMP1]], i32 35) +// CHECK-NEXT: [[TMP3:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i64 [[TMP2]], ptr addrspace(4) [[TMP3]], align 8 // CHECK-NEXT: ret void // __global__ void test_uicmp_i64(unsigned long long *out, unsigned long long a, unsigned long long b) @@ -201,13 +196,12 @@ __global__ void test_uicmp_i64(unsigned long long *out, unsigned long long a, un // CHECK-NEXT: [[OUT_ADDR:%.*]] = alloca ptr addrspace(4), align 8 // CHECK-NEXT: [[OUT_ASCAST:%.*]] = addrspacecast ptr [[OUT]] to ptr addrspace(4) // CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr [[OUT_ADDR]] to ptr addrspace(4) -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[OUT_COERCE:%.*]] to ptr addrspace(4) -// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[OUT_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[OUT_COERCE:%.*]], ptr addrspace(4) [[OUT_ASCAST]], align 8 // CHECK-NEXT: [[OUT1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ASCAST]], align 8 // CHECK-NEXT: store ptr addrspace(4) [[OUT1]], ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = call addrspace(4) i64 @llvm.amdgcn.s.memtime() -// CHECK-NEXT: [[TMP2:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 -// CHECK-NEXT: store i64 [[TMP1]], ptr addrspace(4) [[TMP2]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = call addrspace(4) i64 @llvm.amdgcn.s.memtime() +// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i64 [[TMP0]], ptr addrspace(4) [[TMP1]], align 8 // CHECK-NEXT: ret void // __global__ void test_s_memtime(unsigned long long* out) @@ -228,18 +222,17 @@ __device__ void func(float *x); // CHECK-NEXT: [[SRC_ADDR_ASCAST:%.*]] = addrspacecast ptr [[SRC_ADDR]] to ptr addrspace(4) // CHECK-NEXT: [[SHARED_ADDR_ASCAST:%.*]] = addrspacecast ptr [[SHARED_ADDR]] to ptr addrspace(4) // CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast ptr [[X]] to ptr addrspace(4) -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[SHARED_COERCE:%.*]] to ptr addrspace(4) -// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[SHARED_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[SHARED_COERCE:%.*]], ptr addrspace(4) [[SHARED_ASCAST]], align 8 // CHECK-NEXT: [[SHARED1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[SHARED_ASCAST]], align 8 // CHECK-NEXT: store float [[SRC:%.*]], ptr addrspace(4) [[SRC_ADDR_ASCAST]], align 4 // CHECK-NEXT: store ptr addrspace(4) [[SHARED1]], ptr addrspace(4) [[SHARED_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[SHARED_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(4) [[TMP1]] to ptr addrspace(3) -// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr addrspace(4) [[SRC_ADDR_ASCAST]], align 4 -// CHECK-NEXT: [[TMP4:%.*]] = atomicrmw fmin ptr addrspace(3) [[TMP2]], float [[TMP3]] monotonic, align 4 -// CHECK-NEXT: store volatile float [[TMP4]], ptr addrspace(4) [[X_ASCAST]], align 4 -// CHECK-NEXT: [[TMP5:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[SHARED_ADDR_ASCAST]], align 8 -// CHECK-NEXT: call spir_func addrspace(4) void @_Z4funcPf(ptr addrspace(4) noundef [[TMP5]]) #[[ATTR6:[0-9]+]] +// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[SHARED_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(4) [[TMP0]] to ptr addrspace(3) +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr addrspace(4) [[SRC_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = atomicrmw fmin ptr addrspace(3) [[TMP1]], float [[TMP2]] monotonic, align 4 +// CHECK-NEXT: store volatile float [[TMP3]], ptr addrspace(4) [[X_ASCAST]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[SHARED_ADDR_ASCAST]], align 8 +// CHECK-NEXT: call spir_func addrspace(4) void @_Z4funcPf(ptr addrspace(4) noundef [[TMP4]]) #[[ATTR6:[0-9]+]] // CHECK-NEXT: ret void // __global__ void test_ds_fmin_func(float src, float *__restrict shared) { @@ -255,15 +248,14 @@ __global__ void test_ds_fmin_func(float src, float *__restrict shared) { // CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast ptr [[X]] to ptr addrspace(4) // CHECK-NEXT: [[X_ADDR_ASCAST:%.*]] = addrspacecast ptr [[X_ADDR]] to ptr addrspace(4) // CHECK-NEXT: [[RET_ASCAST:%.*]] = addrspacecast ptr [[RET]] to ptr addrspace(4) -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[X_COERCE:%.*]] to ptr addrspace(4) -// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[X_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[X_COERCE:%.*]], ptr addrspace(4) [[X_ASCAST]], align 8 // CHECK-NEXT: [[X1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[X_ASCAST]], align 8 // CHECK-NEXT: store ptr addrspace(4) [[X1]], ptr addrspace(4) [[X_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[X_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(4) [[TMP1]] to ptr -// CHECK-NEXT: [[TMP3:%.*]] = call addrspace(4) i1 @llvm.amdgcn.is.shared(ptr [[TMP2]]) -// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TMP3]] to i8 -// CHECK-NEXT: store i8 [[FROMBOOL]], ptr addrspace(4) [[RET_ASCAST]], align 1 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[X_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(4) [[TMP0]] to ptr +// CHECK-NEXT: [[TMP2:%.*]] = call addrspace(4) i1 @llvm.amdgcn.is.shared(ptr [[TMP1]]) +// CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[TMP2]] to i8 +// CHECK-NEXT: store i8 [[STOREDV]], ptr addrspace(4) [[RET_ASCAST]], align 1 // CHECK-NEXT: ret void // __global__ void test_is_shared(float *x){ @@ -278,15 +270,14 @@ __global__ void test_is_shared(float *x){ // CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast ptr [[X]] to ptr addrspace(4) // CHECK-NEXT: [[X_ADDR_ASCAST:%.*]] = addrspacecast ptr [[X_ADDR]] to ptr addrspace(4) // CHECK-NEXT: [[RET_ASCAST:%.*]] = addrspacecast ptr [[RET]] to ptr addrspace(4) -// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[X_COERCE:%.*]] to ptr addrspace(4) -// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[X_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(1) [[X_COERCE:%.*]], ptr addrspace(4) [[X_ASCAST]], align 8 // CHECK-NEXT: [[X1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[X_ASCAST]], align 8 // CHECK-NEXT: store ptr addrspace(4) [[X1]], ptr addrspace(4) [[X_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[X_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(4) [[TMP1]] to ptr -// CHECK-NEXT: [[TMP3:%.*]] = call addrspace(4) i1 @llvm.amdgcn.is.private(ptr [[TMP2]]) -// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TMP3]] to i8 -// CHECK-NEXT: store i8 [[FROMBOOL]], ptr addrspace(4) [[RET_ASCAST]], align 1 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[X_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(4) [[TMP0]] to ptr +// CHECK-NEXT: [[TMP2:%.*]] = call addrspace(4) i1 @llvm.amdgcn.is.private(ptr [[TMP1]]) +// CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[TMP2]] to i8 +// CHECK-NEXT: store i8 [[STOREDV]], ptr addrspace(4) [[RET_ASCAST]], align 1 // CHECK-NEXT: ret void // __global__ void test_is_private(int *x){ diff --git a/clang/test/CodeGenCUDA/convergent.cu b/clang/test/CodeGenCUDA/convergent.cu index 5d98d4ba69262..334e5ec34d7cd 100644 --- a/clang/test/CodeGenCUDA/convergent.cu +++ b/clang/test/CodeGenCUDA/convergent.cu @@ -1,3 +1,4 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --version 5 // REQUIRES: x86-registered-target // REQUIRES: nvptx-registered-target @@ -10,36 +11,89 @@ #include "Inputs/cuda.h" -// DEVICE: Function Attrs: -// DEVICE-SAME: convergent -// DEVICE-NEXT: define{{.*}} void @_Z3foov +// DEVICE-LABEL: define dso_local void @_Z3foov( +// DEVICE-SAME: ) #[[ATTR0:[0-9]+]] { +// DEVICE-NEXT: [[ENTRY:.*:]] +// DEVICE-NEXT: ret void +// __device__ void foo() {} +// DEVICE-LABEL: define dso_local void @_Z3baxv( +// DEVICE-SAME: ) #[[ATTR1:[0-9]+]] { +// DEVICE-NEXT: [[ENTRY:.*:]] +// DEVICE-NEXT: ret void +// +[[clang::noconvergent]] __device__ void bax() {} -// HOST: Function Attrs: -// HOST-NOT: convergent -// HOST-NEXT: define{{.*}} void @_Z3barv -// DEVICE: Function Attrs: -// DEVICE-SAME: convergent -// DEVICE-NEXT: define{{.*}} void @_Z3barv __host__ __device__ void baz(); + +__host__ __device__ float aliasf0(int) asm("something"); +__host__ __device__ [[clang::noconvergent]] float aliasf1(int) asm("somethingelse"); + +// DEVICE-LABEL: define dso_local void @_Z3barv( +// DEVICE-SAME: ) #[[ATTR0]] { +// DEVICE-NEXT: [[ENTRY:.*:]] +// DEVICE-NEXT: [[X:%.*]] = alloca i32, align 4 +// DEVICE-NEXT: call void @_Z3bazv() #[[ATTR4:[0-9]+]] +// DEVICE-NEXT: [[TMP0:%.*]] = call i32 asm "trap", "=l"() #[[ATTR5:[0-9]+]], !srcloc [[META3:![0-9]+]] +// DEVICE-NEXT: store i32 [[TMP0]], ptr [[X]], align 4 +// DEVICE-NEXT: call void asm sideeffect "trap", ""() #[[ATTR4]], !srcloc [[META4:![0-9]+]] +// DEVICE-NEXT: call void asm sideeffect "nop", ""() #[[ATTR6:[0-9]+]], !srcloc [[META5:![0-9]+]] +// DEVICE-NEXT: [[TMP1:%.*]] = load i32, ptr [[X]], align 4 +// DEVICE-NEXT: [[CALL:%.*]] = call contract noundef float @something(i32 noundef [[TMP1]]) #[[ATTR4]] +// DEVICE-NEXT: [[TMP2:%.*]] = load i32, ptr [[X]], align 4 +// DEVICE-NEXT: [[CALL1:%.*]] = call contract noundef float @somethingelse(i32 noundef [[TMP2]]) #[[ATTR6]] +// DEVICE-NEXT: ret void +// +// HOST-LABEL: define dso_local void @_Z3barv( +// HOST-SAME: ) #[[ATTR0:[0-9]+]] { +// HOST-NEXT: [[ENTRY:.*:]] +// HOST-NEXT: [[X:%.*]] = alloca i32, align 4 +// HOST-NEXT: call void @_Z3bazv() +// HOST-NEXT: [[TMP0:%.*]] = call i32 asm "trap", "=l,~{dirflag},~{fpsr},~{flags}"() #[[ATTR2:[0-9]+]], !srcloc [[META2:![0-9]+]] +// HOST-NEXT: store i32 [[TMP0]], ptr [[X]], align 4 +// HOST-NEXT: call void asm sideeffect "trap", "~{dirflag},~{fpsr},~{flags}"() #[[ATTR3:[0-9]+]], !srcloc [[META3:![0-9]+]] +// HOST-NEXT: call void asm sideeffect "nop", "~{dirflag},~{fpsr},~{flags}"() #[[ATTR3]], !srcloc [[META4:![0-9]+]] +// HOST-NEXT: [[TMP1:%.*]] = load i32, ptr [[X]], align 4 +// HOST-NEXT: [[CALL:%.*]] = call contract noundef float @something(i32 noundef [[TMP1]]) +// HOST-NEXT: [[TMP2:%.*]] = load i32, ptr [[X]], align 4 +// HOST-NEXT: [[CALL1:%.*]] = call contract noundef float @somethingelse(i32 noundef [[TMP2]]) +// HOST-NEXT: ret void +// __host__ __device__ void bar() { - // DEVICE: call void @_Z3bazv() [[CALL_ATTR:#[0-9]+]] baz(); - // DEVICE: call i32 asm "trap;", "=l"() [[ASM_ATTR:#[0-9]+]] int x; - asm ("trap;" : "=l"(x)); - // DEVICE: call void asm sideeffect "trap;", ""() [[ASM_ATTR:#[0-9]+]] - asm volatile ("trap;"); + asm ("trap" : "=l"(x)); + asm volatile ("trap"); + [[clang::noconvergent]] { asm volatile ("nop"); } + aliasf0(x); + aliasf1(x); } -// DEVICE: declare void @_Z3bazv() [[BAZ_ATTR:#[0-9]+]] -// DEVICE: attributes [[BAZ_ATTR]] = { -// DEVICE-SAME: convergent -// DEVICE-SAME: } -// DEVICE-DAG: attributes [[CALL_ATTR]] = { convergent -// DEVICE-DAG: attributes [[ASM_ATTR]] = { convergent - -// HOST: declare void @_Z3bazv() [[BAZ_ATTR:#[0-9]+]] -// HOST: attributes [[BAZ_ATTR]] = { -// HOST-NOT: convergent -// HOST-SAME: } + +//. +// DEVICE: attributes #[[ATTR0]] = { convergent mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ptx32" } +// DEVICE: attributes #[[ATTR1]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ptx32" } +// DEVICE: attributes #[[ATTR2:[0-9]+]] = { convergent nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ptx32" } +// DEVICE: attributes #[[ATTR3:[0-9]+]] = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ptx32" } +// DEVICE: attributes #[[ATTR4]] = { convergent nounwind } +// DEVICE: attributes #[[ATTR5]] = { convergent nounwind memory(none) } +// DEVICE: attributes #[[ATTR6]] = { nounwind } +//. +// HOST: attributes #[[ATTR0]] = { mustprogress noinline nounwind optnone "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } +// HOST: attributes #[[ATTR1:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } +// HOST: attributes #[[ATTR2]] = { nounwind memory(none) } +// HOST: attributes #[[ATTR3]] = { nounwind } +//. +// DEVICE: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} +// DEVICE: [[META1:![0-9]+]] = !{i32 7, !"nvvm-reflect-ftz", i32 0} +// DEVICE: [[META2:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} +// DEVICE: [[META3]] = !{i64 3120} +// DEVICE: [[META4]] = !{i64 3155} +// DEVICE: [[META5]] = !{i64 3206} +//. +// HOST: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} +// HOST: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} +// HOST: [[META2]] = !{i64 3120} +// HOST: [[META3]] = !{i64 3155} +// HOST: [[META4]] = !{i64 3206} +//. diff --git a/clang/test/CodeGenCXX/aarch64-fmv-resolver-emission.cpp b/clang/test/CodeGenCXX/aarch64-fmv-resolver-emission.cpp new file mode 100644 index 0000000000000..79c07c0d9db11 --- /dev/null +++ b/clang/test/CodeGenCXX/aarch64-fmv-resolver-emission.cpp @@ -0,0 +1,111 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s + +// CHECK: @_Z23used_before_default_defv = weak_odr ifunc void (), ptr @_Z23used_before_default_defv.resolver +// CHECK: @_Z22used_after_default_defv = weak_odr ifunc void (), ptr @_Z22used_after_default_defv.resolver +// CHECK-NOT: @_Z24used_before_default_declv = weak_odr ifunc void (), ptr @_Z24used_before_default_declv.resolver +// CHECK-NOT: @_Z23used_after_default_declv = weak_odr ifunc void (), ptr @_Z23used_after_default_declv.resolver +// CHECK-NOT: @_Z15used_no_defaultv = weak_odr ifunc void (), ptr @_Z15used_no_defaultv.resolver +// CHECK-NOT: @_Z19not_used_no_defaultv = weak_odr ifunc void (), ptr @_Z19not_used_no_defaultv.resolver +// CHECK: @_Z21not_used_with_defaultv = weak_odr ifunc void (), ptr @_Z21not_used_with_defaultv.resolver + + +// Test that an ifunc is generated and used when the default +// version is defined after the first use of the function. +// +__attribute__((target_version("aes"))) void used_before_default_def(void) {} +// CHECK-LABEL: define dso_local void @_Z23used_before_default_defv._Maes( +// +void call_before_def(void) { used_before_default_def(); } +// CHECK-LABEL: define dso_local void @_Z15call_before_defv( +// CHECK: call void @_Z23used_before_default_defv() +// +__attribute__((target_version("default"))) void used_before_default_def(void) {} +// CHECK-LABEL: define dso_local void @_Z23used_before_default_defv.default( +// +// CHECK-NOT: declare void @_Z23used_before_default_defv( + + +// Test that an ifunc is generated and used when the default +// version is defined before the first use of the function. +// +__attribute__((target_version("aes"))) void used_after_default_def(void) {} +// CHECK-LABEL: define dso_local void @_Z22used_after_default_defv._Maes( +// +__attribute__((target_version("default"))) void used_after_default_def(void) {} +// CHECK-LABEL: define dso_local void @_Z22used_after_default_defv.default( +// +void call_after_def(void) { used_after_default_def(); } +// CHECK-LABEL: define dso_local void @_Z14call_after_defv( +// CHECK: call void @_Z22used_after_default_defv() +// +// CHECK-NOT: declare void @_Z22used_after_default_defv( + + +// Test that an unmagled declaration is generated and used when the +// default version is declared after the first use of the function. +// +__attribute__((target_version("aes"))) void used_before_default_decl(void) {} +// CHECK-LABEL: define dso_local void @_Z24used_before_default_declv._Maes( +// +void call_before_decl(void) { used_before_default_decl(); } +// CHECK-LABEL: define dso_local void @_Z16call_before_declv( +// CHECK: call void @_Z24used_before_default_declv() +// +__attribute__((target_version("default"))) void used_before_default_decl(void); +// CHECK: declare void @_Z24used_before_default_declv() + + +// Test that an unmagled declaration is generated and used when the +// default version is declared before the first use of the function. +// +__attribute__((target_version("aes"))) void used_after_default_decl(void) {} +// CHECK-LABEL: define dso_local void @_Z23used_after_default_declv._Maes( +// +__attribute__((target_version("default"))) void used_after_default_decl(void); +// CHECK: declare void @_Z23used_after_default_declv() +// +void call_after_decl(void) { used_after_default_decl(); } +// CHECK-LABEL: define dso_local void @_Z15call_after_declv( +// CHECK: call void @_Z23used_after_default_declv() + + +// Test that an unmagled declaration is generated and used when +// the default version is not present. +// +__attribute__((target_version("aes"))) void used_no_default(void) {} +// CHECK-LABEL: define dso_local void @_Z15used_no_defaultv._Maes( +// +void call_no_default(void) { used_no_default(); } +// CHECK-LABEL: define dso_local void @_Z15call_no_defaultv( +// CHECK: call void @_Z15used_no_defaultv() +// +// CHECK: declare void @_Z15used_no_defaultv() + + +// Test that neither an ifunc nor a declaration is generated if the default +// definition is missing since the versioned function is not used. +// +__attribute__((target_version("aes"))) void not_used_no_default(void) {} +// CHECK-LABEL: define dso_local void @_Z19not_used_no_defaultv._Maes( +// +// CHECK-NOT: declare void @_Z19not_used_no_defaultv( + + +// Test that an ifunc is generated if the default version is defined but not used. +// +__attribute__((target_version("aes"))) void not_used_with_default(void) {} +// CHECK-LABEL: define dso_local void @_Z21not_used_with_defaultv._Maes( +// +__attribute__((target_version("default"))) void not_used_with_default(void) {} +// CHECK-LABEL: define dso_local void @_Z21not_used_with_defaultv.default( +// +// CHECK-NOT: declare void @_Z21not_used_with_defaultv( + + +// CHECK: define weak_odr ptr @_Z23used_before_default_defv.resolver() +// CHECK: define weak_odr ptr @_Z22used_after_default_defv.resolver() +// CHECK-NOT: define weak_odr ptr @_Z24used_before_default_declv.resolver( +// CHECK-NOT: define weak_odr ptr @_Z23used_after_default_declv.resolver( +// CHECK-NOT: define weak_odr ptr @_Z15used_no_defaultv.resolver( +// CHECK-NOT: define weak_odr ptr @_Z19not_used_no_defaultv.resolver( +// CHECK: define weak_odr ptr @_Z21not_used_with_defaultv.resolver() diff --git a/clang/test/CodeGenCXX/aarch64-mangle-sve-vectors-msvc.cpp b/clang/test/CodeGenCXX/aarch64-mangle-sve-vectors-msvc.cpp index 55b87da122b04..435feec774ece 100644 --- a/clang/test/CodeGenCXX/aarch64-mangle-sve-vectors-msvc.cpp +++ b/clang/test/CodeGenCXX/aarch64-mangle-sve-vectors-msvc.cpp @@ -3,5 +3,5 @@ template struct S {}; -// CHECK: cannot mangle this built-in __SVInt8_t type yet +// CHECK: cannot mangle this built-in type: __SVInt8_t yet void f1(S<__SVInt8_t>) {} diff --git a/clang/test/CodeGenCXX/address-space-cast-coerce.cpp b/clang/test/CodeGenCXX/address-space-cast-coerce.cpp index 7279b6c7f23a0..1ad46042b6efd 100644 --- a/clang/test/CodeGenCXX/address-space-cast-coerce.cpp +++ b/clang/test/CodeGenCXX/address-space-cast-coerce.cpp @@ -46,9 +46,9 @@ int mane() { char1 f1{1}; char1 f2{1}; -// CHECK: [[TMP:%.+]] = alloca i16 -// CHECK: [[COERCE:%.+]] = addrspacecast ptr addrspace(5) [[TMP]] to ptr -// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %{{.+}}, ptr align 2 [[COERCE]], i64 1, i1 false) +// CHECK: [[CALL:%.*]] = call i16 +// CHECK: [[TRUNC:%.*]] = trunc i16 [[CALL]] to i8 +// CHECK: store i8 [[TRUNC]] char1 f3 = f1 + f2; } diff --git a/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp b/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp index 412edd6d3edc0..e842de6335046 100644 --- a/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp +++ b/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp @@ -68,23 +68,23 @@ void w_branch_elided(unsigned e){ // CHECK-NEXT: [[E_ADDR:%.*]] = alloca i32, align 4 // CHECK-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK-NEXT: store i32 [[E:%.*]], ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR4:[0-9]+]] +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR3:[0-9]+]] // CHECK-NEXT: store i32 0, ptr [[I]], align 4, !tbaa [[TBAA2]] // CHECK-NEXT: br label [[FOR_COND:%.*]] // CHECK: for.cond: -// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[I]], align 4, !tbaa [[TBAA2]] -// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]] -// CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], [[TMP2]] +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[I]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP0]], [[TMP1]] // CHECK-NEXT: [[CMP_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[CMP]], i1 true) // CHECK-NEXT: br i1 [[CMP_EXPVAL]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] // CHECK: for.cond.cleanup: -// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR4]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR3]] // CHECK-NEXT: br label [[FOR_END:%.*]] // CHECK: for.body: // CHECK-NEXT: br label [[FOR_INC:%.*]] // CHECK: for.inc: -// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]] -// CHECK-NEXT: [[INC:%.*]] = add i32 [[TMP4]], 1 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[INC:%.*]] = add i32 [[TMP2]], 1 // CHECK-NEXT: store i32 [[INC]], ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]] // CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP11:![0-9]+]] // CHECK: for.end: @@ -100,23 +100,23 @@ void fl(unsigned e) // CHECK-NEXT: [[E_ADDR:%.*]] = alloca i32, align 4 // CHECK-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK-NEXT: store i32 [[E:%.*]], ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR4]] +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR3]] // CHECK-NEXT: store i32 0, ptr [[I]], align 4, !tbaa [[TBAA2]] // CHECK-NEXT: br label [[FOR_COND:%.*]] // CHECK: for.cond: -// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[I]], align 4, !tbaa [[TBAA2]] -// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]] -// CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], [[TMP2]] +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[I]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP0]], [[TMP1]] // CHECK-NEXT: [[CMP_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[CMP]], i1 false) // CHECK-NEXT: br i1 [[CMP_EXPVAL]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] // CHECK: for.cond.cleanup: -// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR4]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR3]] // CHECK-NEXT: br label [[FOR_END:%.*]] // CHECK: for.body: // CHECK-NEXT: br label [[FOR_INC:%.*]] // CHECK: for.inc: -// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]] -// CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1 // CHECK-NEXT: store i32 [[INC]], ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]] // CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP12:![0-9]+]] // CHECK: for.end: @@ -146,42 +146,42 @@ void f_branch_elided() // CHECK-NEXT: [[__END1:%.*]] = alloca ptr, align 8 // CHECK-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK-NEXT: store ptr [[E:%.*]], ptr [[E_ADDR]], align 8, !tbaa [[TBAA14:![0-9]+]] -// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[__RANGE1]]) #[[ATTR4]] -// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[E_ADDR]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: store ptr [[TMP1]], ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[__BEGIN1]]) #[[ATTR4]] -// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP3]], i64 0, i64 0 -// CHECK-NEXT: store ptr [[ARRAYDECAY]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[__END1]]) #[[ATTR4]] -// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP5]], i64 0, i64 0 +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[__RANGE1]]) #[[ATTR3]] +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[E_ADDR]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: store ptr [[TMP0]], ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[__BEGIN1]]) #[[ATTR3]] +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP1]], i64 0, i64 0 +// CHECK-NEXT: store ptr [[ARRAYDECAY]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16:![0-9]+]] +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[__END1]]) #[[ATTR3]] +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP2]], i64 0, i64 0 // CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY1]], i64 4 -// CHECK-NEXT: store ptr [[ADD_PTR]], ptr [[__END1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: store ptr [[ADD_PTR]], ptr [[__END1]], align 8, !tbaa [[TBAA16]] // CHECK-NEXT: br label [[FOR_COND:%.*]] // CHECK: for.cond: -// CHECK-NEXT: [[TMP6:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: [[TMP7:%.*]] = load ptr, ptr [[__END1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[TMP6]], [[TMP7]] +// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[__END1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[TMP3]], [[TMP4]] // CHECK-NEXT: [[CMP_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[CMP]], i1 true) // CHECK-NEXT: br i1 [[CMP_EXPVAL]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] // CHECK: for.cond.cleanup: -// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[__END1]]) #[[ATTR4]] -// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[__BEGIN1]]) #[[ATTR4]] -// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[__RANGE1]]) #[[ATTR4]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[__END1]]) #[[ATTR3]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[__BEGIN1]]) #[[ATTR3]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[__RANGE1]]) #[[ATTR3]] // CHECK-NEXT: br label [[FOR_END:%.*]] // CHECK: for.body: -// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR4]] -// CHECK-NEXT: [[TMP12:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4, !tbaa [[TBAA2]] -// CHECK-NEXT: store i32 [[TMP13]], ptr [[I]], align 4, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR4]] +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR3]] +// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: store i32 [[TMP6]], ptr [[I]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR3]] // CHECK-NEXT: br label [[FOR_INC:%.*]] // CHECK: for.inc: -// CHECK-NEXT: [[TMP15:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP15]], i32 1 -// CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP16:![0-9]+]] +// CHECK-NEXT: [[TMP7:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP7]], i32 1 +// CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP18:![0-9]+]] // CHECK: for.end: // CHECK-NEXT: ret void // @@ -198,42 +198,42 @@ void frl(int (&&e) [4]) // CHECK-NEXT: [[__END1:%.*]] = alloca ptr, align 8 // CHECK-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK-NEXT: store ptr [[E:%.*]], ptr [[E_ADDR]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[__RANGE1]]) #[[ATTR4]] -// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[E_ADDR]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: store ptr [[TMP1]], ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[__BEGIN1]]) #[[ATTR4]] -// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP3]], i64 0, i64 0 -// CHECK-NEXT: store ptr [[ARRAYDECAY]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[__END1]]) #[[ATTR4]] -// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP5]], i64 0, i64 0 +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[__RANGE1]]) #[[ATTR3]] +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[E_ADDR]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: store ptr [[TMP0]], ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[__BEGIN1]]) #[[ATTR3]] +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP1]], i64 0, i64 0 +// CHECK-NEXT: store ptr [[ARRAYDECAY]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[__END1]]) #[[ATTR3]] +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP2]], i64 0, i64 0 // CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY1]], i64 4 -// CHECK-NEXT: store ptr [[ADD_PTR]], ptr [[__END1]], align 8, !tbaa [[TBAA14]] +// CHECK-NEXT: store ptr [[ADD_PTR]], ptr [[__END1]], align 8, !tbaa [[TBAA16]] // CHECK-NEXT: br label [[FOR_COND:%.*]] // CHECK: for.cond: -// CHECK-NEXT: [[TMP6:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: [[TMP7:%.*]] = load ptr, ptr [[__END1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[TMP6]], [[TMP7]] +// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[__END1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[TMP3]], [[TMP4]] // CHECK-NEXT: [[CMP_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[CMP]], i1 false) // CHECK-NEXT: br i1 [[CMP_EXPVAL]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] // CHECK: for.cond.cleanup: -// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[__END1]]) #[[ATTR4]] -// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[__BEGIN1]]) #[[ATTR4]] -// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[__RANGE1]]) #[[ATTR4]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[__END1]]) #[[ATTR3]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[__BEGIN1]]) #[[ATTR3]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[__RANGE1]]) #[[ATTR3]] // CHECK-NEXT: br label [[FOR_END:%.*]] // CHECK: for.body: -// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR4]] -// CHECK-NEXT: [[TMP12:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4, !tbaa [[TBAA2]] -// CHECK-NEXT: store i32 [[TMP13]], ptr [[I]], align 4, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR4]] +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR3]] +// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: store i32 [[TMP6]], ptr [[I]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR3]] // CHECK-NEXT: br label [[FOR_INC:%.*]] // CHECK: for.inc: -// CHECK-NEXT: [[TMP15:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP15]], i32 1 -// CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]] -// CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP17:![0-9]+]] +// CHECK-NEXT: [[TMP7:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP7]], i32 1 +// CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA16]] +// CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP19:![0-9]+]] // CHECK: for.end: // CHECK-NEXT: ret void // diff --git a/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp b/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp index 29ae6b6856500..6405621a9d647 100644 --- a/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp +++ b/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp @@ -1,4 +1,4 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals --include-generated-funcs +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --include-generated-funcs --version 5 // RUN: %clang_cc1 -std=c++11 -triple aarch64-linux-gnu -emit-llvm %s -o - | FileCheck %s int __attribute__((target_clones("ls64_v+fp16", "default"))) foo_ovl(int) { return 1; } @@ -45,56 +45,60 @@ void run_foo_tml() { // CHECK: @_ZN7MyClassIssE7foo_tmlEv = weak_odr ifunc i32 (ptr), ptr @_ZN7MyClassIssE7foo_tmlEv.resolver // CHECK: @_ZN7MyClassIisE7foo_tmlEv = weak_odr ifunc i32 (ptr), ptr @_ZN7MyClassIisE7foo_tmlEv.resolver //. -// CHECK-LABEL: @_Z7foo_ovli._Mfp16Mls64_v( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_Z7foo_ovli._Mfp16Mls64_v( +// CHECK-SAME: i32 noundef [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: store i32 [[TMP0]], ptr [[DOTADDR]], align 4 // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: @_Z7foo_ovli.resolver( -// CHECK-NEXT: resolver_entry: +// CHECK-LABEL: define weak_odr ptr @_Z7foo_ovli.resolver() comdat { +// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4503599627436032 // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4503599627436032 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: +// CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] +// CHECK: [[RESOLVER_RETURN]]: // CHECK-NEXT: ret ptr @_Z7foo_ovli._Mfp16Mls64_v -// CHECK: resolver_else: +// CHECK: [[RESOLVER_ELSE]]: // CHECK-NEXT: ret ptr @_Z7foo_ovli.default // // -// CHECK-LABEL: @_Z7foo_ovlv._Mls64Mls64_accdata( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_Z7foo_ovlv._Mls64Mls64_accdata( +// CHECK-SAME: ) #[[ATTR1:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: @_Z7foo_ovlv.resolver( -// CHECK-NEXT: resolver_entry: +// CHECK-LABEL: define weak_odr ptr @_Z7foo_ovlv.resolver() comdat { +// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 11258999068426240 // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 11258999068426240 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: +// CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] +// CHECK: [[RESOLVER_RETURN]]: // CHECK-NEXT: ret ptr @_Z7foo_ovlv._Mls64Mls64_accdata -// CHECK: resolver_else: +// CHECK: [[RESOLVER_ELSE]]: // CHECK-NEXT: ret ptr @_Z7foo_ovlv.default // // -// CHECK-LABEL: @_Z3barv( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_Z3barv( +// CHECK-SAME: ) #[[ATTR2:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_Z7foo_ovli(i32 noundef 1) // CHECK-NEXT: [[CALL1:%.*]] = call noundef i32 @_Z7foo_ovlv() // CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] // CHECK-NEXT: ret i32 [[ADD]] // // -// CHECK-LABEL: @_Z11run_foo_tmlv( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local void @_Z11run_foo_tmlv( +// CHECK-SAME: ) #[[ATTR2]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[MC1:%.*]] = alloca [[STRUCT_MYCLASS:%.*]], align 1 // CHECK-NEXT: [[MC2:%.*]] = alloca [[STRUCT_MYCLASS_0:%.*]], align 1 // CHECK-NEXT: [[MC3:%.*]] = alloca [[STRUCT_MYCLASS_1:%.*]], align 1 @@ -106,131 +110,141 @@ void run_foo_tml() { // CHECK-NEXT: ret void // // -// CHECK-LABEL: @_ZN7MyClassIssE7foo_tmlEv.resolver( -// 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]], 36310271995674624 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 36310271995674624 -// 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: [[TMP7:%.*]] = and i1 true, [[TMP6]] -// CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] -// CHECK: resolver_return1: -// CHECK-NEXT: ret ptr @_ZN7MyClassIssE7foo_tmlEv._Mfrintts -// CHECK: resolver_else2: -// CHECK-NEXT: ret ptr @_ZN7MyClassIssE7foo_tmlEv.default -// -// -// CHECK-LABEL: @_ZN7MyClassIisE7foo_tmlEv.resolver( -// 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]], 36310271995674624 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 36310271995674624 -// 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: [[TMP7:%.*]] = and i1 true, [[TMP6]] -// CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] -// CHECK: resolver_return1: -// CHECK-NEXT: ret ptr @_ZN7MyClassIisE7foo_tmlEv._Mfrintts -// CHECK: resolver_else2: -// CHECK-NEXT: ret ptr @_ZN7MyClassIisE7foo_tmlEv.default -// -// -// CHECK-LABEL: @_ZN7MyClassIfsE7foo_tmlEv( -// CHECK-NEXT: entry: +// CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIfsE7foo_tmlEv( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR2]] comdat { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 3 // // -// CHECK-LABEL: @_ZN7MyClassIdfE7foo_tmlEv( -// CHECK-NEXT: entry: +// CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIdfE7foo_tmlEv( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR2]] comdat { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 4 // // -// CHECK-LABEL: @_Z7foo_ovli.default( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_Z7foo_ovli.default( +// CHECK-SAME: i32 noundef [[TMP0:%.*]]) #[[ATTR2]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: store i32 [[TMP0]], ptr [[DOTADDR]], align 4 // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: @_Z7foo_ovlv.default( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_Z7foo_ovlv.default( +// CHECK-SAME: ) #[[ATTR2]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: @_ZN7MyClassIssE7foo_tmlEv._Mfrintts( -// CHECK-NEXT: entry: +// CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIssE7foo_tmlEv._Mfrintts( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR3:[0-9]+]] comdat { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: @_ZN7MyClassIssE7foo_tmlEv._Msme-f64f64Mssbs( -// CHECK-NEXT: entry: +// CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIssE7foo_tmlEv._Msme-f64f64Mssbs( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR4:[0-9]+]] comdat { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: @_ZN7MyClassIssE7foo_tmlEv.default( -// CHECK-NEXT: entry: +// CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIssE7foo_tmlEv.default( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR2]] comdat { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: @_ZN7MyClassIisE7foo_tmlEv._Mfrintts( -// CHECK-NEXT: entry: +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClassIssE7foo_tmlEv.resolver() comdat { +// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 36310271995674624 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 36310271995674624 +// 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: [[TMP7:%.*]] = and i1 true, [[TMP6]] +// CHECK-NEXT: br i1 [[TMP7]], label %[[RESOLVER_RETURN1:.*]], label %[[RESOLVER_ELSE2:.*]] +// CHECK: [[RESOLVER_RETURN1]]: +// CHECK-NEXT: ret ptr @_ZN7MyClassIssE7foo_tmlEv._Mfrintts +// CHECK: [[RESOLVER_ELSE2]]: +// CHECK-NEXT: ret ptr @_ZN7MyClassIssE7foo_tmlEv.default +// +// +// CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIisE7foo_tmlEv._Mfrintts( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR3]] comdat { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: @_ZN7MyClassIisE7foo_tmlEv._Msme-f64f64Mssbs( -// CHECK-NEXT: entry: +// CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIisE7foo_tmlEv._Msme-f64f64Mssbs( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR4]] comdat { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: @_ZN7MyClassIisE7foo_tmlEv.default( -// CHECK-NEXT: entry: +// CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIisE7foo_tmlEv.default( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR2]] comdat { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 2 // +// +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClassIisE7foo_tmlEv.resolver() comdat { +// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 36310271995674624 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 36310271995674624 +// 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: [[TMP7:%.*]] = and i1 true, [[TMP6]] +// CHECK-NEXT: br i1 [[TMP7]], label %[[RESOLVER_RETURN1:.*]], label %[[RESOLVER_ELSE2:.*]] +// CHECK: [[RESOLVER_RETURN1]]: +// CHECK-NEXT: ret ptr @_ZN7MyClassIisE7foo_tmlEv._Mfrintts +// CHECK: [[RESOLVER_ELSE2]]: +// CHECK-NEXT: ret ptr @_ZN7MyClassIisE7foo_tmlEv.default +// //. -// CHECK: attributes #[[ATTR0:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon" } -// CHECK: attributes #[[ATTR1:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ls64" } -// CHECK: attributes #[[ATTR2:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } -// CHECK: attributes #[[ATTR3:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fptoint" } -// CHECK: attributes #[[ATTR4:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme-f64f64" } +// CHECK: attributes #[[ATTR0]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon" } +// CHECK: attributes #[[ATTR1]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ls64" } +// CHECK: attributes #[[ATTR2]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// CHECK: attributes #[[ATTR3]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fptoint" } +// CHECK: attributes #[[ATTR4]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme-f64f64" } //. // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} diff --git a/clang/test/CodeGenCXX/attr-target-version.cpp b/clang/test/CodeGenCXX/attr-target-version.cpp index fd19f4c5a3030..6661abead20c6 100644 --- a/clang/test/CodeGenCXX/attr-target-version.cpp +++ b/clang/test/CodeGenCXX/attr-target-version.cpp @@ -1,4 +1,4 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals --include-generated-funcs +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --include-generated-funcs --version 5 // RUN: %clang_cc1 -std=c++11 -triple aarch64-linux-gnu -emit-llvm %s -o - | FileCheck %s int __attribute__((target_version("sme-f64f64+bf16"))) foo(int) { return 1; } @@ -59,152 +59,169 @@ int bar() { return m.goo(1) + foo(1) + foo(); } - //. // CHECK: @__aarch64_cpu_features = external dso_local global { i64 } -// CHECK: @_ZN7MyClass3gooEi = weak_odr ifunc i32 (ptr, i32), ptr @_ZN7MyClass3gooEi.resolver // CHECK: @_Z3fooi = weak_odr ifunc i32 (i32), ptr @_Z3fooi.resolver // CHECK: @_Z3foov = weak_odr ifunc i32 (), ptr @_Z3foov.resolver +// CHECK: @_ZN7MyClass3gooEi = weak_odr ifunc i32 (ptr, i32), ptr @_ZN7MyClass3gooEi.resolver // CHECK: @_ZN7MyClass23unused_with_default_defEv = weak_odr ifunc i32 (ptr), ptr @_ZN7MyClass23unused_with_default_defEv.resolver // CHECK: @_ZN7MyClass32unused_with_implicit_default_defEv = weak_odr ifunc i32 (ptr), ptr @_ZN7MyClass32unused_with_implicit_default_defEv.resolver // CHECK: @_ZN7MyClass40unused_with_implicit_forward_default_defEv = weak_odr ifunc i32 (ptr), ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv.resolver //. -// CHECK-LABEL: @_Z3fooi._Mbf16Msme-f64f64( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_Z3fooi._Mbf16Msme-f64f64( +// CHECK-SAME: i32 noundef [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: store i32 [[TMP0]], ptr [[DOTADDR]], align 4 // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: @_Z3fooi.default( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_Z3fooi.default( +// CHECK-SAME: i32 noundef [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: store i32 [[TMP0]], ptr [[DOTADDR]], align 4 // CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: @_Z3foov._Mebf16Msm4( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_Z3foov._Mebf16Msm4( +// CHECK-SAME: ) #[[ATTR2:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: ret i32 3 // // -// CHECK-LABEL: @_Z3foov.default( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_Z3foov.default( +// CHECK-SAME: ) #[[ATTR1]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: ret i32 4 // // -// CHECK-LABEL: @_ZN7MyClass3gooEi.default( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_ZN7MyClass3gooEi.default( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]], i32 noundef [[TMP0:%.*]]) #[[ATTR1]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store i32 [[TMP0]], ptr [[DOTADDR]], align 4 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: @_ZN7MyClass3gooEi._Mcrc( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_ZN7MyClass3gooEi._Mcrc( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]], i32 noundef [[TMP0:%.*]]) #[[ATTR3:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store i32 [[TMP0]], ptr [[DOTADDR]], align 4 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: @_ZN7MyClass3gooEi._Mdotprod( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_ZN7MyClass3gooEi._Mdotprod( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]], i32 noundef [[TMP0:%.*]]) #[[ATTR4:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store i32 [[TMP0]], ptr [[DOTADDR]], align 4 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 3 // // -// CHECK-LABEL: @_ZN7MyClass32unused_with_forward_default_declEv._Mmops( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_ZN7MyClass32unused_with_forward_default_declEv._Mmops( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR5:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 0 // // -// CHECK-LABEL: @_ZN7MyClass41unused_with_implicit_forward_default_declEv._Mdotprod( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_ZN7MyClass41unused_with_implicit_forward_default_declEv._Mdotprod( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR4]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 0 // // -// CHECK-LABEL: @_ZN7MyClass24unused_with_default_declEv._Maes( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_ZN7MyClass24unused_with_default_declEv._Maes( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR6:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 0 // // -// CHECK-LABEL: @_ZN7MyClass23unused_with_default_defEv._Msve( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_ZN7MyClass23unused_with_default_defEv._Msve( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR7:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 0 // // -// CHECK-LABEL: @_ZN7MyClass23unused_with_default_defEv.default( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_ZN7MyClass23unused_with_default_defEv.default( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR1]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: @_ZN7MyClass32unused_with_implicit_default_defEv._Mfp16( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_ZN7MyClass32unused_with_implicit_default_defEv._Mfp16( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR8:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 0 // // -// CHECK-LABEL: @_ZN7MyClass32unused_with_implicit_default_defEv.default( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_ZN7MyClass32unused_with_implicit_default_defEv.default( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR1]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: @_ZN7MyClass40unused_with_implicit_forward_default_defEv.default( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_ZN7MyClass40unused_with_implicit_forward_default_defEv.default( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR1]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 0 // // -// CHECK-LABEL: @_ZN7MyClass40unused_with_implicit_forward_default_defEv._Mlse( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_ZN7MyClass40unused_with_implicit_forward_default_defEv._Mlse( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR9:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: @_ZN7MyClass22unused_without_defaultEv._Mrdm( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_ZN7MyClass22unused_without_defaultEv._Mrdm( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR10:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 0 // // -// CHECK-LABEL: @_Z3barv( -// CHECK-NEXT: entry: +// CHECK-LABEL: define dso_local noundef i32 @_Z3barv( +// CHECK-SAME: ) #[[ATTR1]] { +// CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[M:%.*]] = alloca [[STRUCT_MYCLASS:%.*]], align 1 // CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN7MyClass3gooEi(ptr noundef nonnull align 1 dereferenceable(1) [[M]], i32 noundef 1) // CHECK-NEXT: [[CALL1:%.*]] = call noundef i32 @_Z3fooi(i32 noundef 1) @@ -214,109 +231,109 @@ int bar() { // CHECK-NEXT: ret i32 [[ADD3]] // // -// CHECK-LABEL: @_ZN7MyClass3gooEi.resolver( -// 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]], 1024 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1024 -// 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 @_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: [[TMP7:%.*]] = and i1 true, [[TMP6]] -// CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] -// CHECK: resolver_return1: -// CHECK-NEXT: ret ptr @_ZN7MyClass3gooEi._Mdotprod -// CHECK: resolver_else2: -// CHECK-NEXT: ret ptr @_ZN7MyClass3gooEi.default -// -// -// CHECK-LABEL: @_Z3fooi.resolver( -// CHECK-NEXT: resolver_entry: +// CHECK-LABEL: define weak_odr ptr @_Z3fooi.resolver() comdat { +// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 36028797153181696 // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 36028797153181696 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: +// CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] +// CHECK: [[RESOLVER_RETURN]]: // CHECK-NEXT: ret ptr @_Z3fooi._Mbf16Msme-f64f64 -// CHECK: resolver_else: +// CHECK: [[RESOLVER_ELSE]]: // CHECK-NEXT: ret ptr @_Z3fooi.default // // -// CHECK-LABEL: @_Z3foov.resolver( -// CHECK-NEXT: resolver_entry: +// CHECK-LABEL: define weak_odr ptr @_Z3foov.resolver() comdat { +// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 268435488 // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 268435488 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: +// CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] +// CHECK: [[RESOLVER_RETURN]]: // CHECK-NEXT: ret ptr @_Z3foov._Mebf16Msm4 -// CHECK: resolver_else: +// CHECK: [[RESOLVER_ELSE]]: // CHECK-NEXT: ret ptr @_Z3foov.default // // -// CHECK-LABEL: @_ZN7MyClass23unused_with_default_defEv.resolver( -// CHECK-NEXT: resolver_entry: +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass3gooEi.resolver() comdat { +// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1024 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1024 +// 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 @_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: [[TMP7:%.*]] = and i1 true, [[TMP6]] +// CHECK-NEXT: br i1 [[TMP7]], label %[[RESOLVER_RETURN1:.*]], label %[[RESOLVER_ELSE2:.*]] +// CHECK: [[RESOLVER_RETURN1]]: +// CHECK-NEXT: ret ptr @_ZN7MyClass3gooEi._Mdotprod +// CHECK: [[RESOLVER_ELSE2]]: +// CHECK-NEXT: ret ptr @_ZN7MyClass3gooEi.default +// +// +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass23unused_with_default_defEv.resolver() comdat { +// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073741824 // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073741824 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: +// CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] +// CHECK: [[RESOLVER_RETURN]]: // CHECK-NEXT: ret ptr @_ZN7MyClass23unused_with_default_defEv._Msve -// CHECK: resolver_else: +// CHECK: [[RESOLVER_ELSE]]: // CHECK-NEXT: ret ptr @_ZN7MyClass23unused_with_default_defEv.default // // -// CHECK-LABEL: @_ZN7MyClass32unused_with_implicit_default_defEv.resolver( -// CHECK-NEXT: resolver_entry: +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass32unused_with_implicit_default_defEv.resolver() comdat { +// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 65536 // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 65536 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: +// CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] +// CHECK: [[RESOLVER_RETURN]]: // CHECK-NEXT: ret ptr @_ZN7MyClass32unused_with_implicit_default_defEv._Mfp16 -// CHECK: resolver_else: +// CHECK: [[RESOLVER_ELSE]]: // CHECK-NEXT: ret ptr @_ZN7MyClass32unused_with_implicit_default_defEv.default // // -// CHECK-LABEL: @_ZN7MyClass40unused_with_implicit_forward_default_defEv.resolver( -// CHECK-NEXT: resolver_entry: +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv.resolver() comdat { +// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 128 // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 128 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: +// CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] +// CHECK: [[RESOLVER_RETURN]]: // CHECK-NEXT: ret ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv._Mlse -// CHECK: resolver_else: +// CHECK: [[RESOLVER_ELSE]]: // CHECK-NEXT: ret ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv.default // //. -// CHECK: attributes #[[ATTR0:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme-f64f64" } -// CHECK: attributes #[[ATTR1:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } -// CHECK: attributes #[[ATTR2:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+neon,+sm4" } -// CHECK: attributes #[[ATTR3:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc" } -// CHECK: attributes #[[ATTR4:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon" } -// CHECK: attributes #[[ATTR5:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops" } -// CHECK: attributes #[[ATTR6:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon" } -// CHECK: attributes #[[ATTR7:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" } -// CHECK: attributes #[[ATTR8:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon" } -// CHECK: attributes #[[ATTR9:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse" } -// CHECK: attributes #[[ATTR10:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rdm" } +// CHECK: attributes #[[ATTR0]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme-f64f64" } +// CHECK: attributes #[[ATTR1]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// CHECK: attributes #[[ATTR2]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+neon,+sm4" } +// CHECK: attributes #[[ATTR3]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc" } +// CHECK: attributes #[[ATTR4]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon" } +// CHECK: attributes #[[ATTR5]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops" } +// CHECK: attributes #[[ATTR6]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon" } +// CHECK: attributes #[[ATTR7]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" } +// CHECK: attributes #[[ATTR8]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon" } +// CHECK: attributes #[[ATTR9]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse" } +// CHECK: attributes #[[ATTR10]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rdm" } // CHECK: attributes #[[ATTR11:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" } //. // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} diff --git a/clang/test/CodeGenCXX/cxx2a-consteval.cpp b/clang/test/CodeGenCXX/cxx2a-consteval.cpp index 075cab58358ab..6c09053a74d24 100644 --- a/clang/test/CodeGenCXX/cxx2a-consteval.cpp +++ b/clang/test/CodeGenCXX/cxx2a-consteval.cpp @@ -1,4 +1,3 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -emit-llvm %s -std=c++2a -triple x86_64-unknown-linux-gnu -o %t.ll // RUN: FileCheck -check-prefix=EVAL -input-file=%t.ll %s // RUN: FileCheck -check-prefix=EVAL-STATIC -input-file=%t.ll %s @@ -275,3 +274,26 @@ void f() { // EVAL-FN: call void @_ZN7GH821542S3C2Ei } } + +namespace GH93040 { +struct C { char c = 1; }; +struct Empty { consteval Empty() {} }; +struct Empty2 { consteval Empty2() {} }; +struct Test : C, Empty { + [[no_unique_address]] Empty2 e; +}; +static_assert(sizeof(Test) == 1); +void f() { + Test test; + +// Make sure we don't overwrite the initialization of c. + +// EVAL-FN-LABEL: define {{.*}} void @_ZN7GH930404TestC2Ev +// EVAL-FN: entry: +// EVAL-FN-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// EVAL-FN-NEXT: store ptr {{.*}}, ptr [[THIS_ADDR]], align 8 +// EVAL-FN-NEXT: [[THIS:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// EVAL-FN-NEXT: call void @_ZN7GH930401CC2Ev(ptr noundef nonnull align 1 dereferenceable(1) [[THIS]]) +// EVAL-FN-NEXT: ret void +} +} diff --git a/clang/test/CodeGenCXX/debug-info-explicit-this.cpp b/clang/test/CodeGenCXX/debug-info-explicit-this.cpp new file mode 100644 index 0000000000000..45ab2a0216ca7 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-explicit-this.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -std=c++2b %s -o - | FileCheck %s + +struct Foo { + void Bar(this Foo&& self) {} +}; + +void fn() { + Foo{}.Bar(); +} + +// CHECK: distinct !DISubprogram(name: "Bar", {{.*}}, type: ![[BAR_TYPE:[0-9]+]], {{.*}}, declaration: ![[BAR_DECL:[0-9]+]], {{.*}} +// CHECK: ![[FOO:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo" +// CHECK: ![[BAR_DECL]] = !DISubprogram(name: "Bar", {{.*}}, type: ![[BAR_TYPE]], {{.*}}, +// CHECK: ![[BAR_TYPE]] = !DISubroutineType(types: ![[PARAMS:[0-9]+]]) +// CHECK: ![[PARAMS]] = !{null, ![[SELF:[0-9]+]]} +// CHECK: ![[SELF]] = !DIDerivedType(tag: DW_TAG_rvalue_reference_type, baseType: ![[FOO]] diff --git a/clang/test/CodeGenCXX/fmv-namespace.cpp b/clang/test/CodeGenCXX/fmv-namespace.cpp index abfff1a74f86a..1ac88e68a3a12 100644 --- a/clang/test/CodeGenCXX/fmv-namespace.cpp +++ b/clang/test/CodeGenCXX/fmv-namespace.cpp @@ -26,7 +26,6 @@ __attribute((target_version("mops"))) int bar() { return 1; } //. // CHECK: @__aarch64_cpu_features = external dso_local global { i64 } // CHECK: @_ZN4Name3fooEv = weak_odr ifunc i32 (), ptr @_ZN4Name3fooEv.resolver -// CHECK: @_ZN9OtherName3fooEv = weak_odr ifunc i32 (), ptr @_ZN9OtherName3fooEv.resolver // CHECK: @_ZN3Foo3barEv = weak_odr ifunc i32 (), ptr @_ZN3Foo3barEv.resolver //. // CHECK-LABEL: define dso_local noundef i32 @_ZN4Name3fooEv._Msve( @@ -42,20 +41,6 @@ __attribute((target_version("mops"))) int bar() { return 1; } // CHECK-NEXT: ret i32 [[CALL]] // // -// CHECK-LABEL: define weak_odr ptr @_ZN4Name3fooEv.resolver() comdat { -// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073741824 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073741824 -// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] -// CHECK: [[RESOLVER_RETURN]]: -// CHECK-NEXT: ret ptr @_ZN4Name3fooEv._Msve -// CHECK: [[RESOLVER_ELSE]]: -// CHECK-NEXT: ret ptr @_ZN4Name3fooEv.default -// -// // CHECK-LABEL: define dso_local noundef i32 @_ZN9OtherName3fooEv._Msve( // CHECK-SAME: ) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] @@ -69,20 +54,6 @@ __attribute((target_version("mops"))) int bar() { return 1; } // CHECK-NEXT: ret i32 [[CALL]] // // -// CHECK-LABEL: define weak_odr ptr @_ZN9OtherName3fooEv.resolver() comdat { -// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073741824 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073741824 -// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] -// CHECK: [[RESOLVER_RETURN]]: -// CHECK-NEXT: ret ptr @_ZN9OtherName3fooEv._Msve -// CHECK: [[RESOLVER_ELSE]]: -// CHECK-NEXT: ret ptr @_ZN9OtherName3fooEv.default -// -// // CHECK-LABEL: define dso_local noundef i32 @_ZN3Foo3barEv.default( // CHECK-SAME: ) #[[ATTR1]] { // CHECK-NEXT: [[ENTRY:.*:]] @@ -90,7 +61,7 @@ __attribute((target_version("mops"))) int bar() { return 1; } // // // CHECK-LABEL: define dso_local noundef i32 @_ZN3Foo3barEv._Mmops( -// CHECK-SAME: ) #[[ATTR2:[0-9]+]] { +// CHECK-SAME: ) #[[ATTR3:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: ret i32 1 // @@ -101,6 +72,20 @@ __attribute((target_version("mops"))) int bar() { return 1; } // CHECK-NEXT: ret i32 0 // // +// CHECK-LABEL: define weak_odr ptr @_ZN4Name3fooEv.resolver() comdat { +// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073741824 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073741824 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] +// CHECK: [[RESOLVER_RETURN]]: +// CHECK-NEXT: ret ptr @_ZN4Name3fooEv._Msve +// CHECK: [[RESOLVER_ELSE]]: +// CHECK-NEXT: ret ptr @_ZN4Name3fooEv.default +// +// // CHECK-LABEL: define weak_odr ptr @_ZN3Foo3barEv.resolver() comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() @@ -117,8 +102,8 @@ __attribute((target_version("mops"))) int bar() { return 1; } //. // CHECK: attributes #[[ATTR0]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" } // CHECK: attributes #[[ATTR1]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } -// CHECK: attributes #[[ATTR2]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops" } -// CHECK: attributes #[[ATTR3:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// CHECK: attributes #[[ATTR2:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" } +// CHECK: attributes #[[ATTR3]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops" } //. // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} diff --git a/clang/test/CodeGenCXX/mangle-fail.cpp b/clang/test/CodeGenCXX/mangle-fail.cpp index b588d57749fa3..f3b50cfb54dbd 100644 --- a/clang/test/CodeGenCXX/mangle-fail.cpp +++ b/clang/test/CodeGenCXX/mangle-fail.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=1 // RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=2 +// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-intrinsics -verify %s -DN=3 struct A { int a; }; @@ -13,6 +14,19 @@ template void test(int (&)[sizeof(int)]); template void test(int (&)[sizeof((A){}, T())]) {} // expected-error {{cannot yet mangle}} template void test(int (&)[sizeof(A)]); +#elif N == 3 +// __builtin_ptrauth_type_discriminator +template +struct S1 {}; + +template +void func(S1 s1) { // expected-error {{cannot yet mangle __builtin_ptrauth_type_discriminator expression}} +} + +void testfunc1() { + func(S1()); +} + // FIXME: There are several more cases we can't yet mangle. #else diff --git a/clang/test/CodeGenCXX/ptrauth-explicit-vtable-pointer-control.cpp b/clang/test/CodeGenCXX/ptrauth-explicit-vtable-pointer-control.cpp index e6497b3f152aa..1b103719fbe46 100644 --- a/clang/test/CodeGenCXX/ptrauth-explicit-vtable-pointer-control.cpp +++ b/clang/test/CodeGenCXX/ptrauth-explicit-vtable-pointer-control.cpp @@ -1,15 +1,31 @@ // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \ // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,NODISC %s -// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \ +// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \ // RUN: -fptrauth-vtable-pointer-type-discrimination \ // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,TYPE %s -// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \ +// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \ // RUN: -fptrauth-vtable-pointer-address-discrimination \ // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,ADDR %s -// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \ +// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -fptrauth-vtable-pointer-address-discrimination \ +// RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,BOTH %s + +// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,NODISC %s + +// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,TYPE %s + +// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -fptrauth-vtable-pointer-address-discrimination \ +// RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,ADDR %s + +// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ // RUN: -fptrauth-vtable-pointer-type-discrimination \ // RUN: -fptrauth-vtable-pointer-address-discrimination \ // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,BOTH %s @@ -111,7 +127,7 @@ int TVDisc_ExplicitNoExtraDiscrimination = ptrauth_string_discriminator("_ZTVN5t int TVDisc_ExplicitTypeDiscrimination = ptrauth_string_discriminator("_ZTVN5test126ExplicitTypeDiscriminationE"); -// CHECK-LABEL: define void @test_default(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_default(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // @@ -133,7 +149,7 @@ void test_default(NoExplicitAuth *a) { a->f(); } -// CHECK-LABEL: define void @test_disabled(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_disabled(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // CHECK-NOT: call i64 @llvm.ptrauth.auth @@ -141,7 +157,7 @@ void test_disabled(ExplicitlyDisableAuth *a) { a->f(); } -// CHECK-LABEL: define void @test_addr_disc(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_addr_disc(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // @@ -166,7 +182,7 @@ void test_addr_disc(ExplicitAddressDiscrimination *a) { a->f(); } -// CHECK-LABEL: define void @test_no_addr_disc(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_no_addr_disc(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // @@ -185,7 +201,7 @@ void test_no_addr_disc(ExplicitNoAddressDiscrimination *a) { a->f(); } -// CHECK-LABEL: define void @test_no_extra_disc(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_no_extra_disc(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // @@ -206,7 +222,7 @@ void test_no_extra_disc(ExplicitNoExtraDiscrimination *a) { a->f(); } -// CHECK-LABEL: define void @test_type_disc(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_type_disc(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // @@ -229,7 +245,7 @@ void test_type_disc(ExplicitTypeDiscrimination *a) { a->f(); } -// CHECK-LABEL: define void @test_custom_disc(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_custom_disc(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // @@ -257,7 +273,7 @@ void test_custom_disc(ExplicitCustomDiscrimination *a) { // Codegen should be the same as the simple cases above once we have a vtable. // -// CHECK-LABEL: define void @test_subclass_default(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_subclass_default(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // @@ -279,7 +295,7 @@ void test_subclass_default(NoExplicitAuth *a) { make_subclass(a)->f(); } -// CHECK-LABEL: define void @test_subclass_disabled(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_subclass_disabled(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // CHECK-NOT: call i64 @llvm.ptrauth.auth @@ -287,7 +303,7 @@ void test_subclass_disabled(ExplicitlyDisableAuth *a) { make_subclass(a)->f(); } -// CHECK-LABEL: define void @test_subclass_addr_disc(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_subclass_addr_disc(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // @@ -312,7 +328,7 @@ void test_subclass_addr_disc(ExplicitAddressDiscrimination *a) { make_subclass(a)->f(); } -// CHECK-LABEL: define void @test_subclass_no_addr_disc(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_subclass_no_addr_disc(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // @@ -331,7 +347,7 @@ void test_subclass_no_addr_disc(ExplicitNoAddressDiscrimination *a) { make_subclass(a)->f(); } -// CHECK-LABEL: define void @test_subclass_no_extra_disc(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_subclass_no_extra_disc(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // @@ -352,7 +368,7 @@ void test_subclass_no_extra_disc(ExplicitNoExtraDiscrimination *a) { make_subclass(a)->f(); } -// CHECK-LABEL: define void @test_subclass_type_disc(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_subclass_type_disc(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // @@ -375,7 +391,7 @@ void test_subclass_type_disc(ExplicitTypeDiscrimination *a) { make_subclass(a)->f(); } -// CHECK-LABEL: define void @test_subclass_custom_disc(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_subclass_custom_disc(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // @@ -404,7 +420,7 @@ void test_subclass_custom_disc(ExplicitCustomDiscrimination *a) { // Codegen should be the same as the simple cases above once we have a vtable. // -// CHECK-LABEL: define void @test_multiple_default(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_multiple_default(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[CALL:%.*]] = call noundef ptr @_ZN5test121make_multiple_primary // CHECK: [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 @@ -427,7 +443,7 @@ void test_multiple_default(NoExplicitAuth *a) { make_multiple_primary(a)->f(); } -// CHECK-LABEL: define void @test_multiple_disabled(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_multiple_disabled(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[CALL:%.*]] = call noundef ptr @_ZN5test121make_multiple_primary // CHECK: [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 @@ -436,7 +452,7 @@ void test_multiple_disabled(ExplicitlyDisableAuth *a) { make_multiple_primary(a)->f(); } -// CHECK-LABEL: define void @test_multiple_custom_disc(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_multiple_custom_disc(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[CALL:%.*]] = call noundef ptr @_ZN5test121make_multiple_primary // CHECK: [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 @@ -466,7 +482,7 @@ void test_multiple_custom_disc(ExplicitCustomDiscrimination *a) { // but twice for vtt/vtable. The names in the vtt version have "VTT" prefixes. // -// CHECK-LABEL: define void @test_virtual_default(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_virtual_default(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[VTTADDR:%.*]] = call noundef ptr @_ZN5test120make_virtual_primary // CHECK: [[VTTABLE:%.*]] = load ptr, ptr [[VTTADDR]], align 8 // @@ -509,13 +525,13 @@ void test_virtual_default(NoExplicitAuth *a) { make_virtual_primary(a)->f(); } -// CHECK-LABEL: define void @test_virtual_disabled(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_virtual_disabled(ptr noundef {{%.*}}) {{#.*}} { // CHECK-NOT: call i64 @llvm.ptrauth.auth void test_virtual_disabled(ExplicitlyDisableAuth *a) { make_virtual_primary(a)->f(); } -// CHECK-LABEL: define void @test_virtual_custom_disc(ptr noundef {{%.*}}) {{#.*}} { +// CHECK-LABEL: define{{.*}} void @test_virtual_custom_disc(ptr noundef {{%.*}}) {{#.*}} { // CHECK: [[VTTADDR:%.*]] = call noundef ptr @_ZN5test120make_virtual_primary // CHECK: [[VTTABLE:%.*]] = load ptr, ptr [[VTTADDR]], align 8 // diff --git a/clang/test/CodeGenCXX/ptrauth-global-constant-initializers.cpp b/clang/test/CodeGenCXX/ptrauth-global-constant-initializers.cpp new file mode 100644 index 0000000000000..9ce9def6156ef --- /dev/null +++ b/clang/test/CodeGenCXX/ptrauth-global-constant-initializers.cpp @@ -0,0 +1,245 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fno-rtti -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -fptrauth-vtable-pointer-address-discrimination -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,DARWIN +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fno-rtti -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -fptrauth-vtable-pointer-address-discrimination -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,ELF + +// CHECK: %struct.Base1 = type { ptr } +// CHECK: %struct.Base2 = type { ptr } +// CHECK: %struct.Derived1 = type { %struct.Base1, %struct.Base2 } +// CHECK: %struct.Derived2 = type { %struct.Base2, %struct.Base1 } +// CHECK: %struct.Derived3 = type { %struct.Base1, %struct.Base2 } + +// CHECK: @_ZTV5Base1 = linkonce_odr unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC:38871]], ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV5Base1, i32 0, i32 0, i32 2))] },{{.*}} align 8 +// CHECK: @g_b1 = global %struct.Base1 { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV5Base1, i32 0, i32 0, i32 2), i32 2, i64 [[BASE1_VTABLE_DISC:6511]], ptr @g_b1) },{{.*}} align 8 +// CHECK: @_ZTV5Base2 = linkonce_odr unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, i32 0, i64 [[BASE2_B_DISC:27651]], ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV5Base2, i32 0, i32 0, i32 2))] },{{.*}} align 8 +// CHECK: @g_b2 = global %struct.Base2 { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV5Base2, i32 0, i32 0, i32 2), i32 2, i64 [[BASE2_VTABLE_DISC:63631]], ptr @g_b2) },{{.*}} align 8 +// CHECK: @_ZTV8Derived1 = linkonce_odr unnamed_addr constant { [5 x ptr], [3 x ptr] } { [5 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 0, i32 2)), ptr ptrauth (ptr @_ZN8Derived11cEv, i32 0, i64 [[DERIVED1_C_DISC:54092]], ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 0, i32 3)), ptr ptrauth (ptr @_ZN8Derived11dEv, i32 0, i64 [[DERIVED1_D_DISC:37391]], ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 0, i32 4))], [3 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, i32 0, i64 [[BASE2_B_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 1, i32 2))] },{{.*}} align 8 +// CHECK: @g_d1 = global { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 24) ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 0, i32 2), i32 2, i64 [[BASE1_VTABLE_DISC]], ptr @g_d1), ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 1, i32 2), i32 2, i64 [[BASE2_VTABLE_DISC]], ptr getelementptr inbounds ({ ptr, ptr }, ptr @g_d1, i32 0, i32 1)) },{{.*}} align 8 +// CHECK: @_ZTV8Derived2 = linkonce_odr unnamed_addr constant { [5 x ptr], [3 x ptr] } { [5 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, i32 0, i64 [[BASE2_B_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 0, i32 2)), ptr ptrauth (ptr @_ZN8Derived21cEv, i32 0, i64 [[DERIVED2_C_DISC:15537]], ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 0, i32 3)), ptr ptrauth (ptr @_ZN8Derived21eEv, i32 0, i64 209, ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 0, i32 4))], [3 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 1, i32 2))] },{{.*}} align 8 +// CHECK: @g_d2 = global { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 24) ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 0, i32 2), i32 2, i64 [[BASE2_VTABLE_DISC]], ptr @g_d2), ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 1, i32 2), i32 2, i64 [[BASE1_VTABLE_DISC]], ptr getelementptr inbounds ({ ptr, ptr }, ptr @g_d2, i32 0, i32 1)) },{{.*}} align 8 +// CHECK: @_ZTV8Derived3 = linkonce_odr unnamed_addr constant { [4 x ptr], [3 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC]], ptr getelementptr inbounds ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV8Derived3, i32 0, i32 0, i32 2)), ptr ptrauth (ptr @_ZN8Derived31iEv, i32 0, i64 [[DERIVED3_I_DISC:19084]], ptr getelementptr inbounds ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV8Derived3, i32 0, i32 0, i32 3))], [3 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, i32 0, i64 [[BASE2_B_DISC]], ptr getelementptr inbounds ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV8Derived3, i32 0, i32 1, i32 2))] },{{.*}} align 8 +// CHECK: @g_d3 = global { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV8Derived3, i32 0, i32 0, i32 2), i32 2, i64 [[BASE1_VTABLE_DISC]], ptr @g_d3), ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV8Derived3, i32 0, i32 1, i32 2), i32 2, i64 [[BASE2_VTABLE_DISC]], ptr getelementptr inbounds ({ ptr, ptr }, ptr @g_d3, i32 0, i32 1)) },{{.*}} align 8 +// CHECK: @g_vb1 = global %struct.VirtualBase1 zeroinitializer,{{.*}} align 8 +// CHECK: @g_vb2 = global %struct.VirtualBase2 zeroinitializer,{{.*}} align 8 +// CHECK: @g_d4 = global %struct.Derived4 zeroinitializer,{{.*}} align 8 +// CHECK: @_ZTV12VirtualBase1 = linkonce_odr unnamed_addr constant { [6 x ptr] } { [6 x ptr] [ptr null, ptr null, ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC]], ptr getelementptr inbounds ({ [6 x ptr] }, ptr @_ZTV12VirtualBase1, i32 0, i32 0, i32 4)), ptr ptrauth (ptr @_ZN12VirtualBase11fEv, i32 0, i64 [[VIRTUALBASE1_F_DISC:7987]], ptr getelementptr inbounds ({ [6 x ptr] }, ptr @_ZTV12VirtualBase1, i32 0, i32 0, i32 5))] },{{.*}} align 8 +// CHECK: @_ZTT12VirtualBase1 = linkonce_odr unnamed_addr constant [2 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-32, 16) ({ [6 x ptr] }, ptr @_ZTV12VirtualBase1, i32 0, i32 0, i32 4), i32 2), ptr ptrauth (ptr getelementptr inbounds inrange(-32, 16) ({ [6 x ptr] }, ptr @_ZTV12VirtualBase1, i32 0, i32 0, i32 4), i32 2)],{{.*}} align 8 +// CHECK: @_ZTV12VirtualBase2 = linkonce_odr unnamed_addr constant { [5 x ptr], [4 x ptr] } { [5 x ptr] [ptr inttoptr (i64 8 to ptr), ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, i32 0, i64 [[BASE2_B_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTV12VirtualBase2, i32 0, i32 0, i32 3)), ptr ptrauth (ptr @_ZN12VirtualBase21gEv, i32 0, i64 [[VIRTUALBASE2_G_DISC:51224]], ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTV12VirtualBase2, i32 0, i32 0, i32 4))], [4 x ptr] [ptr null, ptr inttoptr (i64 -8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTV12VirtualBase2, i32 0, i32 1, i32 3))] },{{.*}} align 8 +// CHECK: @_ZTT12VirtualBase2 = linkonce_odr unnamed_addr constant [2 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-24, 16) ({ [5 x ptr], [4 x ptr] }, ptr @_ZTV12VirtualBase2, i32 0, i32 0, i32 3), i32 2), ptr ptrauth (ptr getelementptr inbounds inrange(-24, 8) ({ [5 x ptr], [4 x ptr] }, ptr @_ZTV12VirtualBase2, i32 0, i32 1, i32 3), i32 2)],{{.*}} align 8 +// CHECK: @_ZTV8Derived4 = linkonce_odr unnamed_addr constant { [7 x ptr], [5 x ptr] } { [7 x ptr] [ptr null, ptr null, ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC]], ptr getelementptr inbounds ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 0, i32 4)), ptr ptrauth (ptr @_ZN12VirtualBase11fEv, i32 0, i64 [[VIRTUALBASE1_F_DISC]], ptr getelementptr inbounds ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 0, i32 5)), ptr ptrauth (ptr @_ZN8Derived41hEv, i32 0, i64 [[DERIVED4_H_DISC:31844]], ptr getelementptr inbounds ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 0, i32 6))], [5 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr inttoptr (i64 -8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, i32 0, i64 [[BASE2_B_DISC]], ptr getelementptr inbounds ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 1, i32 3)), ptr ptrauth (ptr @_ZN12VirtualBase21gEv, i32 0, i64 [[VIRTUALBASE2_G_DISC]], ptr getelementptr inbounds ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 1, i32 4))] },{{.*}} align 8 +// CHECK: @_ZTT8Derived4 = linkonce_odr unnamed_addr constant [7 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-32, 24) ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 0, i32 4), i32 2), ptr ptrauth (ptr getelementptr inbounds inrange(-32, 16) ({ [6 x ptr] }, ptr @_ZTC8Derived40_12VirtualBase1, i32 0, i32 0, i32 4), i32 2), ptr ptrauth (ptr getelementptr inbounds inrange(-32, 16) ({ [6 x ptr] }, ptr @_ZTC8Derived40_12VirtualBase1, i32 0, i32 0, i32 4), i32 2), ptr ptrauth (ptr getelementptr inbounds inrange(-24, 16) ({ [5 x ptr], [4 x ptr] }, ptr @_ZTC8Derived48_12VirtualBase2, i32 0, i32 0, i32 3), i32 2), ptr ptrauth (ptr getelementptr inbounds inrange(-24, 8) ({ [5 x ptr], [4 x ptr] }, ptr @_ZTC8Derived48_12VirtualBase2, i32 0, i32 1, i32 3), i32 2), ptr ptrauth (ptr getelementptr inbounds inrange(-32, 24) ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 0, i32 4), i32 2), ptr ptrauth (ptr getelementptr inbounds inrange(-24, 16) ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 1, i32 3), i32 2)],{{.*}} align 8 +// CHECK: @_ZTC8Derived40_12VirtualBase1 = linkonce_odr unnamed_addr constant { [6 x ptr] } { [6 x ptr] [ptr null, ptr null, ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC]], ptr getelementptr inbounds ({ [6 x ptr] }, ptr @_ZTC8Derived40_12VirtualBase1, i32 0, i32 0, i32 4)), ptr ptrauth (ptr @_ZN12VirtualBase11fEv, i32 0, i64 [[VIRTUALBASE1_F_DISC]], ptr getelementptr inbounds ({ [6 x ptr] }, ptr @_ZTC8Derived40_12VirtualBase1, i32 0, i32 0, i32 5))] },{{.*}} align 8 +// CHECK: @_ZTC8Derived48_12VirtualBase2 = linkonce_odr unnamed_addr constant { [5 x ptr], [4 x ptr] } { [5 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, i32 0, i64 [[BASE2_B_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTC8Derived48_12VirtualBase2, i32 0, i32 0, i32 3)), ptr ptrauth (ptr @_ZN12VirtualBase21gEv, i32 0, i64 [[VIRTUALBASE2_G_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTC8Derived48_12VirtualBase2, i32 0, i32 0, i32 4))], [4 x ptr] [ptr null, ptr inttoptr (i64 8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTC8Derived48_12VirtualBase2, i32 0, i32 1, i32 3))] },{{.*}} align 8 + +struct Base1 { virtual void a() {} }; +struct Base2 { virtual void b() {} }; +struct Derived1 : public Base1, public Base2 { + virtual void c() {} + virtual void d() {} +}; +struct Derived2 : public Base2, public Base1 { + virtual void c() {} + virtual void e() {} +}; + +struct Derived3 : public Base1, public Base2 { + constexpr Derived3(){} + virtual void i() {} +}; + +Base1 g_b1; +Base2 g_b2; +Derived1 g_d1; +Derived2 g_d2; +Derived3 g_d3; + +extern "C" void test_basic_inheritance() { + Base1 g_b1; + Base2 g_b2; + Derived1 g_d1; + Derived2 g_d2; + Derived3 g_d3; +} + +struct VirtualBase1 : virtual Base1 { + VirtualBase1(){} + virtual void f() {} +}; +struct VirtualBase2 : virtual Base1, Base2 { + VirtualBase2(){} + virtual void g() {} +}; +struct Derived4 : VirtualBase1, VirtualBase2 { + virtual void h() {} +}; +struct Derived5 : VirtualBase2, VirtualBase1 { + virtual void h() {} +}; + +// DARWIN-LABEL: define {{.*}} ptr @_ZN12VirtualBase1C1Ev +// ELF-LABEL: define {{.*}} void @_ZN12VirtualBase1C1Ev +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) + +// DARWIN-LABEL: define {{.*}} ptr @_ZN12VirtualBase2C1Ev +// ELF-LABEL: define {{.*}} void @_ZN12VirtualBase2C1Ev +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) + +// DARWIN-LABEL: define {{.*}} ptr @_ZN8Derived4C1Ev +// ELF-LABEL: define {{.*}} void @_ZN8Derived4C1Ev +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) + +// DARWIN-LABEL: define {{.*}} ptr @_ZN8Derived5C1Ev +// ELF-LABEL: define {{.*}} void @_ZN8Derived5C1Ev +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) + + +VirtualBase1 g_vb1; +VirtualBase2 g_vb2; +Derived4 g_d4; +Derived5 g_d5; + + +extern "C" void cross_check_vtables(Base1 *b1, + Base2 *b2, + Derived1 *d1, + Derived2 *d2, + Derived3 *d3, + VirtualBase1 *vb1, + VirtualBase2 *vb2, + Derived4 *d4, + Derived4 *d5) { + asm("; b1->a()" ::: "memory"); + b1->a(); + asm("; b2->b()" ::: "memory"); + b2->b(); + asm("; d1->a()" ::: "memory"); + d1->a(); + asm("; d1->c()" ::: "memory"); + d1->c(); + asm("; d2->a()" ::: "memory"); + d2->a(); + asm("; d2->c()" ::: "memory"); + d2->c(); + asm("; d3->a()" ::: "memory"); + d3->a(); + asm("; d3->b()" ::: "memory"); + d3->b(); + asm("; d3->i()" ::: "memory"); + d3->i(); + asm("; vb1->a()" ::: "memory"); + vb1->a(); + asm("; vb1->f()" ::: "memory"); + vb1->f(); + asm("; vb2->a()" ::: "memory"); + vb2->a(); + asm("; vb2->g()" ::: "memory"); + vb2->g(); + asm("; d4->a()" ::: "memory"); + d4->a(); + asm("; d4->b()" ::: "memory"); + d4->b(); + asm("; d4->f()" ::: "memory"); + d4->f(); + asm("; d4->g()" ::: "memory"); + d4->g(); + asm("; d4->h()" ::: "memory"); + d4->h(); + asm("; d5->a()" ::: "memory"); + d5->a(); + asm("; d5->b()" ::: "memory"); + d5->b(); + asm("; d5->f()" ::: "memory"); + d5->f(); + asm("; d5->g()" ::: "memory"); + d5->g(); + asm("; d5->h()" ::: "memory"); + d5->h(); +} + +// CHECK-LABEL: define{{.*}} void @cross_check_vtables( +// CHECK: "; b1->a()", +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_A_DISC]]) +// CHECK: "; b2->b()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_B_DISC]]) +// CHECK: "; d1->a()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_A_DISC]]) +// CHECK: "; d1->c()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[DERIVED1_C_DISC]]) +// CHECK: "; d2->a()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_A_DISC]]) +// CHECK: "; d2->c()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[DERIVED2_C_DISC]]) +// CHECK: "; d3->a()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_A_DISC]]) +// CHECK: "; d3->b()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_B_DISC]]) +// CHECK: "; d3->i()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[DERIVED3_I_DISC]]) +// CHECK: "; vb1->a()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_A_DISC]]) +// CHECK: "; vb1->f()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[VIRTUALBASE1_F_DISC]]) +// CHECK: "; vb2->a()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_A_DISC]]) +// CHECK: "; vb2->g()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[VIRTUALBASE2_G_DISC]]) +// CHECK: "; d4->a()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_A_DISC]]) +// CHECK: "; d4->b()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_B_DISC]]) +// CHECK: "; d4->f()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[VIRTUALBASE1_F_DISC]]) +// CHECK: "; d4->g()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[VIRTUALBASE2_G_DISC]]) +// CHECK: "; d4->h()" +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[DERIVED4_H_DISC]]) + +// DARWIN-LABEL: define {{.*}} ptr @_ZN5Base1C2Ev +// ELF-LABEL: define {{.*}} void @_ZN5Base1C2Ev +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) + +// DARWIN-LABEL: define {{.*}} ptr @_ZN5Base2C2Ev +// ELF-LABEL: define {{.*}} void @_ZN5Base2C2Ev +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) + +// DARWIN-LABEL: define {{.*}} ptr @_ZN8Derived1C2Ev +// ELF-LABEL: define {{.*}} void @_ZN8Derived1C2Ev +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) + +// DARWIN-LABEL: define {{.*}} ptr @_ZN8Derived2C2Ev +// ELF-LABEL: define {{.*}} void @_ZN8Derived2C2Ev +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) + +// DARWIN-LABEL: define {{.*}} ptr @_ZN8Derived3C2Ev +// ELF-LABEL: define {{.*}} void @_ZN8Derived3C2Ev +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) diff --git a/clang/test/CodeGenCXX/ptrauth-member-function-pointer.cpp b/clang/test/CodeGenCXX/ptrauth-member-function-pointer.cpp new file mode 100644 index 0000000000000..0a9ac3fa510f5 --- /dev/null +++ b/clang/test/CodeGenCXX/ptrauth-member-function-pointer.cpp @@ -0,0 +1,440 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -o - %s | FileCheck -check-prefixes=CHECK,NODEBUG,DARWIN %s +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -debug-info-kind=limited -o - %s | FileCheck -check-prefixes=CHECK,DARWIN %s +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 1 -o - %s | FileCheck %s -check-prefix=STACK-PROT +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 2 -o - %s | FileCheck %s -check-prefix=STACK-PROT +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 3 -o - %s | FileCheck %s -check-prefix=STACK-PROT + +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -o - %s | FileCheck -check-prefixes=CHECK,NODEBUG,ELF %s +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -debug-info-kind=limited -o - %s | FileCheck -check-prefixes=CHECK,ELF %s +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 1 -o - %s | FileCheck %s -check-prefix=STACK-PROT +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 2 -o - %s | FileCheck %s -check-prefix=STACK-PROT +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 3 -o - %s | FileCheck %s -check-prefix=STACK-PROT + + +// CHECK: @gmethod0 = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 [[TYPEDISC1:35591]]) to i64), i64 0 }, align 8 +// CHECK: @gmethod1 = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived011nonvirtual5Ev, i32 0, i64 [[TYPEDISC0:22163]]) to i64), i64 0 }, align 8 +// CHECK: @gmethod2 = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 [[TYPEDISC0]]) to i64), i64 0 }, align 8 + +// CHECK: @__const._Z13testArrayInitv.p0 = private unnamed_addr constant [1 x { i64, i64 }] [{ i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 35591) to i64), i64 0 }], align 8 +// CHECK: @__const._Z13testArrayInitv.p1 = private unnamed_addr constant [1 x { i64, i64 }] [{ i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 35591) to i64), i64 0 }], align 8 +// CHECK: @__const._Z13testArrayInitv.c0 = private unnamed_addr constant %struct.Class0 { { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 35591) to i64), i64 0 } }, align 8 +// CHECK: @__const._Z13testArrayInitv.c1 = private unnamed_addr constant %struct.Class0 { { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 35591) to i64), i64 0 } }, align 8 + +// CHECK: @_ZTV5Base0 = unnamed_addr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr @_ZTI5Base0, +// CHECK-SAME: ptr ptrauth (ptr @_ZN5Base08virtual1Ev, i32 0, i64 55600, ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5Base0, i32 0, i32 0, i32 2)), +// CHECK-SAME: ptr ptrauth (ptr @_ZN5Base08virtual3Ev, i32 0, i64 53007, ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5Base0, i32 0, i32 0, i32 3)), +// CHECK-SAME: ptr ptrauth (ptr @_ZN5Base016virtual_variadicEiz, i32 0, i64 7464, ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5Base0, i32 0, i32 0, i32 4))] }, align 8 + +typedef __SIZE_TYPE__ size_t; + +namespace std { +template +class initializer_list { + const _Ep *__begin_; + size_t __size_; + + initializer_list(const _Ep *__b, size_t __s); +}; +} // namespace std + +struct Base0 { + void nonvirtual0(); + virtual void virtual1(); + virtual void virtual3(); + virtual void virtual_variadic(int, ...); +}; + +struct A0 { + int d[4]; +}; + +struct A1 { + int d[8]; +}; + +struct __attribute__((trivial_abi)) TrivialS { + TrivialS(const TrivialS &); + ~TrivialS(); + int p[4]; +}; + +struct Derived0 : Base0 { + void virtual1() override; + void nonvirtual5(); + virtual void virtual6(); + virtual A0 return_agg(); + virtual A1 sret(); + virtual void trivial_abi(TrivialS); +}; + +struct Base1 { + virtual void virtual7(); +}; + +struct Derived1 : Base0, Base1 { + void virtual1() override; + void virtual7() override; +}; + +typedef void (Base0::*MethodTy0)(); +typedef void (Base0::*VariadicMethodTy0)(int, ...); +typedef void (Derived0::*MethodTy1)(); + +struct Class0 { + MethodTy1 m0; +}; + +// CHECK: define{{.*}} void @_ZN5Base08virtual1Ev( + +// CHECK: define{{.*}} void @_Z5test0v() +// CHECK: %[[METHOD0:.*]] = alloca { i64, i64 }, align 8 +// CHECK-NEXT: %[[VARMETHOD1:.*]] = alloca { i64, i64 }, align 8 +// CHECK-NEXT: %[[METHOD2:.*]] = alloca { i64, i64 }, align 8 +// CHECK-NEXT: %[[METHOD3:.*]] = alloca { i64, i64 }, align 8 +// CHECK-NEXT: %[[METHOD4:.*]] = alloca { i64, i64 }, align 8 +// CHECK-NEXT: %[[METHOD5:.*]] = alloca { i64, i64 }, align 8 +// CHECK-NEXT: %[[METHOD6:.*]] = alloca { i64, i64 }, align 8 +// CHECK-NEXT: %[[METHOD7:.*]] = alloca { i64, i64 }, align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 [[TYPEDISC0]]) to i64), i64 0 }, ptr %[[METHOD0]], align 8 +// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 [[TYPEDISC0]]) to i64), i64 0 }, ptr %[[METHOD0]], align 8 +// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual3Ev_vfpthunk_, i32 0, i64 [[TYPEDISC0]]) to i64), i64 0 }, ptr %[[METHOD0]], align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base016virtual_variadicEiz_vfpthunk_, i32 0, i64 34368) to i64), i64 0 }, ptr %[[VARMETHOD1]], align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 +// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 +// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual3Ev_vfpthunk_, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 +// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived011nonvirtual5Ev, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 +// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived08virtual6Ev_vfpthunk_, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived010return_aggEv_vfpthunk_, i32 0, i64 64418) to i64), i64 0 }, ptr %[[METHOD3]], align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived04sretEv_vfpthunk_, i32 0, i64 28187) to i64), i64 0 }, ptr %[[METHOD4]], align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived011trivial_abiE8TrivialS_vfpthunk_, i32 0, i64 8992) to i64), i64 0 }, ptr %[[METHOD5]], align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base18virtual7Ev_vfpthunk_, i32 0, i64 [[TYPEDISC2:61596]]) to i64), i64 0 }, ptr %[[METHOD6]], align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived18virtual7Ev_vfpthunk_, i32 0, i64 25206) to i64), i64 0 }, ptr %[[METHOD7]], align 8 +// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 25206) to i64), i64 0 }, ptr %[[METHOD7]], align 8 +// CHECK: ret void + +// CHECK: define linkonce_odr hidden void @_ZN5Base08virtual1Ev_vfpthunk_(ptr noundef %[[THIS:.*]]) +// CHECK: %[[THIS_ADDR:.*]] = alloca ptr, align 8 +// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]], align 8 +// CHECK: %[[THIS1:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 +// CHECK-NEXT: %[[V0:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 +// CHECK-NEXT: %[[VTABLE:.*]] = load ptr, ptr %[[THIS1]], align 8 +// CHECK-NEXT: %[[V2:.*]] = ptrtoint ptr %[[VTABLE]] to i64 +// CHECK-NEXT: %[[V3:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V2]], i32 2, i64 0) +// CHECK-NEXT: %[[V4:.*]] = inttoptr i64 %[[V3]] to ptr +// CHECK-NEXT: %[[VFN:.*]] = getelementptr inbounds ptr, ptr %[[V4]], i64 0 +// CHECK-NEXT: %[[V5:.*]] = load ptr, ptr %[[VFN]], align 8 +// CHECK-NEXT: %[[V6:.*]] = ptrtoint ptr %[[VFN]] to i64 +// CHECK-NEXT: %[[V7:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V6]], i64 55600) +// CHECK-NEXT: musttail call void %[[V5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %[[V0]]) [ "ptrauth"(i32 0, i64 %[[V7]]) ] +// CHECK-NEXT: ret void + +// CHECK: define linkonce_odr hidden void @_ZN5Base08virtual3Ev_vfpthunk_(ptr noundef %{{.*}}) +// CHECK: load ptr, ptr %{{.*}}, align 8 +// CHECK: load ptr, ptr %{{.*}}, align 8 +// CHECK: %[[VTABLE:.*]] = load ptr, ptr %{{.*}}, align 8 +// CHECK: %[[V2:.*]] = ptrtoint ptr %[[VTABLE]] to i64 +// CHECK: %[[V3:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V2]], i32 2, i64 0) +// CHECK: %[[V4:.*]] = inttoptr i64 %[[V3]] to ptr +// CHECK: getelementptr inbounds ptr, ptr %[[V4]], i64 1 +// CHECK: call i64 @llvm.ptrauth.blend(i64 %{{.*}}, i64 53007) + +// CHECK: define linkonce_odr hidden void @_ZN5Base016virtual_variadicEiz_vfpthunk_(ptr noundef %[[THIS:.*]], i32 noundef %0, ...) +// CHECK: %[[THIS_ADDR:.*]] = alloca ptr, align 8 +// CHECK-NEXT: %[[_ADDR:.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr %[[THIS]], ptr %[[THIS_ADDR]], align 8 +// CHECK: store i32 %0, ptr %[[_ADDR]], align 4 +// CHECK: %[[THIS1:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 +// CHECK-NEXT: %[[V1:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 +// CHECK-NEXT: %[[V2:.*]] = load i32, ptr %[[_ADDR]], align 4 +// CHECK-NEXT: %[[VTABLE:.*]] = load ptr, ptr %[[THIS1]], align 8 +// CHECK-NEXT: %[[V4:.*]] = ptrtoint ptr %[[VTABLE]] to i64 +// CHECK-NEXT: %[[V5:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V4]], i32 2, i64 0) +// CHECK-NEXT: %[[V6:.*]] = inttoptr i64 %[[V5]] to ptr +// CHECK-NEXT: %[[VFN:.*]] = getelementptr inbounds ptr, ptr %[[V6]], i64 2 +// CHECK-NEXT: %[[V7:.*]] = load ptr, ptr %[[VFN]], align 8 +// CHECK-NEXT: %[[V8:.*]] = ptrtoint ptr %[[VFN]] to i64 +// CHECK-NEXT: %[[V9:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V8]], i64 7464) +// CHECK-NEXT: musttail call void (ptr, i32, ...) %[[V7]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %[[V1]], i32 noundef %[[V2]], ...) [ "ptrauth"(i32 0, i64 %[[V9]]) ] +// CHECK-NEXT: ret void + +// CHECK: define linkonce_odr hidden void @_ZN8Derived08virtual6Ev_vfpthunk_(ptr noundef %[[THIS:.*]]) +// CHECK: %[[THIS_ADDR:.*]] = alloca ptr, align 8 +// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]], align 8 +// CHECK: %[[THIS1:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 +// CHECK: %[[V0:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 +// CHECK: %[[VTABLE:.*]] = load ptr, ptr %[[THIS1]], align 8 +// CHECK: %[[V1:.*]] = ptrtoint ptr %[[VTABLE]] to i64 +// CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V1]], i32 2, i64 0) +// CHECK: %[[V3:.*]] = inttoptr i64 %[[V2]] to ptr +// CHECK: %[[VFN:.*]] = getelementptr inbounds ptr, ptr %[[V3]], i64 3 +// CHECK: %[[V5:.*]] = ptrtoint ptr %[[VFN]] to i64 +// CHECK: call i64 @llvm.ptrauth.blend(i64 %[[V5]], i64 55535) + +// Check that the return value of the musttail call isn't copied to a temporary. + +// CHECK: define linkonce_odr hidden [2 x i64] @_ZN8Derived010return_aggEv_vfpthunk_(ptr noundef %{{.*}}) +// CHECK: %[[CALL:.*]] = musttail call [2 x i64] %{{.*}}(ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %{{.*}}) [ "ptrauth"(i32 0, i64 %{{.*}}) ] +// CHECK-NEXT: ret [2 x i64] %[[CALL]] + +// Check that the sret pointer passed to the caller is forwarded to the musttail +// call. + +// CHECK: define linkonce_odr hidden void @_ZN8Derived04sretEv_vfpthunk_(ptr dead_on_unwind noalias writable sret(%struct.A1) align 4 %[[AGG_RESULT:.*]], ptr noundef %{{.*}}) +// CHECK: musttail call void %{{.*}}(ptr dead_on_unwind writable sret(%struct.A1) align 4 %[[AGG_RESULT]], ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %{{.*}}) [ "ptrauth"(i32 0, i64 %{{.*}}) ] +// CHECK-NEXT: ret void + +// Check that the thunk function doesn't destruct the trivial_abi argument. + +// CHECK: define linkonce_odr hidden void @_ZN8Derived011trivial_abiE8TrivialS_vfpthunk_(ptr noundef %{{.*}}, [2 x i64] %{{.*}}) +// NODEBUG-NOT: call +// CHECK: call i64 @llvm.ptrauth.auth( +// NODEBUG-NOT: call +// CHECK: call i64 @llvm.ptrauth.blend( +// NODEBUG-NOT: call +// CHECK: musttail call void +// CHECK-NEXT: ret void + +// CHECK: define linkonce_odr hidden void @_ZN5Base18virtual7Ev_vfpthunk_(ptr noundef %[[THIS:.*]]) +// CHECK: entry: +// CHECK: %[[THIS_ADDR:.*]] = alloca ptr, align 8 +// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]], align 8 +// CHECK: %[[THIS1:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 +// CHECK: %[[V0:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 +// CHECK: %[[VTABLE:.*]] = load ptr, ptr %[[THIS1]], align 8 +// CHECK: %[[V1:.*]] = ptrtoint ptr %[[VTABLE]] to i64 +// CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V1]], i32 2, i64 0) +// CHECK: %[[V3:.*]] = inttoptr i64 %[[V2]] to ptr +// CHECK: getelementptr inbounds ptr, ptr %[[V3]], i64 0 + +// CHECK: define linkonce_odr hidden void @_ZN8Derived18virtual7Ev_vfpthunk_(ptr noundef %[[THIS:.*]]) +// CHECK: %[[THIS_ADDR:.*]] = alloca ptr, align 8 +// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]], align 8 +// CHECK: %[[THIS1:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 +// CHECK: load ptr, ptr %[[THIS_ADDR]], align 8 +// CHECK: %[[VTABLE:.*]] = load ptr, ptr %[[THIS1]], align 8 +// CHECK: %[[V1:.*]] = ptrtoint ptr %[[VTABLE]] to i64 +// CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V1]], i32 2, i64 0) +// CHECK: %[[V3:.*]] = inttoptr i64 %[[V2]] to ptr +// CHECK: getelementptr inbounds ptr, ptr %[[V3]], i64 3 + +void Base0::virtual1() {} + +void test0() { + MethodTy0 method0; + method0 = &Base0::nonvirtual0; + method0 = &Base0::virtual1; + method0 = &Base0::virtual3; + + VariadicMethodTy0 varmethod1; + varmethod1 = &Base0::virtual_variadic; + + MethodTy1 method2; + method2 = &Derived0::nonvirtual0; + method2 = &Derived0::virtual1; + method2 = &Derived0::virtual3; + method2 = &Derived0::nonvirtual5; + method2 = &Derived0::virtual6; + + A0 (Derived0::*method3)(); + method3 = &Derived0::return_agg; + + A1 (Derived0::*method4)(); + method4 = &Derived0::sret; + + void (Derived0::*method5)(TrivialS); + method5 = &Derived0::trivial_abi; + + void (Base1::*method6)(); + method6 = &Base1::virtual7; + + void (Derived1::*method7)(); + method7 = &Derived1::virtual7; + method7 = &Derived1::virtual1; +} + +// CHECK: define{{.*}} void @_Z5test1P5Base0MS_FvvE(ptr noundef %[[A0:.*]], [2 x i64] %[[A1_COERCE:.*]]) +// CHECK: %[[A1:.*]] = alloca { i64, i64 }, align 8 +// CHECK: %[[A0_ADDR:.*]] = alloca ptr, align 8 +// CHECK: %[[A1_ADDR:.*]] = alloca { i64, i64 }, align 8 +// CHECK: store [2 x i64] %[[A1_COERCE]], ptr %[[A1]], align 8 +// CHECK: %[[A11:.*]] = load { i64, i64 }, ptr %[[A1]], align 8 +// CHECK: store ptr %[[A0]], ptr %[[A0_ADDR]], align 8 +// CHECK: store { i64, i64 } %[[A11]], ptr %[[A1_ADDR]], align 8 +// CHECK: %[[V1:.*]] = load ptr, ptr %[[A0_ADDR]], align 8 +// CHECK: %[[V2:.*]] = load { i64, i64 }, ptr %[[A1_ADDR]], align 8 +// CHECK: %[[MEMPTR_ADJ:.*]] = extractvalue { i64, i64 } %[[V2]], 1 +// CHECK: %[[MEMPTR_ADJ_SHIFTED:.*]] = ashr i64 %[[MEMPTR_ADJ]], 1 +// CHECK: %[[V4:.*]] = getelementptr inbounds i8, ptr %[[V1]], i64 %[[MEMPTR_ADJ_SHIFTED]] +// CHECK: %[[MEMPTR_PTR:.*]] = extractvalue { i64, i64 } %[[V2]], 0 +// CHECK: %[[V5:.*]] = and i64 %[[MEMPTR_ADJ]], 1 +// CHECK: %[[MEMPTR_ISVIRTUAL:.*]] = icmp ne i64 %[[V5]], 0 +// CHECK: br i1 %[[MEMPTR_ISVIRTUAL]] + +// CHECK: %[[VTABLE:.*]] = load ptr, ptr %[[V4]], align 8 +// CHECK: %[[V7:.*]] = ptrtoint ptr %[[VTABLE]] to i64 +// CHECK: %[[V8:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V7]], i32 2, i64 0) +// CHECK: %[[V9:.*]] = inttoptr i64 %[[V8]] to ptr +// DARWIN: %[[V10:.*]] = trunc i64 %[[MEMPTR_PTR]] to i32 +// DARWIN: %[[V11:.*]] = zext i32 %[[V10]] to i64 +// DARWIN: %[[V12:.*]] = getelementptr i8, ptr %[[V9]], i64 %[[V11]] +// ELF: %[[V12:.*]] = getelementptr i8, ptr %[[V9]], i64 %[[MEMPTR_PTR]] +// CHECK: %[[MEMPTR_VIRTUALFN:.*]] = load ptr, ptr %[[V12]], align 8 +// CHECK: br + +// CHECK: %[[MEMPTR_NONVIRTUALFN:.*]] = inttoptr i64 %[[MEMPTR_PTR]] to ptr +// CHECK: br + +// CHECK: %[[V14:.*]] = phi ptr [ %[[MEMPTR_VIRTUALFN]], {{.*}} ], [ %[[MEMPTR_NONVIRTUALFN]], {{.*}} ] +// CHECK: %[[V15:.*]] = phi i64 [ 0, {{.*}} ], [ [[TYPEDISC0]], {{.*}} ] +// CHECK: call void %[[V14]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %[[V4]]) [ "ptrauth"(i32 0, i64 %[[V15]]) ] +// CHECK: ret void + +void test1(Base0 *a0, MethodTy0 a1) { + (a0->*a1)(); +} + +// CHECK: define{{.*}} void @_Z15testConversion0M5Base0FvvEM8Derived0FvvE([2 x i64] %[[METHOD0_COERCE:.*]], [2 x i64] %[[METHOD1_COERCE:.*]]) +// CHECK: %[[METHOD0:.*]] = alloca { i64, i64 }, align 8 +// CHECK: %[[METHOD1:.*]] = alloca { i64, i64 }, align 8 +// CHECK: %[[METHOD0_ADDR:.*]] = alloca { i64, i64 }, align 8 +// CHECK: %[[METHOD1_ADDR:.*]] = alloca { i64, i64 }, align 8 +// CHECK: store [2 x i64] %[[METHOD0_COERCE]], ptr %[[METHOD0]], align 8 +// CHECK: %[[METHOD01:.*]] = load { i64, i64 }, ptr %[[METHOD0]], align 8 +// CHECK: store [2 x i64] %[[METHOD1_COERCE]], ptr %[[METHOD1]], align 8 +// CHECK: %[[METHOD12:.*]] = load { i64, i64 }, ptr %[[METHOD1]], align 8 +// CHECK: store { i64, i64 } %[[METHOD01]], ptr %[[METHOD0_ADDR]], align 8 +// CHECK: store { i64, i64 } %[[METHOD12]], ptr %[[METHOD1_ADDR]], align 8 +// CHECK: %[[V2:.*]] = load { i64, i64 }, ptr %[[METHOD0_ADDR]], align 8 +// CHECK: %[[MEMPTR_PTR:.*]] = extractvalue { i64, i64 } %[[V2]], 0 +// CHECK: %[[MEMPTR_ADJ:.*]] = extractvalue { i64, i64 } %[[V2]], 1 +// CHECK: %[[V3:.*]] = and i64 %[[MEMPTR_ADJ]], 1 +// CHECK: %[[IS_VIRTUAL_OFFSET:.*]] = icmp ne i64 %[[V3]], 0 +// CHECK: br i1 %[[IS_VIRTUAL_OFFSET]] + +// CHECK: %[[V4:.*]] = inttoptr i64 %[[MEMPTR_PTR]] to ptr +// CHECK: %[[V5:.*]] = icmp ne ptr %[[V4]], null +// CHECK: br i1 %[[V5]] + +// CHECK: %[[V6:.*]] = ptrtoint ptr %[[V4]] to i64 +// CHECK: %[[V7:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V6]], i32 0, i64 [[TYPEDISC0]], i32 0, i64 [[TYPEDISC1]]) +// CHECK: %[[V8:.*]] = inttoptr i64 %[[V7]] to ptr +// CHECK: br + +// CHECK: %[[V9:.*]] = phi ptr [ null, {{.*}} ], [ %[[V8]], {{.*}} ] +// CHECK: %[[V1:.*]] = ptrtoint ptr %[[V9]] to i64 +// CHECK: %[[V11:.*]] = insertvalue { i64, i64 } %[[V2]], i64 %[[V1]], 0 +// CHECK: br + +// CHECK: %[[V12:.*]] = phi { i64, i64 } [ %[[V2]], {{.*}} ], [ %[[V11]], {{.*}} ] +// CHECK: store { i64, i64 } %[[V12]], ptr %[[METHOD1_ADDR]], align 8 +// CHECK: ret void + +void testConversion0(MethodTy0 method0, MethodTy1 method1) { + method1 = method0; +} + +// CHECK: define{{.*}} void @_Z15testConversion1M5Base0FvvE( +// CHECK: call i64 @llvm.ptrauth.resign(i64 %{{.*}}, i32 0, i64 [[TYPEDISC0]], i32 0, i64 [[TYPEDISC1]]) + +void testConversion1(MethodTy0 method0) { + MethodTy1 method1 = reinterpret_cast(method0); +} + +// CHECK: define{{.*}} void @_Z15testConversion2M8Derived0FvvE( +// CHECK: call i64 @llvm.ptrauth.resign(i64 %{{.*}}, i32 0, i64 [[TYPEDISC1]], i32 0, i64 [[TYPEDISC0]]) + +void testConversion2(MethodTy1 method1) { + MethodTy0 method0 = static_cast(method1); +} + +// CHECK: define{{.*}} void @_Z15testConversion3M8Derived0FvvE( +// CHECK: call i64 @llvm.ptrauth.resign(i64 %{{.*}}, i32 0, i64 [[TYPEDISC1]], i32 0, i64 [[TYPEDISC0]]) + +void testConversion3(MethodTy1 method1) { + MethodTy0 method0 = reinterpret_cast(method1); +} + +// No need to call @llvm.ptrauth.resign if the source member function +// pointer is a constant. + +// CHECK: define{{.*}} void @_Z15testConversion4v( +// CHECK: %[[METHOD0:.*]] = alloca { i64, i64 }, align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 [[TYPEDISC0]]) to i64), i64 0 }, ptr %[[METHOD0]], align 8 +// CHECK: ret void + +void testConversion4() { + MethodTy0 method0 = reinterpret_cast(&Derived0::virtual1); +} + +// This code used to crash. +namespace testNonVirtualThunk { + struct R {}; + + struct B0 { + virtual void bar(); + }; + + struct B1 { + virtual R foo(); + }; + + struct D : B0, B1 { + virtual R foo(); + }; + + D d; +} + +// CHECK: define internal void @_ZN22TestAnonymousNamespace12_GLOBAL__N_11S3fooEv_vfpthunk_( + +namespace TestAnonymousNamespace { +namespace { +struct S { + virtual void foo(){}; +}; +} // namespace + +void test() { + auto t = &S::foo; +} +} // namespace TestAnonymousNamespace + +MethodTy1 gmethod0 = reinterpret_cast(&Base0::nonvirtual0); +MethodTy0 gmethod1 = reinterpret_cast(&Derived0::nonvirtual5); +MethodTy0 gmethod2 = reinterpret_cast(&Derived0::virtual1); + +// CHECK-LABEL: define{{.*}} void @_Z13testArrayInitv() +// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %p0, ptr align 8 @__const._Z13testArrayInitv.p0, i64 16, i1 false) +// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %p1, ptr align 8 @__const._Z13testArrayInitv.p1, i64 16, i1 false) +// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %c0, ptr align 8 @__const._Z13testArrayInitv.c0, i64 16, i1 false) +// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %c1, ptr align 8 @__const._Z13testArrayInitv.c1, i64 16, i1 false) +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %{{.*}} align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %{{.*}}, align 8 + +void initList(std::initializer_list); + +void testArrayInit() { + MethodTy1 p0[] = {&Base0::nonvirtual0}; + MethodTy1 p1[] = {&Base0::virtual1}; + Class0 c0{&Base0::nonvirtual0}; + Class0 c1{&Base0::virtual1}; + initList({&Base0::nonvirtual0}); + initList({&Base0::virtual1}); +} + + + +// STACK-PROT: define {{.*}}_vfpthunk{{.*}}[[ATTRS:#[0-9]+]] +// STACK-PROT: attributes [[ATTRS]] = +// STACK-PROT-NOT: ssp +// STACK-PROT-NOT: sspstrong +// STACK-PROT-NOT: sspreq +// STACK-PROT-NEXT: attributes + +// CHECK: define{{.*}} void @_Z15testConvertNullv( +// CHECK: %[[T:.*]] = alloca { i64, i64 }, +// store { i64, i64 } zeroinitializer, { i64, i64 }* %[[T]], + +void testConvertNull() { + VariadicMethodTy0 t = (VariadicMethodTy0)(MethodTy0{}); +} diff --git a/clang/test/CodeGenCXX/ptrauth-rtti-layout.cpp b/clang/test/CodeGenCXX/ptrauth-rtti-layout.cpp index b4a8784a33d8c..2b633addd677e 100644 --- a/clang/test/CodeGenCXX/ptrauth-rtti-layout.cpp +++ b/clang/test/CodeGenCXX/ptrauth-rtti-layout.cpp @@ -1,10 +1,16 @@ -// RUN: %clang_cc1 %s -I%S -triple=arm64-apple-ios -fptrauth-calls -std=c++11 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -I%S -triple=arm64-apple-ios -fptrauth-calls -std=c++11 -emit-llvm -o - | FileCheck --check-prefix=DARWIN %s +// RUN: %clang_cc1 %s -I%S -triple=aarch64-linux-gnu -fptrauth-calls -std=c++11 -emit-llvm -o - | FileCheck --check-prefix=ELF %s + #include struct A { int a; }; -// CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr] -// CHECK: @_ZTS1A = linkonce_odr hidden constant [3 x i8] c"1A\00" -// CHECK: @_ZTI1A = linkonce_odr hidden constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr inttoptr (i64 add (i64 ptrtoint (ptr @_ZTS1A to i64), i64 -9223372036854775808) to ptr) } +// DARWIN: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr] +// DARWIN: @_ZTS1A = linkonce_odr hidden constant [3 x i8] c"1A\00" +// DARWIN: @_ZTI1A = linkonce_odr hidden constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr inttoptr (i64 add (i64 ptrtoint (ptr @_ZTS1A to i64), i64 -9223372036854775808) to ptr) } + +// ELF: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr] +// ELF: @_ZTS1A = linkonce_odr constant [3 x i8] c"1A\00" +// ELF: @_ZTI1A = linkonce_odr constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr @_ZTS1A } auto ATI = typeid(A); diff --git a/clang/test/CodeGenCXX/ptrauth-static-destructors.cpp b/clang/test/CodeGenCXX/ptrauth-static-destructors.cpp index cad43dc0746df..634450bf62ea9 100644 --- a/clang/test/CodeGenCXX/ptrauth-static-destructors.cpp +++ b/clang/test/CodeGenCXX/ptrauth-static-destructors.cpp @@ -2,8 +2,27 @@ // RUN: | FileCheck %s --check-prefix=CXAATEXIT // RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -emit-llvm -std=c++11 %s -o - \ -// RUN: -fno-use-cxa-atexit \ -// RUN: | FileCheck %s --check-prefix=ATEXIT +// RUN: -fno-use-cxa-atexit | FileCheck %s --check-prefixes=ATEXIT,ATEXIT_DARWIN + +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -emit-llvm -std=c++11 %s -o - \ +// RUN: | FileCheck %s --check-prefix=CXAATEXIT + +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -emit-llvm -std=c++11 %s -o - \ +// RUN: -fno-use-cxa-atexit | FileCheck %s --check-prefixes=ATEXIT,ATEXIT_ELF + +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -emit-llvm -std=c++11 %s \ +// RUN: -fptrauth-function-pointer-type-discrimination -o - | FileCheck %s --check-prefix=CXAATEXIT_DISC + +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -emit-llvm -std=c++11 %s -o - \ +// RUN: -fptrauth-function-pointer-type-discrimination -fno-use-cxa-atexit \ +// RUN: | FileCheck %s --check-prefixes=ATEXIT_DISC,ATEXIT_DISC_DARWIN + +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -emit-llvm -std=c++11 %s \ +// RUN: -fptrauth-function-pointer-type-discrimination -o - | FileCheck %s --check-prefix=CXAATEXIT_DISC + +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -emit-llvm -std=c++11 %s -o - \ +// RUN: -fptrauth-function-pointer-type-discrimination -fno-use-cxa-atexit \ +// RUN: | FileCheck %s --check-prefixes=ATEXIT_DISC,ATEXIT_DISC_ELF class Foo { public: @@ -16,9 +35,22 @@ Foo global; // CXAATEXIT: define internal void @__cxx_global_var_init() // CXAATEXIT: call i32 @__cxa_atexit(ptr ptrauth (ptr @_ZN3FooD1Ev, i32 0), ptr @global, ptr @__dso_handle) +// CXAATEXIT_DISC: define internal void @__cxx_global_var_init() +// CXAATEXIT_DISC: call i32 @__cxa_atexit(ptr ptrauth (ptr @_ZN3FooD1Ev, i32 0, i64 10942), ptr @global, ptr @__dso_handle) // ATEXIT: define internal void @__cxx_global_var_init() // ATEXIT: %{{.*}} = call i32 @atexit(ptr ptrauth (ptr @__dtor_global, i32 0)) -// ATEXIT: define internal void @__dtor_global() {{.*}} section "__TEXT,__StaticInit,regular,pure_instructions" { -// ATEXIT: %{{.*}} = call ptr @_ZN3FooD1Ev(ptr @global) +// ATEXIT_DARWIN: define internal void @__dtor_global() {{.*}} section "__TEXT,__StaticInit,regular,pure_instructions" { +// ATEXIT_ELF: define internal void @__dtor_global() {{.*}} section ".text.startup" { +// ATEXIT_DARWIN: %{{.*}} = call ptr @_ZN3FooD1Ev(ptr @global) +// ATEXIT_ELF: call void @_ZN3FooD1Ev(ptr @global) + +// ATEXIT_DISC: define internal void @__cxx_global_var_init() +// ATEXIT_DISC: %{{.*}} = call i32 @atexit(ptr ptrauth (ptr @__dtor_global, i32 0, i64 10942)) + + +// ATEXIT_DISC_DARWIN: define internal void @__dtor_global() {{.*}} section "__TEXT,__StaticInit,regular,pure_instructions" { +// ATEXIT_DISC_ELF: define internal void @__dtor_global() {{.*}} section ".text.startup" { +// ATEXIT_DISC_DARWIN: %{{.*}} = call ptr @_ZN3FooD1Ev(ptr @global) +// ATEXIT_DISC_ELF: call void @_ZN3FooD1Ev(ptr @global) diff --git a/clang/test/CodeGenCXX/ptrauth-throw.cpp b/clang/test/CodeGenCXX/ptrauth-throw.cpp index cea7226547e5a..0e6091a370223 100644 --- a/clang/test/CodeGenCXX/ptrauth-throw.cpp +++ b/clang/test/CodeGenCXX/ptrauth-throw.cpp @@ -1,5 +1,8 @@ -// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fcxx-exceptions -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK -// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fcxx-exceptions -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECKDISC +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fcxx-exceptions -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fcxx-exceptions -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECKDISC + +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fcxx-exceptions -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple aarch64-linux-gnu -fptrauth-calls -fcxx-exceptions -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECKDISC class Foo { public: @@ -7,10 +10,10 @@ class Foo { } }; -// CHECK-LABEL: define void @_Z1fv() +// CHECK-LABEL: define{{.*}} void @_Z1fv() // CHECK: call void @__cxa_throw(ptr %{{.*}}, ptr @_ZTI3Foo, ptr ptrauth (ptr @_ZN3FooD1Ev, i32 0)) -// CHECKDISC-LABEL: define void @_Z1fv() +// CHECKDISC-LABEL: define{{.*}} void @_Z1fv() // CHECKDISC: call void @__cxa_throw(ptr %{{.*}}, ptr @_ZTI3Foo, ptr ptrauth (ptr @_ZN3FooD1Ev, i32 0, i64 10942)) void f() { @@ -18,10 +21,10 @@ void f() { } // __cxa_throw is defined to take its destructor as "void (*)(void *)" in the ABI. -// CHECK-LABEL: define void @__cxa_throw({{.*}}) +// CHECK-LABEL: define{{.*}} void @__cxa_throw({{.*}}) // CHECK: call void {{%.*}}(ptr noundef {{%.*}}) [ "ptrauth"(i32 0, i64 0) ] -// CHECKDISC-LABEL: define void @__cxa_throw({{.*}}) +// CHECKDISC-LABEL: define{{.*}} void @__cxa_throw({{.*}}) // CHECKDISC: call void {{%.*}}(ptr noundef {{%.*}}) [ "ptrauth"(i32 0, i64 10942) ] extern "C" void __cxa_throw(void *exception, void *, void (*dtor)(void *)) { diff --git a/clang/test/CodeGenCXX/ptrauth-thunks.cpp b/clang/test/CodeGenCXX/ptrauth-thunks.cpp index a85c8c4c065c4..f4491a3aab7ab 100644 --- a/clang/test/CodeGenCXX/ptrauth-thunks.cpp +++ b/clang/test/CodeGenCXX/ptrauth-thunks.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -emit-llvm -std=c++11 %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -emit-llvm -std=c++11 %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -emit-llvm -std=c++11 %s -o - | FileCheck %s namespace Test1 { struct B1 { diff --git a/clang/test/CodeGenCXX/ptrauth-type-info-vtable.cpp b/clang/test/CodeGenCXX/ptrauth-type-info-vtable.cpp new file mode 100644 index 0000000000000..174aeda89d175 --- /dev/null +++ b/clang/test/CodeGenCXX/ptrauth-type-info-vtable.cpp @@ -0,0 +1,100 @@ +// RUN: %clang_cc1 -DENABLE_TID=0 -I%S -std=c++11 -triple=arm64e-apple-darwin \ +// RUN: -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -fptrauth-vtable-pointer-address-discrimination \ +// RUN: %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NODISC + +// RUN: %clang_cc1 -DENABLE_TID=0 -I%S -std=c++11 -triple=aarch64-linux-gnu \ +// RUN: -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -fptrauth-vtable-pointer-address-discrimination \ +// RUN: %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NODISC + +// RUN: %clang_cc1 -DENABLE_TID=1 -I%S -std=c++11 -triple=arm64e-apple-darwin \ +// RUN: -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -fptrauth-vtable-pointer-address-discrimination \ +// RUN: -fptrauth-type-info-vtable-pointer-discrimination \ +// RUN: %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,DISC + +// RUN: %clang_cc1 -DENABLE_TID=1 -I%S -std=c++11 -triple=aarch64-linux-gnu \ +// RUN: -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -fptrauth-vtable-pointer-address-discrimination \ +// RUN: -fptrauth-type-info-vtable-pointer-discrimination \ +// RUN: %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,DISC + +// copied from typeinfo +namespace std { + +#if __has_cpp_attribute(clang::ptrauth_vtable_pointer) +# if __has_feature(ptrauth_type_info_vtable_pointer_discrimination) +# define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH \ + [[clang::ptrauth_vtable_pointer(process_independent, address_discrimination, type_discrimination)]] +# else +# define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH \ + [[clang::ptrauth_vtable_pointer(process_independent, no_address_discrimination, no_extra_discrimination)]] +# endif +#else +# define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH +#endif + + class _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH type_info + { + type_info& operator=(const type_info&); + type_info(const type_info&); + + protected: + explicit type_info(const char* __n); + + public: + virtual ~type_info(); + + virtual void test_method(); + }; +} // namespace std + +static_assert(__has_feature(ptrauth_type_info_vtable_pointer_discrimination) == ENABLE_TID, "incorrect feature state"); + +// CHECK: @disc_std_type_info = global i32 [[STDTYPEINFO_DISC:45546]] +extern "C" int disc_std_type_info = __builtin_ptrauth_string_discriminator("_ZTVSt9type_info"); + +// CHECK: @_ZTV10TestStruct = unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTI10TestStruct, ptr ptrauth (ptr @_ZN10TestStructD1Ev, i32 0, i64 52216, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV10TestStruct, i32 0, i32 0, i32 2)), ptr ptrauth (ptr @_ZN10TestStructD0Ev, i32 0, i64 39671, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV10TestStruct, i32 0, i32 0, i32 3))] }, align 8 +// CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr] +// CHECK: @_ZTS10TestStruct = constant [13 x i8] c"10TestStruct\00", align 1 + +// NODISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr @_ZTS10TestStruct }, align 8 + +// DISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 [[STDTYPEINFO_DISC]]), ptr @_ZTS10TestStruct }, align 8 + +struct TestStruct { + virtual ~TestStruct(); + int a; +}; + +TestStruct::~TestStruct(){} + +extern "C" void test_vtable(std::type_info* t) { + t->test_method(); +} +// NODISC: define{{.*}} void @test_vtable(ptr noundef %t) +// NODISC: [[T_ADDR:%.*]] = alloca ptr, align 8 +// NODISC: store ptr %t, ptr [[T_ADDR]], align 8 +// NODISC: [[T:%.*]] = load ptr, ptr [[T_ADDR]], align 8 +// NODISC: [[VPTR:%.*]] = load ptr, ptr [[T]], align 8 +// NODISC: [[CAST_VPTR:%.*]] = ptrtoint ptr [[VPTR]] to i64 +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_VPTR]], i32 2, i64 0) + +// DISC: define{{.*}} void @test_vtable(ptr noundef %t) +// DISC: [[T_ADDR:%.*]] = alloca ptr, align 8 +// DISC: store ptr %t, ptr [[T_ADDR]], align 8 +// DISC: [[T:%.*]] = load ptr, ptr [[T_ADDR]], align 8 +// DISC: [[VPTR:%.*]] = load ptr, ptr [[T]], align 8 +// DISC: [[ADDR:%.*]] = ptrtoint ptr [[T]] to i64 +// DISC: [[DISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[ADDR]], i64 [[STDTYPEINFO_DISC]]) +// DISC: [[VPTRI:%.*]] = ptrtoint ptr [[VPTR]] to i64 +// DISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VPTRI]], i32 2, i64 [[DISCRIMINATOR]]) + +extern "C" const void *ensure_typeinfo() { + return new TestStruct; +} diff --git a/clang/test/CodeGenCXX/ptrauth-virtual-function.cpp b/clang/test/CodeGenCXX/ptrauth-virtual-function.cpp index 563d60780769b..4aa24738d8ce3 100644 --- a/clang/test/CodeGenCXX/ptrauth-virtual-function.cpp +++ b/clang/test/CodeGenCXX/ptrauth-virtual-function.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -emit-llvm -std=c++11 %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -emit-llvm -std=c++11 %s -o - | FileCheck --check-prefixes=CHECK,DARWIN %s +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -emit-llvm -std=c++11 %s -o - | FileCheck --check-prefixes=CHECK,ELF %s // Check virtual function pointers in vtables are signed. @@ -182,7 +183,8 @@ V1::~V1() { // Check sign/authentication of vtable pointers and authentication of virtual // functions. -// CHECK-LABEL: define noundef ptr @_ZN2V1D2Ev( +// DARWIN-LABEL: define noundef ptr @_ZN2V1D2Ev( +// ELF-LABEL: define dso_local void @_ZN2V1D2Ev( // CHECK: %[[THIS1:.*]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T1:[0-9]+]] = ptrtoint ptr %[[T0]] to i64 @@ -193,7 +195,7 @@ V1::~V1() { // CHECK: %[[SIGNED_VTADDR:[0-9]+]] = inttoptr i64 %[[T7]] to ptr // CHECK: store ptr %[[SIGNED_VTADDR]], ptr %[[THIS1]] -// CHECK-LABEL: define void @_Z8testB0m0P2B0( +// CHECK-LABEL: define{{.*}} void @_Z8testB0m0P2B0( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) @@ -208,7 +210,7 @@ void testB0m0(B0 *a) { a->m0(); } -// CHECK-LABEL: define void @_Z8testB0m1P2B0( +// CHECK-LABEL: define{{.*}} void @_Z8testB0m1P2B0( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) @@ -223,7 +225,7 @@ void testB0m1(B0 *a) { a->m1(); } -// CHECK-LABEL: define void @_Z8testB0m2P2B0( +// CHECK-LABEL: define{{.*}} void @_Z8testB0m2P2B0( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) @@ -238,7 +240,7 @@ void testB0m2(B0 *a) { a->m2(); } -// CHECK-LABEL: define void @_Z8testD0m0P2D0( +// CHECK-LABEL: define{{.*}} void @_Z8testD0m0P2D0( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) @@ -253,7 +255,7 @@ void testD0m0(D0 *a) { a->m0(); } -// CHECK-LABEL: define void @_Z8testD0m1P2D0( +// CHECK-LABEL: define{{.*}} void @_Z8testD0m1P2D0( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) @@ -268,7 +270,7 @@ void testD0m1(D0 *a) { a->m1(); } -// CHECK-LABEL: define void @_Z8testD0m2P2D0( +// CHECK-LABEL: define{{.*}} void @_Z8testD0m2P2D0( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) @@ -283,7 +285,7 @@ void testD0m2(D0 *a) { a->m2(); } -// CHECK-LABEL: define void @_Z8testD0m3P2D0( +// CHECK-LABEL: define{{.*}} void @_Z8testD0m3P2D0( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) @@ -299,7 +301,7 @@ void testD0m3(D0 *a) { } -// CHECK-LABEL: define void @_Z8testD1m0P2D1( +// CHECK-LABEL: define{{.*}} void @_Z8testD1m0P2D1( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) @@ -314,7 +316,7 @@ void testD1m0(D1 *a) { a->m0(); } -// CHECK-LABEL: define void @_Z8testD1m1P2D1( +// CHECK-LABEL: define{{.*}} void @_Z8testD1m1P2D1( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) @@ -329,7 +331,7 @@ void testD1m1(D1 *a) { a->m1(); } -// CHECK-LABEL: define void @_Z8testD1m2P2D1( +// CHECK-LABEL: define{{.*}} void @_Z8testD1m2P2D1( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) @@ -345,7 +347,7 @@ void testD1m2(D1 *a) { } -// CHECK-LABEL: define void @_Z8testD2m0P2D2( +// CHECK-LABEL: define{{.*}} void @_Z8testD2m0P2D2( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) @@ -360,7 +362,7 @@ void testD2m0(D2 *a) { a->m0(); } -// CHECK-LABEL: define void @_Z8testD2m1P2D2( +// CHECK-LABEL: define{{.*}} void @_Z8testD2m1P2D2( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) @@ -375,21 +377,21 @@ void testD2m1(D2 *a) { a->m1(); } -// CHECK-LABEL: define void @_Z10testD2m2D0P2D2( +// CHECK-LABEL: define{{.*}} void @_Z10testD2m2D0P2D2( // CHECK: call void @_ZN2B02m2Ev(ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}){{$}} void testD2m2D0(D2 *a) { a->D0::m2(); } -// CHECK-LABEL: define void @_Z10testD2m2D1P2D2( +// CHECK-LABEL: define{{.*}} void @_Z10testD2m2D1P2D2( // CHECK: call void @_ZN2B02m2Ev(ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}){{$}} void testD2m2D1(D2 *a) { a->D1::m2(); } -// CHECK-LABEL: define void @_Z8testD2m3P2D2( +// CHECK-LABEL: define{{.*}} void @_Z8testD2m3P2D2( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) @@ -404,7 +406,7 @@ void testD2m3(D2 *a) { a->m3(); } -// CHECK-LABEL: define void @_Z8testD3m0P2D3( +// CHECK-LABEL: define{{.*}} void @_Z8testD3m0P2D3( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) @@ -419,7 +421,7 @@ void testD3m0(D3 *a) { a->m0(); } -// CHECK-LABEL: define void @_Z8testD3m1P2D3( +// CHECK-LABEL: define{{.*}} void @_Z8testD3m1P2D3( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) @@ -434,7 +436,7 @@ void testD3m1(D3 *a) { a->m1(); } -// CHECK: define void @_Z8testD3m2P2D3(ptr noundef %[[A:.*]]) +// CHECK: define{{.*}} void @_Z8testD3m2P2D3(ptr noundef %[[A:.*]]) // CHECK: %[[A_ADDR:.*]] = alloca ptr, align 8 // CHECK: store ptr %[[A]], ptr %[[A_ADDR]], align 8 // CHECK: %[[V0:.*]] = load ptr, ptr %[[A_ADDR]], align 8 @@ -459,7 +461,7 @@ void testD3m2(D3 *a) { a->m2(); } -// CHECK-LABEL: define void @_Z17testD3Destructor0P2D3( +// CHECK-LABEL: define{{.*}} void @_Z17testD3Destructor0P2D3( // CHECK: load ptr, ptr // CHECK: %[[VTABLE:.*]] = load ptr, ptr %{{.*}} // CHECK: %[[T2:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 @@ -475,7 +477,7 @@ void testD3Destructor0(D3 *a) { delete a; } -// CHECK-LABEL: define void @_Z17testD3Destructor1P2D3( +// CHECK-LABEL: define{{.*}} void @_Z17testD3Destructor1P2D3( // CHECK: %[[T6:.*]] = load ptr, ptr % // CHECK: %[[VTABLE0:[a-z0-9]+]] = load ptr, ptr % // CHECK: %[[T2:[0-9]+]] = ptrtoint ptr %[[VTABLE0]] to i64 @@ -492,14 +494,15 @@ void testD3Destructor0(D3 *a) { // CHECK: %[[T12:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T13:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 // CHECK: %[[T14:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T13]], i64 57279) -// CHECK: %call = call noundef ptr %[[T12]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i32 0, i64 %[[T14]]) ] +// DARWIN: %call = call noundef ptr %[[T12]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i32 0, i64 %[[T14]]) ] +// ELF: call void %[[T12]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i32 0, i64 %[[T14]]) ] // CHECK: call void @_ZdlPv(ptr noundef %[[T7]]) void testD3Destructor1(D3 *a) { ::delete a; } -// CHECK-LABEL: define void @_Z17testD3Destructor2P2D3( +// CHECK-LABEL: define{{.*}} void @_Z17testD3Destructor2P2D3( // CHECK: load ptr, ptr // CHECK: %[[VTABLE:.*]] = load ptr, ptr % // CHECK: %[[T2:.*]] = ptrtoint ptr %[[VTABLE]] to i64 @@ -509,7 +512,8 @@ void testD3Destructor1(D3 *a) { // CHECK: %[[T5:.*]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:.*]] = ptrtoint ptr %[[VFN]] to i64 // CHECK: %[[T7:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 57279) -// CHECK: %call = call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// DARWIN: %call = call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// ELF: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i32 0, i64 %[[T7]]) ] void testD3Destructor2(D3 *a) { a->~D3(); @@ -526,23 +530,27 @@ void materializeConstructors() { V1 V1; } -// CHECK-LABEL: define linkonce_odr noundef ptr @_ZN2B0C2Ev( +// DARWIN-LABEL: define linkonce_odr noundef ptr @_ZN2B0C2Ev( +// ELF-LABEL: define linkonce_odr void @_ZN2B0C2Ev( // CHECK: %[[THIS:.*]] = load ptr, ptr % // CHECK: %[[T0:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 40) ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 2) to i64), i32 2, i64 0) // CHECK: %[[SIGNED_VTADDR:[0-9]+]] = inttoptr i64 %[[T0]] to ptr // CHECK: store ptr %[[SIGNED_VTADDR]], ptr %[[THIS]] -// CHECK-LABEL: define linkonce_odr noundef ptr @_ZN2D0C2Ev( +// DARWIN-LABEL: define linkonce_odr noundef ptr @_ZN2D0C2Ev( +// ELF-LABEL: define linkonce_odr void @_ZN2D0C2Ev( // CHECK: %[[T0:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 56) ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 2) to i64), i32 2, i64 0) // CHECK: %[[SIGNED_VTADDR:[0-9]+]] = inttoptr i64 %[[T0]] to ptr // CHECK: store ptr %[[SIGNED_VTADDR]], ptr %[[THIS]] -// CHECK-LABEL: define linkonce_odr noundef ptr @_ZN2D1C2Ev( +// DARWIN-LABEL: define linkonce_odr noundef ptr @_ZN2D1C2Ev( +// ELF-LABEL: define linkonce_odr void @_ZN2D1C2Ev( // CHECK: %[[T0:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 48) ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 2) to i64), i32 2, i64 0) // CHECK: %[[SIGNED_VTADDR:[0-9]+]] = inttoptr i64 %[[T0]] to ptr // CHECK: store ptr %[[SIGNED_VTADDR]], ptr %[[THIS]] -// CHECK-LABEL: define linkonce_odr noundef ptr @_ZN2D2C2Ev( +// DARWIN-LABEL: define linkonce_odr noundef ptr @_ZN2D2C2Ev( +// ELF-LABEL: define linkonce_odr void @_ZN2D2C2Ev( // CHECK: %[[SLOT0:.*]] = load ptr, ptr // CHECK: %[[SIGN_VTADDR0:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 56) ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 2) to i64), i32 2, i64 0) // CHECK: %[[T1:[0-9]+]] = inttoptr i64 %[[SIGN_VTADDR0]] to ptr @@ -552,7 +560,8 @@ void materializeConstructors() { // CHECK: %[[T5:[0-9]+]] = inttoptr i64 %[[SIGN_VTADDR1]] to ptr // CHECK: store ptr %[[T5]], ptr %[[T3]] -// CHECK-LABEL: define linkonce_odr noundef ptr @_ZN2V0C2Ev( +// DARWIN-LABEL: define linkonce_odr noundef ptr @_ZN2V0C2Ev( +// ELF-LABEL: define linkonce_odr void @_ZN2V0C2Ev( // CHECK: %[[THIS1]] = load ptr, ptr % // CHECK: %[[VTT:[a-z0-9]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = load ptr, ptr %[[VTT]] diff --git a/clang/test/CodeGenCXX/ptrauth-vtable-virtual-inheritance-thunk.cpp b/clang/test/CodeGenCXX/ptrauth-vtable-virtual-inheritance-thunk.cpp index 00b1cbd06e0f0..031bb48608af7 100644 --- a/clang/test/CodeGenCXX/ptrauth-vtable-virtual-inheritance-thunk.cpp +++ b/clang/test/CodeGenCXX/ptrauth-vtable-virtual-inheritance-thunk.cpp @@ -1,4 +1,7 @@ -// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-intrinsics -fptrauth-calls -fptrauth-vtable-pointer-type-discrimination -emit-llvm -O0 -disable-llvm-passes -o - | FileCheck --check-prefix=CHECK %s +// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -disable-llvm-passes -fptrauth-intrinsics -fptrauth-calls \ +// RUN: -fptrauth-vtable-pointer-type-discrimination -emit-llvm -O0 -o - | FileCheck --check-prefixes=CHECK,DARWIN %s +// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -disable-llvm-passes -fptrauth-intrinsics -fptrauth-calls \ +// RUN: -fptrauth-vtable-pointer-type-discrimination -emit-llvm -O0 -o - | FileCheck --check-prefixes=CHECK,ELF %s // The actual vtable construction @@ -103,9 +106,11 @@ // CHECK: @_ZTVN10__cxxabiv120__si_class_type_infoE = external global [0 x ptr] -// CHECK: @_ZTS1B = linkonce_odr hidden constant [3 x i8] c"1B\00", align 1 +// DARWIN: @_ZTS1B = linkonce_odr hidden constant [3 x i8] c"1B\00", align 1 +// ELF: @_ZTS1B = linkonce_odr constant [3 x i8] c"1B\00", comdat, align 1 -// CHECK: @_ZTI1B = linkonce_odr hidden constant { ptr, ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), i32 2), ptr inttoptr (i64 add (i64 ptrtoint (ptr @_ZTS1B to i64), i64 -9223372036854775808) to ptr), ptr @_ZTI1A }, align 8 +// DARWIN: @_ZTI1B = linkonce_odr hidden constant { ptr, ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), i32 2), ptr inttoptr (i64 add (i64 ptrtoint (ptr @_ZTS1B to i64), i64 -9223372036854775808) to ptr), ptr @_ZTI1A }, align 8 +// ELF: @_ZTI1B = linkonce_odr constant { ptr, ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), i32 2), ptr @_ZTS1B, ptr @_ZTI1A }, comdat, align 8 // CHECK: @_ZTI1C = constant { ptr, ptr, i32, i32, ptr, i64 } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), i32 2), ptr @_ZTS1C, i32 0, i32 1, ptr @_ZTI1B, i64 -6141 }, align 8 @@ -177,7 +182,8 @@ // CHECK-SAME: ptr ptrauth (ptr @_ZN1A1gEv, i32 0, i64 19402, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 3)), // CHECK-SAME: ptr ptrauth (ptr @_ZN1A1hEz, i32 0, i64 31735, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 4)), // CHECK-SAME: ptr ptrauth (ptr @_ZN1BD1Ev, i32 0, i64 2043, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1BD0Ev, i32 0, i64 63674, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 6))] }, align 8 +// DARWIN-SAME: ptr ptrauth (ptr @_ZN1BD0Ev, i32 0, i64 63674, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 6))] }, align 8 +// ELF-SAME: ptr ptrauth (ptr @_ZN1BD0Ev, i32 0, i64 63674, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 6))] }, comdat, align 8 extern "C" int printf(const char *format, ...); @@ -284,13 +290,15 @@ int main() { } // And check the thunks -// CHECK: ptr @_ZTv0_n48_N1CD1Ev(ptr noundef %this) +// DARWIN: ptr @_ZTv0_n48_N1CD1Ev(ptr noundef %this) +// ELF: void @_ZTv0_n48_N1CD1Ev(ptr noundef %this) // CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]], i32 2, i64 62866) // CHECK: void @_ZTv0_n48_N1CD0Ev(ptr noundef %this) // CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]], i32 2, i64 62866) -// CHECK: ptr @_ZTv0_n48_N1DD1Ev(ptr noundef %this) +// DARWIN: ptr @_ZTv0_n48_N1DD1Ev(ptr noundef %this) +// ELF: void @_ZTv0_n48_N1DD1Ev(ptr noundef %this) // CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]], i32 2, i64 62866) // CHECK: void @_ZTv0_n48_N1DD0Ev(ptr noundef %this) diff --git a/clang/test/CodeGenCXX/regparm.cpp b/clang/test/CodeGenCXX/regparm.cpp index 1fd471c2d0727..b9735485db8de 100644 --- a/clang/test/CodeGenCXX/regparm.cpp +++ b/clang/test/CodeGenCXX/regparm.cpp @@ -32,7 +32,7 @@ struct S3 { } a; }; __attribute((regparm(2))) void foo4(S3 a, int b); -// CHECK: declare void @_Z4foo42S3i(ptr noundef byval(%struct.S3) align 4, i32 inreg noundef) +// CHECK: declare void @_Z4foo42S3i(i32 inreg noundef) void bar3(S3 a, int b) { foo4(a, b); } diff --git a/clang/test/CodeGenCXX/trivial_abi.cpp b/clang/test/CodeGenCXX/trivial_abi.cpp index 3012b0f2bc33d..54912a617c287 100644 --- a/clang/test/CodeGenCXX/trivial_abi.cpp +++ b/clang/test/CodeGenCXX/trivial_abi.cpp @@ -262,6 +262,26 @@ void testExceptionLarge() { calleeExceptionLarge(Large(), Large()); } +// CHECK: define void @_ZN7GH930401gEPNS_1SE +// CHECK: [[CALL:%.*]] = call i64 @_ZN7GH930401fEv +// CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 [[CALL]] to i56 +// CHECK-NEXT: store i56 [[TRUNC]] +// CHECK-NEXT: ret void +void* operator new(unsigned long, void*); +namespace GH93040 { +struct [[clang::trivial_abi]] S { + char a; + int x; + __attribute((aligned(2))) char y; + S(); +} __attribute((packed)); +S f(); +void g(S* s) { new(s) S(f()); } +struct S2 { [[no_unique_address]] S s; char c;}; +static_assert(sizeof(S) == 8 && sizeof(S2) == 8, ""); +} + + // PR42961 // CHECK: define{{.*}} @"_ZN3$_08__invokeEv"() diff --git a/clang/test/CodeGenCXX/ubsan-vtable-checks.cpp b/clang/test/CodeGenCXX/ubsan-vtable-checks.cpp index 72c59cb41c34b..c891ff0a4fa42 100644 --- a/clang/test/CodeGenCXX/ubsan-vtable-checks.cpp +++ b/clang/test/CodeGenCXX/ubsan-vtable-checks.cpp @@ -3,6 +3,8 @@ // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm -fsanitize=null,vptr %s -o - | FileCheck %s --check-prefix=CHECK-VPTR --check-prefix=ITANIUM // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -fsanitize=null,vptr %s -o - | FileCheck %s --check-prefix=CHECK-VPTR --check-prefix=MSABI --check-prefix=CHECK-VPTR-MS // RUN: %clang_cc1 -std=c++11 -triple arm64e-ios-13 -emit-llvm -fptrauth-intrinsics -fptrauth-calls -fptrauth-vtable-pointer-type-discrimination -fptrauth-vtable-pointer-address-discrimination -fsanitize=null,vptr %s -o - | FileCheck %s --check-prefix=CHECK-VPTR --check-prefix=ITANIUM --check-prefix=CHECK-PTRAUTH +// RUN: %clang_cc1 -std=c++11 -triple aarch64-unknown-linux -emit-llvm -fptrauth-intrinsics -fptrauth-calls -fptrauth-vtable-pointer-type-discrimination -fptrauth-vtable-pointer-address-discrimination -fsanitize=null,vptr %s -o - | FileCheck %s --check-prefix=CHECK-VPTR --check-prefix=ITANIUM --check-prefix=CHECK-PTRAUTH + struct T { virtual ~T() {} virtual int v() { return 1; } @@ -29,7 +31,7 @@ int get_v(T* t) { // CHECK-NULL: load ptr, ptr {{.*}} // CHECK-PTRAUTH: [[CAST_VTABLE:%.*]] = ptrtoint ptr %vtable to i64 - // CHECK-PTRAUTH: [[STRIPPED_VTABLE:%.*]] = call i64 @llvm.ptrauth.strip(i64 [[CAST_VTABLE]], i32 0), !nosanitize !2 + // CHECK-PTRAUTH: [[STRIPPED_VTABLE:%.*]] = call i64 @llvm.ptrauth.strip(i64 [[CAST_VTABLE]], i32 0), !nosanitize // CHECK-PTRAUTH: [[STRIPPED_PTR:%.*]] = inttoptr i64 [[STRIPPED_VTABLE]] to ptr // CHECK-PTRAUTH: [[STRIPPED_INT:%.*]] = ptrtoint ptr [[STRIPPED_PTR]] to i64 // Make sure authed vtable pointer feeds into hashing diff --git a/clang/test/CodeGenCXX/x86_32-vaarg.cpp b/clang/test/CodeGenCXX/x86_32-vaarg.cpp index a3f2791484362..90665652a0286 100644 --- a/clang/test/CodeGenCXX/x86_32-vaarg.cpp +++ b/clang/test/CodeGenCXX/x86_32-vaarg.cpp @@ -18,3 +18,25 @@ empty empty_record_test(int z, ...) { __builtin_va_start(list, z); return __builtin_va_arg(list, empty); } + +typedef struct { + struct { + int a[0]; + } b; +} SortOfEmpty; + +// CHECK-LABEL: @_Z18test_sort_of_emptyiz( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[Z_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[LIST:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 +// CHECK-NEXT: store i32 [[Z:%.*]], ptr [[Z_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.va_start.p0(ptr [[LIST]]) +// CHECK-NEXT: ret void +// +SortOfEmpty test_sort_of_empty(int z, ...) { + __builtin_va_list list; + __builtin_va_start(list, z); + return __builtin_va_arg(list, SortOfEmpty); +} diff --git a/clang/test/CodeGenCoroutines/coro-elide-thinlto.cpp b/clang/test/CodeGenCoroutines/coro-elide-thinlto.cpp new file mode 100644 index 0000000000000..54063cf0704aa --- /dev/null +++ b/clang/test/CodeGenCoroutines/coro-elide-thinlto.cpp @@ -0,0 +1,78 @@ +// REQUIRES: x86_64-linux +// This tests that the coroutine elide optimization could happen succesfully with ThinLTO. +// This test is adapted from coro-elide.cpp and splits functions into two files. +// +// RUN: split-file %s %t +// RUN: %clang --target=x86_64-linux -std=c++20 -O2 -flto=thin -I %S -c %t/coro-elide-callee.cpp -o %t/coro-elide-callee.bc +// RUN: %clang --target=x86_64-linux -std=c++20 -O2 -flto=thin -I %S -c %t/coro-elide-caller.cpp -o %t/coro-elide-caller.bc +// RUN: llvm-lto --thinlto %t/coro-elide-callee.bc %t/coro-elide-caller.bc -o %t/summary +// RUN: %clang_cc1 -O2 -x ir %t/coro-elide-caller.bc -fthinlto-index=%t/summary.thinlto.bc -emit-llvm -o - | FileCheck %s + +//--- coro-elide-task.h +#pragma once +#include "Inputs/coroutine.h" + +struct Task { + struct promise_type { + struct FinalAwaiter { + bool await_ready() const noexcept { return false; } + template + std::coroutine_handle<> await_suspend(std::coroutine_handle h) noexcept { + if (!h) + return std::noop_coroutine(); + return h.promise().continuation; + } + void await_resume() noexcept {} + }; + Task get_return_object() noexcept { + return std::coroutine_handle::from_promise(*this); + } + std::suspend_always initial_suspend() noexcept { return {}; } + FinalAwaiter final_suspend() noexcept { return {}; } + void unhandled_exception() noexcept {} + void return_value(int x) noexcept { + _value = x; + } + std::coroutine_handle<> continuation; + int _value; + }; + + Task(std::coroutine_handle handle) : handle(handle) {} + ~Task() { + if (handle) + handle.destroy(); + } + + struct Awaiter { + bool await_ready() const noexcept { return false; } + void await_suspend(std::coroutine_handle continuation) noexcept {} + int await_resume() noexcept { + return 43; + } + }; + + auto operator co_await() { + return Awaiter{}; + } + +private: + std::coroutine_handle handle; +}; + +//--- coro-elide-callee.cpp +#include "coro-elide-task.h" +Task task0() { + co_return 43; +} + +//--- coro-elide-caller.cpp +#include "coro-elide-task.h" + +Task task0(); + +Task task1() { + co_return co_await task0(); +} + +// CHECK-LABEL: define{{.*}} void @_Z5task1v.resume +// CHECK-NOT: {{.*}}_Znwm diff --git a/clang/test/CodeGenHIP/dpp-const-fold.hip b/clang/test/CodeGenHIP/dpp-const-fold.hip index f5a97c6b0e77f..c5450ec4b8413 100644 --- a/clang/test/CodeGenHIP/dpp-const-fold.hip +++ b/clang/test/CodeGenHIP/dpp-const-fold.hip @@ -22,25 +22,25 @@ constexpr static bool BountCtrl() return true & false; } -// CHECK: call i32 @llvm.amdgcn.update.dpp.i32(i32 %1, i32 %2, i32 16, i32 0, i32 0, i1 false) +// CHECK: call i32 @llvm.amdgcn.update.dpp.i32(i32 %0, i32 %1, i32 16, i32 0, i32 0, i1 false) __attribute__((global)) void test_update_dpp_const_fold_imm_operand_2(int* out, int a, int b) { *out = __builtin_amdgcn_update_dpp(a, b, OpCtrl(), 0, 0, false); } -// CHECK: call i32 @llvm.amdgcn.update.dpp.i32(i32 %1, i32 %2, i32 0, i32 4, i32 0, i1 false) +// CHECK: call i32 @llvm.amdgcn.update.dpp.i32(i32 %0, i32 %1, i32 0, i32 4, i32 0, i1 false) __attribute__((global)) void test_update_dpp_const_fold_imm_operand_3(int* out, int a, int b) { *out = __builtin_amdgcn_update_dpp(a, b, 0, RowMask(), 0, false); } -// CHECK: call i32 @llvm.amdgcn.update.dpp.i32(i32 %1, i32 %2, i32 0, i32 0, i32 3, i1 false) +// CHECK: call i32 @llvm.amdgcn.update.dpp.i32(i32 %0, i32 %1, i32 0, i32 0, i32 3, i1 false) __attribute__((global)) void test_update_dpp_const_fold_imm_operand_4(int* out, int a, int b) { *out = __builtin_amdgcn_update_dpp(a, b, 0, 0, BankMask(), false); } -// CHECK: call i32 @llvm.amdgcn.update.dpp.i32(i32 %1, i32 %2, i32 0, i32 0, i32 0, i1 false) +// CHECK: call i32 @llvm.amdgcn.update.dpp.i32(i32 %0, i32 %1, i32 0, i32 0, i32 0, i1 false) __attribute__((global)) void test_update_dpp_const_fold_imm_operand_5(int* out, int a, int b) { *out = __builtin_amdgcn_update_dpp(a, b, 0, 0, 0, BountCtrl()); diff --git a/clang/test/CodeGenHIP/spirv-amdgcn-dpp-const-fold.hip b/clang/test/CodeGenHIP/spirv-amdgcn-dpp-const-fold.hip index 2b785200e8eea..71270bc1c68d8 100644 --- a/clang/test/CodeGenHIP/spirv-amdgcn-dpp-const-fold.hip +++ b/clang/test/CodeGenHIP/spirv-amdgcn-dpp-const-fold.hip @@ -21,25 +21,25 @@ constexpr static bool BountCtrl() return true & false; } -// CHECK: call{{.*}} i32 @llvm.amdgcn.update.dpp.i32(i32 %1, i32 %2, i32 16, i32 0, i32 0, i1 false) +// CHECK: call{{.*}} i32 @llvm.amdgcn.update.dpp.i32(i32 %0, i32 %1, i32 16, i32 0, i32 0, i1 false) __attribute__((global)) void test_update_dpp_const_fold_imm_operand_2(int* out, int a, int b) { *out = __builtin_amdgcn_update_dpp(a, b, OpCtrl(), 0, 0, false); } -// CHECK: call{{.*}} i32 @llvm.amdgcn.update.dpp.i32(i32 %1, i32 %2, i32 0, i32 4, i32 0, i1 false) +// CHECK: call{{.*}} i32 @llvm.amdgcn.update.dpp.i32(i32 %0, i32 %1, i32 0, i32 4, i32 0, i1 false) __attribute__((global)) void test_update_dpp_const_fold_imm_operand_3(int* out, int a, int b) { *out = __builtin_amdgcn_update_dpp(a, b, 0, RowMask(), 0, false); } -// CHECK: call{{.*}} i32 @llvm.amdgcn.update.dpp.i32(i32 %1, i32 %2, i32 0, i32 0, i32 3, i1 false) +// CHECK: call{{.*}} i32 @llvm.amdgcn.update.dpp.i32(i32 %0, i32 %1, i32 0, i32 0, i32 3, i1 false) __attribute__((global)) void test_update_dpp_const_fold_imm_operand_4(int* out, int a, int b) { *out = __builtin_amdgcn_update_dpp(a, b, 0, 0, BankMask(), false); } -// CHECK: call{{.*}} i32 @llvm.amdgcn.update.dpp.i32(i32 %1, i32 %2, i32 0, i32 0, i32 0, i1 false) +// CHECK: call{{.*}} i32 @llvm.amdgcn.update.dpp.i32(i32 %0, i32 %1, i32 0, i32 0, i32 0, i1 false) __attribute__((global)) void test_update_dpp_const_fold_imm_operand_5(int* out, int a, int b) { *out = __builtin_amdgcn_update_dpp(a, b, 0, 0, 0, BountCtrl()); diff --git a/clang/test/CodeGenHLSL/builtins/frac.hlsl b/clang/test/CodeGenHLSL/builtins/frac.hlsl index 7c4d1468e96d2..b457f5c278791 100644 --- a/clang/test/CodeGenHLSL/builtins/frac.hlsl +++ b/clang/test/CodeGenHLSL/builtins/frac.hlsl @@ -1,53 +1,84 @@ // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ -// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ -// RUN: --check-prefixes=CHECK,NATIVE_HALF +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECK,DXIL_CHECK,DXIL_NATIVE_HALF,NATIVE_HALF // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ -// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF +// RUN: -o - | FileCheck %s --check-prefixes=CHECK,DXIL_CHECK,NO_HALF,DXIL_NO_HALF +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECK,SPIR_CHECK,NATIVE_HALF,SPIR_NATIVE_HALF +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ +// RUN: -o - | FileCheck %s --check-prefixes=CHECK,SPIR_CHECK,NO_HALF,SPIR_NO_HALF -// NATIVE_HALF: define noundef half @ -// NATIVE_HALF: %dx.frac = call half @llvm.dx.frac.f16( -// NATIVE_HALF: ret half %dx.frac -// NO_HALF: define noundef float @"?test_frac_half@@YA$halff@$halff@@Z"( -// NO_HALF: %dx.frac = call float @llvm.dx.frac.f32( -// NO_HALF: ret float %dx.frac +// DXIL_NATIVE_HALF: define noundef half @ +// SPIR_NATIVE_HALF: define spir_func noundef half @ +// DXIL_NATIVE_HALF: %hlsl.frac = call half @llvm.dx.frac.f16( +// SPIR_NATIVE_HALF: %hlsl.frac = call half @llvm.spv.frac.f16( +// NATIVE_HALF: ret half %hlsl.frac +// DXIL_NO_HALF: define noundef float @ +// SPIR_NO_HALF: define spir_func noundef float @ +// DXIL_NO_HALF: %hlsl.frac = call float @llvm.dx.frac.f32( +// SPIR_NO_HALF: %hlsl.frac = call float @llvm.spv.frac.f32( +// NO_HALF: ret float %hlsl.frac half test_frac_half(half p0) { return frac(p0); } -// NATIVE_HALF: define noundef <2 x half> @ -// NATIVE_HALF: %dx.frac = call <2 x half> @llvm.dx.frac.v2f16 -// NATIVE_HALF: ret <2 x half> %dx.frac -// NO_HALF: define noundef <2 x float> @ -// NO_HALF: %dx.frac = call <2 x float> @llvm.dx.frac.v2f32( -// NO_HALF: ret <2 x float> %dx.frac +// DXIL_NATIVE_HALF: define noundef <2 x half> @ +// SPIR_NATIVE_HALF: define spir_func noundef <2 x half> @ +// DXIL_NATIVE_HALF: %hlsl.frac = call <2 x half> @llvm.dx.frac.v2f16 +// SPIR_NATIVE_HALF: %hlsl.frac = call <2 x half> @llvm.spv.frac.v2f16 +// NATIVE_HALF: ret <2 x half> %hlsl.frac +// DXIL_NO_HALF: define noundef <2 x float> @ +// SPIR_NO_HALF: define spir_func noundef <2 x float> @ +// DXIL_NO_HALF: %hlsl.frac = call <2 x float> @llvm.dx.frac.v2f32( +// SPIR_NO_HALF: %hlsl.frac = call <2 x float> @llvm.spv.frac.v2f32( +// NO_HALF: ret <2 x float> %hlsl.frac half2 test_frac_half2(half2 p0) { return frac(p0); } -// NATIVE_HALF: define noundef <3 x half> @ -// NATIVE_HALF: %dx.frac = call <3 x half> @llvm.dx.frac.v3f16 -// NATIVE_HALF: ret <3 x half> %dx.frac -// NO_HALF: define noundef <3 x float> @ -// NO_HALF: %dx.frac = call <3 x float> @llvm.dx.frac.v3f32( -// NO_HALF: ret <3 x float> %dx.frac +// DXIL_NATIVE_HALF: define noundef <3 x half> @ +// SPIR_NATIVE_HALF: define spir_func noundef <3 x half> @ +// DXIL_NATIVE_HALF: %hlsl.frac = call <3 x half> @llvm.dx.frac.v3f16 +// SPIR_NATIVE_HALF: %hlsl.frac = call <3 x half> @llvm.spv.frac.v3f16 +// NATIVE_HALF: ret <3 x half> %hlsl.frac +// DXIL_NO_HALF: define noundef <3 x float> @ +// SPIR_NO_HALF: define spir_func noundef <3 x float> @ +// DXIL_NO_HALF: %hlsl.frac = call <3 x float> @llvm.dx.frac.v3f32( +// SPIR_NO_HALF: %hlsl.frac = call <3 x float> @llvm.spv.frac.v3f32( +// NO_HALF: ret <3 x float> %hlsl.frac half3 test_frac_half3(half3 p0) { return frac(p0); } -// NATIVE_HALF: define noundef <4 x half> @ -// NATIVE_HALF: %dx.frac = call <4 x half> @llvm.dx.frac.v4f16 -// NATIVE_HALF: ret <4 x half> %dx.frac -// NO_HALF: define noundef <4 x float> @ -// NO_HALF: %dx.frac = call <4 x float> @llvm.dx.frac.v4f32( -// NO_HALF: ret <4 x float> %dx.frac +// DXIL_NATIVE_HALF: define noundef <4 x half> @ +// SPIR_NATIVE_HALF: define spir_func noundef <4 x half> @ +// DXIL_NATIVE_HALF: %hlsl.frac = call <4 x half> @llvm.dx.frac.v4f16 +// SPIR_NATIVE_HALF: %hlsl.frac = call <4 x half> @llvm.spv.frac.v4f16 +// NATIVE_HALF: ret <4 x half> %hlsl.frac +// DXIL_NO_HALF: define noundef <4 x float> @ +// SPIR_NO_HALF: define spir_func noundef <4 x float> @ +// DXIL_NO_HALF: %hlsl.frac = call <4 x float> @llvm.dx.frac.v4f32( +// SPIR_NO_HALF: %hlsl.frac = call <4 x float> @llvm.spv.frac.v4f32( +// NO_HALF: ret <4 x float> %hlsl.frac half4 test_frac_half4(half4 p0) { return frac(p0); } -// CHECK: define noundef float @ -// CHECK: %dx.frac = call float @llvm.dx.frac.f32( -// CHECK: ret float %dx.frac +// DXIL_CHECK: define noundef float @ +// SPIR_CHECK: define spir_func noundef float @ +// DXIL_CHECK: %hlsl.frac = call float @llvm.dx.frac.f32( +// SPIR_CHECK: %hlsl.frac = call float @llvm.spv.frac.f32( +// CHECK: ret float %hlsl.frac float test_frac_float(float p0) { return frac(p0); } -// CHECK: define noundef <2 x float> @ -// CHECK: %dx.frac = call <2 x float> @llvm.dx.frac.v2f32 -// CHECK: ret <2 x float> %dx.frac +// DXIL_CHECK: define noundef <2 x float> @ +// SPIR_CHECK: define spir_func noundef <2 x float> @ +// DXIL_CHECK: %hlsl.frac = call <2 x float> @llvm.dx.frac.v2f32 +// SPIR_CHECK: %hlsl.frac = call <2 x float> @llvm.spv.frac.v2f32 +// CHECK: ret <2 x float> %hlsl.frac float2 test_frac_float2(float2 p0) { return frac(p0); } -// CHECK: define noundef <3 x float> @ -// CHECK: %dx.frac = call <3 x float> @llvm.dx.frac.v3f32 -// CHECK: ret <3 x float> %dx.frac +// DXIL_CHECK: define noundef <3 x float> @ +// SPIR_CHECK: define spir_func noundef <3 x float> @ +// DXIL_CHECK: %hlsl.frac = call <3 x float> @llvm.dx.frac.v3f32 +// SPIR_CHECK: %hlsl.frac = call <3 x float> @llvm.spv.frac.v3f32 +// CHECK: ret <3 x float> %hlsl.frac float3 test_frac_float3(float3 p0) { return frac(p0); } -// CHECK: define noundef <4 x float> @ -// CHECK: %dx.frac = call <4 x float> @llvm.dx.frac.v4f32 -// CHECK: ret <4 x float> %dx.frac +// DXIL_CHECK: define noundef <4 x float> @ +// SPIR_CHECK: define spir_func noundef <4 x float> @ +// DXIL_CHECK: %hlsl.frac = call <4 x float> @llvm.dx.frac.v4f32 +// SPIR_CHECK: %hlsl.frac = call <4 x float> @llvm.spv.frac.v4f32 +// CHECK: ret <4 x float> %hlsl.frac float4 test_frac_float4(float4 p0) { return frac(p0); } diff --git a/clang/test/CodeGenOpenCL/addr-space-struct-arg.cl b/clang/test/CodeGenOpenCL/addr-space-struct-arg.cl index 385f8a753cd8e..1651cb379a20f 100644 --- a/clang/test/CodeGenOpenCL/addr-space-struct-arg.cl +++ b/clang/test/CodeGenOpenCL/addr-space-struct-arg.cl @@ -145,7 +145,9 @@ kernel void KernelOneMemberSpir(global struct StructOneMember* u) { // AMDGCN-LABEL: define{{.*}} amdgpu_kernel void @KernelLargeOneMember( // AMDGCN: %[[U:.*]] = alloca %struct.LargeStructOneMember, align 8, addrspace(5) -// AMDGCN: store %struct.LargeStructOneMember %u.coerce, ptr addrspace(5) %[[U]], align 8 +// AMDGCN: %[[U_ELEM:.*]] = getelementptr inbounds %struct.LargeStructOneMember, ptr addrspace(5) %[[U]], i32 0, i32 0 +// AMDGCN: %[[EXTRACT:.*]] = extractvalue %struct.LargeStructOneMember %u.coerce, 0 +// AMDGCN: store [100 x <2 x i32>] %[[EXTRACT]], ptr addrspace(5) %[[U_ELEM]], align 8 // AMDGCN: call void @FuncOneLargeMember(ptr addrspace(5) noundef byref(%struct.LargeStructOneMember) align 8 %[[U]]) kernel void KernelLargeOneMember(struct LargeStructOneMember u) { FuncOneLargeMember(u); @@ -177,7 +179,12 @@ kernel void KernelTwoMember(struct StructTwoMember u) { // AMDGCN-LABEL: define{{.*}} amdgpu_kernel void @KernelLargeTwoMember // AMDGCN-SAME: (%struct.LargeStructTwoMember %[[u_coerce:.*]]) // AMDGCN: %[[u:.*]] = alloca %struct.LargeStructTwoMember, align 8, addrspace(5) -// AMDGCN: store %struct.LargeStructTwoMember %[[u_coerce]], ptr addrspace(5) %[[u]] +// AMDGCN: %[[U_PTR0:.*]] = getelementptr inbounds %struct.LargeStructTwoMember, ptr addrspace(5) %[[u]], i32 0, i32 0 +// AMDGCN: %[[EXTRACT0:.*]] = extractvalue %struct.LargeStructTwoMember %u.coerce, 0 +// AMDGCN: store [40 x <2 x i32>] %[[EXTRACT0]], ptr addrspace(5) %[[U_PTR0]] +// AMDGCN: %[[U_PTR1:.*]] = getelementptr inbounds %struct.LargeStructTwoMember, ptr addrspace(5) %[[u]], i32 0, i32 1 +// AMDGCN: %[[EXTRACT1:.*]] = extractvalue %struct.LargeStructTwoMember %u.coerce, 1 +// AMDGCN: store [20 x <2 x i32>] %[[EXTRACT1]], ptr addrspace(5) %[[U_PTR1]] // AMDGCN: call void @FuncLargeTwoMember(ptr addrspace(5) noundef byref(%struct.LargeStructTwoMember) align 8 %[[u]]) kernel void KernelLargeTwoMember(struct LargeStructTwoMember u) { FuncLargeTwoMember(u); diff --git a/clang/test/CodeGenOpenCL/amdgpu-abi-struct-arg-byref.cl b/clang/test/CodeGenOpenCL/amdgpu-abi-struct-arg-byref.cl index fa83a38a01b0a..fe0a2f9578db0 100644 --- a/clang/test/CodeGenOpenCL/amdgpu-abi-struct-arg-byref.cl +++ b/clang/test/CodeGenOpenCL/amdgpu-abi-struct-arg-byref.cl @@ -61,7 +61,7 @@ Mat4X4 __attribute__((noinline)) foo(Mat3X3 in) { // the return value. // AMDGCN-LABEL: define dso_local amdgpu_kernel void @ker -// AMDGCN-SAME: (ptr addrspace(1) noundef align 4 [[IN:%.*]], ptr addrspace(1) noundef align 4 [[OUT:%.*]]) #[[ATTR1:[0-9]+]] !kernel_arg_addr_space !4 !kernel_arg_access_qual !5 !kernel_arg_type !6 !kernel_arg_base_type !6 !kernel_arg_type_qual !7 { +// AMDGCN-SAME: (ptr addrspace(1) noundef align 4 [[IN:%.*]], ptr addrspace(1) noundef align 4 [[OUT:%.*]]) #[[ATTR1:[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]+]] { // AMDGCN-NEXT: entry: // AMDGCN-NEXT: [[IN_ADDR:%.*]] = alloca ptr addrspace(1), align 8, addrspace(5) // AMDGCN-NEXT: [[OUT_ADDR:%.*]] = alloca ptr addrspace(1), align 8, addrspace(5) @@ -74,7 +74,7 @@ Mat4X4 __attribute__((noinline)) foo(Mat3X3 in) { // AMDGCN-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [[STRUCT_MAT3X3:%.*]], ptr addrspace(1) [[TMP1]], i64 1 // AMDGCN-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT_MAT3X3]], ptr addrspace(1) [[ARRAYIDX1]], i32 0, i32 0 // AMDGCN-NEXT: [[TMP3:%.*]] = load [9 x i32], ptr addrspace(1) [[TMP2]], align 4 -// AMDGCN-NEXT: [[CALL:%.*]] = call [[STRUCT_MAT4X4]] @foo([9 x i32] [[TMP3]]) #[[ATTR3:[0-9]+]] +// AMDGCN-NEXT: [[CALL:%.*]] = call [[STRUCT_MAT4X4]] @[[FOO:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]]([9 x i32] [[TMP3]]) #[[ATTR3:[0-9]+]] // AMDGCN-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_MAT4X4]], ptr addrspace(5) [[TMP]], i32 0, i32 0 // AMDGCN-NEXT: [[TMP5:%.*]] = extractvalue [[STRUCT_MAT4X4]] [[CALL]], 0 // AMDGCN-NEXT: store [16 x i32] [[TMP5]], ptr addrspace(5) [[TMP4]], align 4 @@ -98,7 +98,7 @@ Mat64X64 __attribute__((noinline)) foo_large(Mat32X32 in) { } // AMDGCN-LABEL: define dso_local amdgpu_kernel void @ker_large -// AMDGCN-SAME: (ptr addrspace(1) noundef align 4 [[IN:%.*]], ptr addrspace(1) noundef align 4 [[OUT:%.*]]) #[[ATTR1]] !kernel_arg_addr_space !4 !kernel_arg_access_qual !5 !kernel_arg_type !8 !kernel_arg_base_type !8 !kernel_arg_type_qual !7 { +// AMDGCN-SAME: (ptr addrspace(1) noundef align 4 [[IN:%.*]], ptr addrspace(1) noundef align 4 [[OUT:%.*]]) #[[ATTR1]] !kernel_arg_addr_space [[META4]] !kernel_arg_access_qual [[META5]] !kernel_arg_type [[META8:![0-9]+]] !kernel_arg_base_type [[META8]] !kernel_arg_type_qual [[META7]] { // AMDGCN-NEXT: entry: // AMDGCN-NEXT: [[IN_ADDR:%.*]] = alloca ptr addrspace(1), align 8, addrspace(5) // AMDGCN-NEXT: [[OUT_ADDR:%.*]] = alloca ptr addrspace(1), align 8, addrspace(5) @@ -168,7 +168,7 @@ void test_indirect_arg_globl(void) { #endif // AMDGCN-LABEL: define dso_local amdgpu_kernel void @test_indirect_arg_local -// AMDGCN-SAME: () #[[ATTR1]] !kernel_arg_addr_space !9 !kernel_arg_access_qual !9 !kernel_arg_type !9 !kernel_arg_base_type !9 !kernel_arg_type_qual !9 { +// AMDGCN-SAME: () #[[ATTR1]] !kernel_arg_addr_space [[META9:![0-9]+]] !kernel_arg_access_qual [[META9]] !kernel_arg_type [[META9]] !kernel_arg_base_type [[META9]] !kernel_arg_type_qual [[META9]] { // AMDGCN-NEXT: entry: // AMDGCN-NEXT: [[BYVAL_TEMP:%.*]] = alloca [[STRUCT_LARGESTRUCTONEMEMBER:%.*]], align 8, addrspace(5) // AMDGCN-NEXT: call void @llvm.memcpy.p5.p3.i64(ptr addrspace(5) align 8 [[BYVAL_TEMP]], ptr addrspace(3) align 8 @test_indirect_arg_local.l_s, i64 800, i1 false) @@ -193,7 +193,7 @@ void test_indirect_arg_private(void) { } // AMDGCN-LABEL: define dso_local amdgpu_kernel void @KernelOneMember -// AMDGCN-SAME: (<2 x i32> [[U_COERCE:%.*]]) #[[ATTR1]] !kernel_arg_addr_space !10 !kernel_arg_access_qual !11 !kernel_arg_type !12 !kernel_arg_base_type !12 !kernel_arg_type_qual !13 { +// AMDGCN-SAME: (<2 x i32> [[U_COERCE:%.*]]) #[[ATTR1]] !kernel_arg_addr_space [[META10:![0-9]+]] !kernel_arg_access_qual [[META11:![0-9]+]] !kernel_arg_type [[META12:![0-9]+]] !kernel_arg_base_type [[META12]] !kernel_arg_type_qual [[META13:![0-9]+]] { // AMDGCN-NEXT: entry: // AMDGCN-NEXT: [[U:%.*]] = alloca [[STRUCT_STRUCTONEMEMBER:%.*]], align 8, addrspace(5) // AMDGCN-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds [[STRUCT_STRUCTONEMEMBER]], ptr addrspace(5) [[U]], i32 0, i32 0 @@ -208,7 +208,7 @@ kernel void KernelOneMember(struct StructOneMember u) { } // AMDGCN-LABEL: define dso_local amdgpu_kernel void @KernelOneMemberSpir -// AMDGCN-SAME: (ptr addrspace(1) noundef align 8 [[U:%.*]]) #[[ATTR1]] !kernel_arg_addr_space !14 !kernel_arg_access_qual !11 !kernel_arg_type !15 !kernel_arg_base_type !15 !kernel_arg_type_qual !13 { +// AMDGCN-SAME: (ptr addrspace(1) noundef align 8 [[U:%.*]]) #[[ATTR1]] !kernel_arg_addr_space [[META14:![0-9]+]] !kernel_arg_access_qual [[META11]] !kernel_arg_type [[META15:![0-9]+]] !kernel_arg_base_type [[META15]] !kernel_arg_type_qual [[META13]] { // AMDGCN-NEXT: entry: // AMDGCN-NEXT: [[U_ADDR:%.*]] = alloca ptr addrspace(1), align 8, addrspace(5) // AMDGCN-NEXT: store ptr addrspace(1) [[U]], ptr addrspace(5) [[U_ADDR]], align 8 @@ -223,10 +223,12 @@ kernel void KernelOneMemberSpir(global struct StructOneMember* u) { } // AMDGCN-LABEL: define dso_local amdgpu_kernel void @KernelLargeOneMember -// AMDGCN-SAME: ([[STRUCT_LARGESTRUCTONEMEMBER:%.*]] [[U_COERCE:%.*]]) #[[ATTR1]] !kernel_arg_addr_space !10 !kernel_arg_access_qual !11 !kernel_arg_type !16 !kernel_arg_base_type !16 !kernel_arg_type_qual !13 { +// AMDGCN-SAME: ([[STRUCT_LARGESTRUCTONEMEMBER:%.*]] [[U_COERCE:%.*]]) #[[ATTR1]] !kernel_arg_addr_space [[META10]] !kernel_arg_access_qual [[META11]] !kernel_arg_type [[META16:![0-9]+]] !kernel_arg_base_type [[META16]] !kernel_arg_type_qual [[META13]] { // AMDGCN-NEXT: entry: // AMDGCN-NEXT: [[U:%.*]] = alloca [[STRUCT_LARGESTRUCTONEMEMBER]], align 8, addrspace(5) -// AMDGCN-NEXT: store [[STRUCT_LARGESTRUCTONEMEMBER]] [[U_COERCE]], ptr addrspace(5) [[U]], align 8 +// AMDGCN-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_LARGESTRUCTONEMEMBER]], ptr addrspace(5) [[U]], i32 0, i32 0 +// AMDGCN-NEXT: [[TMP1:%.*]] = extractvalue [[STRUCT_LARGESTRUCTONEMEMBER]] [[U_COERCE]], 0 +// AMDGCN-NEXT: store [100 x <2 x i32>] [[TMP1]], ptr addrspace(5) [[TMP0]], align 8 // AMDGCN-NEXT: call void @FuncOneLargeMember(ptr addrspace(5) noundef byref([[STRUCT_LARGESTRUCTONEMEMBER]]) align 8 [[U]]) #[[ATTR3]] // AMDGCN-NEXT: ret void // @@ -271,15 +273,20 @@ void FuncLargeTwoMember(struct LargeStructTwoMember u) { } // AMDGCN-LABEL: define dso_local amdgpu_kernel void @KernelTwoMember -// AMDGCN-SAME: ([[STRUCT_STRUCTTWOMEMBER:%.*]] [[U_COERCE:%.*]]) #[[ATTR1]] !kernel_arg_addr_space !10 !kernel_arg_access_qual !11 !kernel_arg_type !17 !kernel_arg_base_type !17 !kernel_arg_type_qual !13 { +// AMDGCN-SAME: ([[STRUCT_STRUCTTWOMEMBER:%.*]] [[U_COERCE:%.*]]) #[[ATTR1]] !kernel_arg_addr_space [[META10]] !kernel_arg_access_qual [[META11]] !kernel_arg_type [[META17:![0-9]+]] !kernel_arg_base_type [[META17]] !kernel_arg_type_qual [[META13]] { // AMDGCN-NEXT: entry: // AMDGCN-NEXT: [[U:%.*]] = alloca [[STRUCT_STRUCTTWOMEMBER]], align 8, addrspace(5) -// AMDGCN-NEXT: store [[STRUCT_STRUCTTWOMEMBER]] [[U_COERCE]], ptr addrspace(5) [[U]], align 8 // AMDGCN-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_STRUCTTWOMEMBER]], ptr addrspace(5) [[U]], i32 0, i32 0 -// AMDGCN-NEXT: [[TMP1:%.*]] = load <2 x i32>, ptr addrspace(5) [[TMP0]], align 8 +// AMDGCN-NEXT: [[TMP1:%.*]] = extractvalue [[STRUCT_STRUCTTWOMEMBER]] [[U_COERCE]], 0 +// AMDGCN-NEXT: store <2 x i32> [[TMP1]], ptr addrspace(5) [[TMP0]], align 8 // AMDGCN-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT_STRUCTTWOMEMBER]], ptr addrspace(5) [[U]], i32 0, i32 1 -// AMDGCN-NEXT: [[TMP3:%.*]] = load <2 x i32>, ptr addrspace(5) [[TMP2]], align 8 -// AMDGCN-NEXT: call void @FuncTwoMember(<2 x i32> [[TMP1]], <2 x i32> [[TMP3]]) #[[ATTR3]] +// AMDGCN-NEXT: [[TMP3:%.*]] = extractvalue [[STRUCT_STRUCTTWOMEMBER]] [[U_COERCE]], 1 +// AMDGCN-NEXT: store <2 x i32> [[TMP3]], ptr addrspace(5) [[TMP2]], align 8 +// AMDGCN-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_STRUCTTWOMEMBER]], ptr addrspace(5) [[U]], i32 0, i32 0 +// AMDGCN-NEXT: [[TMP5:%.*]] = load <2 x i32>, ptr addrspace(5) [[TMP4]], align 8 +// AMDGCN-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT_STRUCTTWOMEMBER]], ptr addrspace(5) [[U]], i32 0, i32 1 +// AMDGCN-NEXT: [[TMP7:%.*]] = load <2 x i32>, ptr addrspace(5) [[TMP6]], align 8 +// AMDGCN-NEXT: call void @FuncTwoMember(<2 x i32> [[TMP5]], <2 x i32> [[TMP7]]) #[[ATTR3]] // AMDGCN-NEXT: ret void // kernel void KernelTwoMember(struct StructTwoMember u) { @@ -287,10 +294,15 @@ kernel void KernelTwoMember(struct StructTwoMember u) { } // AMDGCN-LABEL: define dso_local amdgpu_kernel void @KernelLargeTwoMember -// AMDGCN-SAME: ([[STRUCT_LARGESTRUCTTWOMEMBER:%.*]] [[U_COERCE:%.*]]) #[[ATTR1]] !kernel_arg_addr_space !10 !kernel_arg_access_qual !11 !kernel_arg_type !18 !kernel_arg_base_type !18 !kernel_arg_type_qual !13 { +// AMDGCN-SAME: ([[STRUCT_LARGESTRUCTTWOMEMBER:%.*]] [[U_COERCE:%.*]]) #[[ATTR1]] !kernel_arg_addr_space [[META10]] !kernel_arg_access_qual [[META11]] !kernel_arg_type [[META18:![0-9]+]] !kernel_arg_base_type [[META18]] !kernel_arg_type_qual [[META13]] { // AMDGCN-NEXT: entry: // AMDGCN-NEXT: [[U:%.*]] = alloca [[STRUCT_LARGESTRUCTTWOMEMBER]], align 8, addrspace(5) -// AMDGCN-NEXT: store [[STRUCT_LARGESTRUCTTWOMEMBER]] [[U_COERCE]], ptr addrspace(5) [[U]], align 8 +// AMDGCN-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_LARGESTRUCTTWOMEMBER]], ptr addrspace(5) [[U]], i32 0, i32 0 +// AMDGCN-NEXT: [[TMP1:%.*]] = extractvalue [[STRUCT_LARGESTRUCTTWOMEMBER]] [[U_COERCE]], 0 +// AMDGCN-NEXT: store [40 x <2 x i32>] [[TMP1]], ptr addrspace(5) [[TMP0]], align 8 +// AMDGCN-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT_LARGESTRUCTTWOMEMBER]], ptr addrspace(5) [[U]], i32 0, i32 1 +// AMDGCN-NEXT: [[TMP3:%.*]] = extractvalue [[STRUCT_LARGESTRUCTTWOMEMBER]] [[U_COERCE]], 1 +// AMDGCN-NEXT: store [20 x <2 x i32>] [[TMP3]], ptr addrspace(5) [[TMP2]], align 8 // AMDGCN-NEXT: call void @FuncLargeTwoMember(ptr addrspace(5) noundef byref([[STRUCT_LARGESTRUCTTWOMEMBER]]) align 8 [[U]]) #[[ATTR3]] // AMDGCN-NEXT: ret void // diff --git a/clang/test/CodeGenOpenCL/builtins-alloca.cl b/clang/test/CodeGenOpenCL/builtins-alloca.cl new file mode 100644 index 0000000000000..474e95e74e006 --- /dev/null +++ b/clang/test/CodeGenOpenCL/builtins-alloca.cl @@ -0,0 +1,141 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL1.2 \ +// RUN: -emit-llvm -o - | FileCheck --check-prefixes=OPENCL %s +// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL2.0 \ +// RUN: -emit-llvm -o - | FileCheck --check-prefixes=OPENCL %s +// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL3.0 \ +// RUN: -emit-llvm -o - | FileCheck --check-prefixes=OPENCL %s +// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space \ +// RUN: -emit-llvm -o - | FileCheck --check-prefixes=OPENCL %s + +// OPENCL-LABEL: define dso_local void @test1_builtin_alloca( +// OPENCL-SAME: i32 noundef [[N:%.*]]) #[[ATTR0:[0-9]+]] { +// OPENCL-NEXT: [[ENTRY:.*:]] +// OPENCL-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// OPENCL-NEXT: [[ALLOC_PTR:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5) +// OPENCL-NEXT: store i32 [[N]], ptr addrspace(5) [[N_ADDR]], align 4 +// OPENCL-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[N_ADDR]], align 4 +// OPENCL-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64 +// OPENCL-NEXT: [[MUL:%.*]] = mul i64 [[CONV]], 4 +// OPENCL-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[MUL]], align 8, addrspace(5) +// OPENCL-NEXT: store ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[ALLOC_PTR]], align 4 +// OPENCL-NEXT: ret void +// +void test1_builtin_alloca(unsigned n) { + __private float* alloc_ptr = (__private float*)__builtin_alloca(n*sizeof(int)); +} + +// OPENCL-LABEL: define dso_local void @test1_builtin_alloca_uninitialized( +// OPENCL-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] { +// OPENCL-NEXT: [[ENTRY:.*:]] +// OPENCL-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// OPENCL-NEXT: [[ALLOC_PTR_UNINITIALIZED:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5) +// OPENCL-NEXT: store i32 [[N]], ptr addrspace(5) [[N_ADDR]], align 4 +// OPENCL-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[N_ADDR]], align 4 +// OPENCL-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64 +// OPENCL-NEXT: [[MUL:%.*]] = mul i64 [[CONV]], 4 +// OPENCL-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[MUL]], align 8, addrspace(5) +// OPENCL-NEXT: store ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[ALLOC_PTR_UNINITIALIZED]], align 4 +// OPENCL-NEXT: ret void +// +void test1_builtin_alloca_uninitialized(unsigned n) { + __private float* alloc_ptr_uninitialized = (__private float*)__builtin_alloca_uninitialized(n*sizeof(int)); +} + +// OPENCL-LABEL: define dso_local void @test1_builtin_alloca_with_align( +// OPENCL-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] { +// OPENCL-NEXT: [[ENTRY:.*:]] +// OPENCL-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// OPENCL-NEXT: [[ALLOC_PTR_ALIGN:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5) +// OPENCL-NEXT: store i32 [[N]], ptr addrspace(5) [[N_ADDR]], align 4 +// OPENCL-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[N_ADDR]], align 4 +// OPENCL-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64 +// OPENCL-NEXT: [[MUL:%.*]] = mul i64 [[CONV]], 4 +// OPENCL-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[MUL]], align 1, addrspace(5) +// OPENCL-NEXT: store ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[ALLOC_PTR_ALIGN]], align 4 +// OPENCL-NEXT: ret void +// +void test1_builtin_alloca_with_align(unsigned n) { + __private float* alloc_ptr_align = (__private float*)__builtin_alloca_with_align((n*sizeof(int)), 8); +} + +// OPENCL-LABEL: define dso_local void @test1_builtin_alloca_with_align_uninitialized( +// OPENCL-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] { +// OPENCL-NEXT: [[ENTRY:.*:]] +// OPENCL-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// OPENCL-NEXT: [[ALLOC_PTR_ALIGN_UNINITIALIZED:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5) +// OPENCL-NEXT: store i32 [[N]], ptr addrspace(5) [[N_ADDR]], align 4 +// OPENCL-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[N_ADDR]], align 4 +// OPENCL-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64 +// OPENCL-NEXT: [[MUL:%.*]] = mul i64 [[CONV]], 4 +// OPENCL-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[MUL]], align 1, addrspace(5) +// OPENCL-NEXT: store ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[ALLOC_PTR_ALIGN_UNINITIALIZED]], align 4 +// OPENCL-NEXT: ret void +// +void test1_builtin_alloca_with_align_uninitialized(unsigned n) { + __private float* alloc_ptr_align_uninitialized = (__private float*)__builtin_alloca_with_align_uninitialized((n*sizeof(int)), 8); +} + +// OPENCL-LABEL: define dso_local void @test2_builtin_alloca( +// OPENCL-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] { +// OPENCL-NEXT: [[ENTRY:.*:]] +// OPENCL-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// OPENCL-NEXT: [[ALLOC_PTR:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5) +// OPENCL-NEXT: store i32 [[N]], ptr addrspace(5) [[N_ADDR]], align 4 +// OPENCL-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[N_ADDR]], align 4 +// OPENCL-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64 +// OPENCL-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[CONV]], align 8, addrspace(5) +// OPENCL-NEXT: store ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[ALLOC_PTR]], align 4 +// OPENCL-NEXT: ret void +// +void test2_builtin_alloca(unsigned n) { + __private void *alloc_ptr = __builtin_alloca(n); +} + +// OPENCL-LABEL: define dso_local void @test2_builtin_alloca_uninitialized( +// OPENCL-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] { +// OPENCL-NEXT: [[ENTRY:.*:]] +// OPENCL-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// OPENCL-NEXT: [[ALLOC_PTR_UNINITIALIZED:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5) +// OPENCL-NEXT: store i32 [[N]], ptr addrspace(5) [[N_ADDR]], align 4 +// OPENCL-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[N_ADDR]], align 4 +// OPENCL-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64 +// OPENCL-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[CONV]], align 8, addrspace(5) +// OPENCL-NEXT: store ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[ALLOC_PTR_UNINITIALIZED]], align 4 +// OPENCL-NEXT: ret void +// +void test2_builtin_alloca_uninitialized(unsigned n) { + __private void *alloc_ptr_uninitialized = __builtin_alloca_uninitialized(n); +} + +// OPENCL-LABEL: define dso_local void @test2_builtin_alloca_with_align( +// OPENCL-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] { +// OPENCL-NEXT: [[ENTRY:.*:]] +// OPENCL-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// OPENCL-NEXT: [[ALLOC_PTR_ALIGN:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5) +// OPENCL-NEXT: store i32 [[N]], ptr addrspace(5) [[N_ADDR]], align 4 +// OPENCL-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[N_ADDR]], align 4 +// OPENCL-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64 +// OPENCL-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[CONV]], align 1, addrspace(5) +// OPENCL-NEXT: store ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[ALLOC_PTR_ALIGN]], align 4 +// OPENCL-NEXT: ret void +// +void test2_builtin_alloca_with_align(unsigned n) { + __private void *alloc_ptr_align = __builtin_alloca_with_align(n, 8); +} + +// OPENCL-LABEL: define dso_local void @test2_builtin_alloca_with_align_uninitialized( +// OPENCL-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] { +// OPENCL-NEXT: [[ENTRY:.*:]] +// OPENCL-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// OPENCL-NEXT: [[ALLOC_PTR_ALIGN_UNINITIALIZED:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5) +// OPENCL-NEXT: store i32 [[N]], ptr addrspace(5) [[N_ADDR]], align 4 +// OPENCL-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[N_ADDR]], align 4 +// OPENCL-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64 +// OPENCL-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[CONV]], align 1, addrspace(5) +// OPENCL-NEXT: store ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[ALLOC_PTR_ALIGN_UNINITIALIZED]], align 4 +// OPENCL-NEXT: ret void +// +void test2_builtin_alloca_with_align_uninitialized(unsigned n) { + __private void *alloc_ptr_align_uninitialized = __builtin_alloca_with_align_uninitialized(n, 8); +} diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-gfx11-err.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-gfx11-err.cl index 1fcb1d721ad72..8242ae6a98c40 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-gfx11-err.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-gfx11-err.cl @@ -5,13 +5,22 @@ typedef int v2i __attribute__((ext_vector_type(2))); typedef short v8s __attribute__((ext_vector_type(8))); +typedef half v8h __attribute__((ext_vector_type(8))); +typedef __bf16 v8y __attribute__((ext_vector_type(8))); typedef short v4s __attribute__((ext_vector_type(4))); +typedef half v4h __attribute__((ext_vector_type(4))); +typedef __bf16 v4y __attribute__((ext_vector_type(4))); -void amdgcn_global_load_tr(global v2i* v2i_inptr, global v8s* v8s_inptr, global int* int_inptr, global v4s* v4s_inptr) +void amdgcn_global_load_tr(global v2i* v2i_inptr, global v8s* v8s_inptr, global v8h* v8h_inptr, global v8y* v8y_inptr, + global int* int_inptr, global v4s* v4s_inptr, global v4h* v4h_inptr, global v4y* v4y_inptr) { v2i out_1 = __builtin_amdgcn_global_load_tr_b64_v2i32(v2i_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b64_v2i32' needs target feature gfx12-insts,wavefrontsize32}} v8s out_2 = __builtin_amdgcn_global_load_tr_b128_v8i16(v8s_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b128_v8i16' needs target feature gfx12-insts,wavefrontsize32}} + v8h out_3 = __builtin_amdgcn_global_load_tr_b128_v8f16(v8h_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b128_v8f16' needs target feature gfx12-insts,wavefrontsize32}} + v8y out_4 = __builtin_amdgcn_global_load_tr_b128_v8bf16(v8y_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b128_v8bf16' needs target feature gfx12-insts,wavefrontsize32}} - int out_3 = __builtin_amdgcn_global_load_tr_b64_i32(int_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b64_i32' needs target feature gfx12-insts,wavefrontsize64}} - v4s out_4 = __builtin_amdgcn_global_load_tr_b128_v4i16(v4s_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b128_v4i16' needs target feature gfx12-insts,wavefrontsize64}} + int out_5 = __builtin_amdgcn_global_load_tr_b64_i32(int_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b64_i32' needs target feature gfx12-insts,wavefrontsize64}} + v4s out_6 = __builtin_amdgcn_global_load_tr_b128_v4i16(v4s_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b128_v4i16' needs target feature gfx12-insts,wavefrontsize64}} + v4h out_7 = __builtin_amdgcn_global_load_tr_b128_v4f16(v4h_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b128_v4f16' needs target feature gfx12-insts,wavefrontsize64}} + v4y out_8 = __builtin_amdgcn_global_load_tr_b128_v4bf16(v4y_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b128_v4bf16' needs target feature gfx12-insts,wavefrontsize64}} } diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-gfx12-w32-err.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-gfx12-w32-err.cl index 7a36881c051b1..6f7a93ef897ac 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-gfx12-w32-err.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-gfx12-w32-err.cl @@ -4,9 +4,13 @@ // REQUIRES: amdgpu-registered-target typedef short v4s __attribute__((ext_vector_type(4))); +typedef half v4h __attribute__((ext_vector_type(4))); +typedef __bf16 v4y __attribute__((ext_vector_type(4))); -void amdgcn_global_load_tr(global int* int_inptr, global v4s* v4s_inptr) +void amdgcn_global_load_tr(global int* int_inptr, global v4s* v4s_inptr, global v4h* v4h_inptr, global v4y* v4y_inptr) { int out_1 = __builtin_amdgcn_global_load_tr_b64_i32(int_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b64_i32' needs target feature gfx12-insts,wavefrontsize64}} v4s out_2 = __builtin_amdgcn_global_load_tr_b128_v4i16(v4s_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b128_v4i16' needs target feature gfx12-insts,wavefrontsize64}} + v4h out_3 = __builtin_amdgcn_global_load_tr_b128_v4f16(v4h_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b128_v4f16' needs target feature gfx12-insts,wavefrontsize64}} + v4y out_4 = __builtin_amdgcn_global_load_tr_b128_v4bf16(v4y_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b128_v4bf16' needs target feature gfx12-insts,wavefrontsize64}} } diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-gfx12-w64-err.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-gfx12-w64-err.cl index 9155ee6e61822..b7323f1b41c2a 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-gfx12-w64-err.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-gfx12-w64-err.cl @@ -5,9 +5,13 @@ typedef int v2i __attribute__((ext_vector_type(2))); typedef short v8s __attribute__((ext_vector_type(8))); +typedef half v8h __attribute__((ext_vector_type(8))); +typedef __bf16 v8y __attribute__((ext_vector_type(8))); -void amdgcn_global_load_tr(global v2i* v2i_inptr, global v8s* v8s_inptr) +void amdgcn_global_load_tr(global v2i* v2i_inptr, global v8s* v8s_inptr, global v8h* v8h_inptr, global v8y* v8y_inptr) { v2i out_1 = __builtin_amdgcn_global_load_tr_b64_v2i32(v2i_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b64_v2i32' needs target feature gfx12-insts,wavefrontsize32}} v8s out_2 = __builtin_amdgcn_global_load_tr_b128_v8i16(v8s_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b128_v8i16' needs target feature gfx12-insts,wavefrontsize32}} + v8h out_3 = __builtin_amdgcn_global_load_tr_b128_v8f16(v8h_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b128_v8f16' needs target feature gfx12-insts,wavefrontsize32}} + v8y out_4 = __builtin_amdgcn_global_load_tr_b128_v8bf16(v8y_inptr); // expected-error{{'__builtin_amdgcn_global_load_tr_b128_v8bf16' needs target feature gfx12-insts,wavefrontsize32}} } diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-w32.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-w32.cl index ce8b2c2c7c5ba..186fc4eacfaaf 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-w32.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-w32.cl @@ -4,6 +4,8 @@ typedef int v2i __attribute__((ext_vector_type(2))); typedef short v8s __attribute__((ext_vector_type(8))); +typedef half v8h __attribute__((ext_vector_type(8))); +typedef __bf16 v8y __attribute__((ext_vector_type(8))); // CHECK-GFX1200-LABEL: @test_amdgcn_global_load_tr_b64_v2i32( // CHECK-GFX1200-NEXT: entry: @@ -24,3 +26,23 @@ v8s test_amdgcn_global_load_tr_b128_v8i16(global v8s* inptr) { return __builtin_amdgcn_global_load_tr_b128_v8i16(inptr); } + +// CHECK-GFX1200-LABEL: @test_amdgcn_global_load_tr_b128_v8f16( +// CHECK-GFX1200-NEXT: entry: +// CHECK-GFX1200-NEXT: [[TMP0:%.*]] = tail call <8 x half> @llvm.amdgcn.global.load.tr.b128.v8f16(ptr addrspace(1) [[INPTR:%.*]]) +// CHECK-GFX1200-NEXT: ret <8 x half> [[TMP0]] +// +v8h test_amdgcn_global_load_tr_b128_v8f16(global v8h* inptr) +{ + return __builtin_amdgcn_global_load_tr_b128_v8f16(inptr); +} + +// CHECK-GFX1200-LABEL: @test_amdgcn_global_load_tr_b128_v8bf16( +// CHECK-GFX1200-NEXT: entry: +// CHECK-GFX1200-NEXT: [[TMP0:%.*]] = tail call <8 x bfloat> @llvm.amdgcn.global.load.tr.b128.v8bf16(ptr addrspace(1) [[INPTR:%.*]]) +// CHECK-GFX1200-NEXT: ret <8 x bfloat> [[TMP0]] +// +v8y test_amdgcn_global_load_tr_b128_v8bf16(global v8y* inptr) +{ + return __builtin_amdgcn_global_load_tr_b128_v8bf16(inptr); +} diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-w64.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-w64.cl index b0eed07627f41..b6627f1c8114d 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-w64.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-global-load-tr-w64.cl @@ -3,6 +3,8 @@ // RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx1200 -target-feature +wavefrontsize64 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-GFX1200 typedef short v4s __attribute__((ext_vector_type(4))); +typedef half v4h __attribute__((ext_vector_type(4))); +typedef __bf16 v4y __attribute__((ext_vector_type(4))); // CHECK-GFX1200-LABEL: @test_amdgcn_global_load_tr_b64_i32( // CHECK-GFX1200-NEXT: entry: @@ -23,3 +25,23 @@ v4s test_amdgcn_global_load_tr_b128_v4i16(global v4s* inptr) { return __builtin_amdgcn_global_load_tr_b128_v4i16(inptr); } + +// CHECK-GFX1200-LABEL: @test_amdgcn_global_load_tr_b128_v4f16( +// CHECK-GFX1200-NEXT: entry: +// CHECK-GFX1200-NEXT: [[TMP0:%.*]] = tail call <4 x half> @llvm.amdgcn.global.load.tr.b128.v4f16(ptr addrspace(1) [[INPTR:%.*]]) +// CHECK-GFX1200-NEXT: ret <4 x half> [[TMP0]] +// +v4h test_amdgcn_global_load_tr_b128_v4f16(global v4h* inptr) +{ + return __builtin_amdgcn_global_load_tr_b128_v4f16(inptr); +} + +// CHECK-GFX1200-LABEL: @test_amdgcn_global_load_tr_b128_v4bf16( +// CHECK-GFX1200-NEXT: entry: +// CHECK-GFX1200-NEXT: [[TMP0:%.*]] = tail call <4 x bfloat> @llvm.amdgcn.global.load.tr.b128.v4bf16(ptr addrspace(1) [[INPTR:%.*]]) +// CHECK-GFX1200-NEXT: ret <4 x bfloat> [[TMP0]] +// +v4y test_amdgcn_global_load_tr_b128_v4bf16(global v4y* inptr) +{ + return __builtin_amdgcn_global_load_tr_b128_v4bf16(inptr); +} diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-raw-buffer-load.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-raw-buffer-load.cl new file mode 100644 index 0000000000000..3403b69e07e4b --- /dev/null +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-raw-buffer-load.cl @@ -0,0 +1,172 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: amdgpu-registered-target +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu verde -emit-llvm -o - %s | FileCheck %s + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned int v2u32 __attribute__((ext_vector_type(2))); +typedef unsigned int v3u32 __attribute__((ext_vector_type(3))); +typedef unsigned int v4u32 __attribute__((ext_vector_type(4))); + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call i8 @llvm.amdgcn.raw.ptr.buffer.load.i8(ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 0, i32 0) +// CHECK-NEXT: ret i8 [[TMP0]] +// +u8 test_amdgcn_raw_ptr_buffer_load_b8(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b8(rsrc, /*offset=*/0, /*soffset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call i16 @llvm.amdgcn.raw.ptr.buffer.load.i16(ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 0, i32 0) +// CHECK-NEXT: ret i16 [[TMP0]] +// +u16 test_amdgcn_raw_ptr_buffer_load_b16(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b16(rsrc, /*offset=*/0, /*soffset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 0, i32 0) +// CHECK-NEXT: ret i32 [[TMP0]] +// +u32 test_amdgcn_raw_ptr_buffer_load_b32(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b32(rsrc, /*offset=*/0, /*soffset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v2i32(ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 0, i32 0) +// CHECK-NEXT: ret <2 x i32> [[TMP0]] +// +v2u32 test_amdgcn_raw_ptr_buffer_load_b64(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b64(rsrc, /*offset=*/0, /*soffset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b96( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <3 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v3i32(ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 0, i32 0) +// CHECK-NEXT: ret <3 x i32> [[TMP0]] +// +v3u32 test_amdgcn_raw_ptr_buffer_load_b96(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b96(rsrc, /*offset=*/0, /*soffset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b128( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v4i32(ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 0, i32 0) +// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// +v4u32 test_amdgcn_raw_ptr_buffer_load_b128(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b128(rsrc, /*offset=*/0, /*soffset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b8_non_const_offset( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call i8 @llvm.amdgcn.raw.ptr.buffer.load.i8(ptr addrspace(8) [[RSRC:%.*]], i32 [[OFFSET:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret i8 [[TMP0]] +// +u8 test_amdgcn_raw_ptr_buffer_load_b8_non_const_offset(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b8(rsrc, offset, /*soffset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b16_non_const_offset( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call i16 @llvm.amdgcn.raw.ptr.buffer.load.i16(ptr addrspace(8) [[RSRC:%.*]], i32 [[OFFSET:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret i16 [[TMP0]] +// +u16 test_amdgcn_raw_ptr_buffer_load_b16_non_const_offset(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b16(rsrc, offset, /*soffset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b32_non_const_offset( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC:%.*]], i32 [[OFFSET:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret i32 [[TMP0]] +// +u32 test_amdgcn_raw_ptr_buffer_load_b32_non_const_offset(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b32(rsrc, offset, /*soffset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b64_non_const_offset( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v2i32(ptr addrspace(8) [[RSRC:%.*]], i32 [[OFFSET:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <2 x i32> [[TMP0]] +// +v2u32 test_amdgcn_raw_ptr_buffer_load_b64_non_const_offset(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b64(rsrc, offset, /*soffset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b96_non_const_offset( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <3 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v3i32(ptr addrspace(8) [[RSRC:%.*]], i32 [[OFFSET:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <3 x i32> [[TMP0]] +// +v3u32 test_amdgcn_raw_ptr_buffer_load_b96_non_const_offset(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b96(rsrc, offset, /*soffset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b128_non_const_offset( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v4i32(ptr addrspace(8) [[RSRC:%.*]], i32 [[OFFSET:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// +v4u32 test_amdgcn_raw_ptr_buffer_load_b128_non_const_offset(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b128(rsrc, offset, /*soffset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b8_non_const_soffset( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call i8 @llvm.amdgcn.raw.ptr.buffer.load.i8(ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 [[SOFFSET:%.*]], i32 0) +// CHECK-NEXT: ret i8 [[TMP0]] +// +u8 test_amdgcn_raw_ptr_buffer_load_b8_non_const_soffset(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b8(rsrc, /*offset=*/0, soffset, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b16_non_const_soffset( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call i16 @llvm.amdgcn.raw.ptr.buffer.load.i16(ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 [[SOFFSET:%.*]], i32 0) +// CHECK-NEXT: ret i16 [[TMP0]] +// +u16 test_amdgcn_raw_ptr_buffer_load_b16_non_const_soffset(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b16(rsrc, /*offset=*/0, soffset, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b32_non_const_soffset( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 [[SOFFSET:%.*]], i32 0) +// CHECK-NEXT: ret i32 [[TMP0]] +// +u32 test_amdgcn_raw_ptr_buffer_load_b32_non_const_soffset(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b32(rsrc, /*offset=*/0, soffset, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b64_non_const_soffset( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v2i32(ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 [[SOFFSET:%.*]], i32 0) +// CHECK-NEXT: ret <2 x i32> [[TMP0]] +// +v2u32 test_amdgcn_raw_ptr_buffer_load_b64_non_const_soffset(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b64(rsrc, /*offset=*/0, soffset, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b96_non_const_soffset( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <3 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v3i32(ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 [[SOFFSET:%.*]], i32 0) +// CHECK-NEXT: ret <3 x i32> [[TMP0]] +// +v3u32 test_amdgcn_raw_ptr_buffer_load_b96_non_const_soffset(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b96(rsrc, /*offset=*/0, soffset, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_load_b128_non_const_soffset( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v4i32(ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 [[SOFFSET:%.*]], i32 0) +// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// +v4u32 test_amdgcn_raw_ptr_buffer_load_b128_non_const_soffset(__amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { + return __builtin_amdgcn_raw_buffer_load_b128(rsrc, /*offset=*/0, soffset, /*aux=*/0); +} diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-raw-buffer-store.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-raw-buffer-store.cl index 37975d59730c5..097c545917270 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn-raw-buffer-store.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-raw-buffer-store.cl @@ -2,19 +2,19 @@ // REQUIRES: amdgpu-registered-target // RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu verde -emit-llvm -o - %s | FileCheck %s -typedef char i8; -typedef short i16; -typedef int i32; -typedef int i64 __attribute__((ext_vector_type(2))); -typedef int i96 __attribute__((ext_vector_type(3))); -typedef int i128 __attribute__((ext_vector_type(4))); +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned int v2u32 __attribute__((ext_vector_type(2))); +typedef unsigned int v3u32 __attribute__((ext_vector_type(3))); +typedef unsigned int v4u32 __attribute__((ext_vector_type(4))); // CHECK-LABEL: @test_amdgcn_raw_ptr_buffer_store_b8( // CHECK-NEXT: entry: // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.i8(i8 [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 0, i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b8(i8 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b8(u8 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b8(vdata, rsrc, /*offset=*/0, /*soffset=*/0, /*aux=*/0); } @@ -23,7 +23,7 @@ void test_amdgcn_raw_ptr_buffer_store_b8(i8 vdata, __amdgpu_buffer_rsrc_t rsrc, // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.i16(i16 [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 0, i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b16(i16 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b16(u16 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b16(vdata, rsrc, /*offset=*/0, /*soffset=*/0, /*aux=*/0); } @@ -32,7 +32,7 @@ void test_amdgcn_raw_ptr_buffer_store_b16(i16 vdata, __amdgpu_buffer_rsrc_t rsrc // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.i32(i32 [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 0, i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b32(i32 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b32(u32 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b32(vdata, rsrc, /*offset=*/0, /*soffset=*/0, /*aux=*/0); } @@ -41,7 +41,7 @@ void test_amdgcn_raw_ptr_buffer_store_b32(i32 vdata, __amdgpu_buffer_rsrc_t rsrc // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.v2i32(<2 x i32> [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 0, i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b64(i64 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b64(v2u32 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b64(vdata, rsrc, /*offset=*/0, /*soffset=*/0, /*aux=*/0); } @@ -50,7 +50,7 @@ void test_amdgcn_raw_ptr_buffer_store_b64(i64 vdata, __amdgpu_buffer_rsrc_t rsrc // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.v3i32(<3 x i32> [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 0, i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b96(i96 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b96(v3u32 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b96(vdata, rsrc, /*offset=*/0, /*soffset=*/0, /*aux=*/0); } @@ -59,7 +59,7 @@ void test_amdgcn_raw_ptr_buffer_store_b96(i96 vdata, __amdgpu_buffer_rsrc_t rsrc // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.v4i32(<4 x i32> [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 0, i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b128(i128 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b128(v4u32 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b128(vdata, rsrc, /*offset=*/0, /*soffset=*/0, /*aux=*/0); } @@ -68,7 +68,7 @@ void test_amdgcn_raw_ptr_buffer_store_b128(i128 vdata, __amdgpu_buffer_rsrc_t rs // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.i8(i8 [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 [[OFFSET:%.*]], i32 0, i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b8_non_const_offset(i8 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b8_non_const_offset(u8 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b8(vdata, rsrc, offset, /*soffset=*/0, /*aux=*/0); } @@ -77,7 +77,7 @@ void test_amdgcn_raw_ptr_buffer_store_b8_non_const_offset(i8 vdata, __amdgpu_buf // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.i16(i16 [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 [[OFFSET:%.*]], i32 0, i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b16_non_const_offset(i16 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b16_non_const_offset(u16 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b16(vdata, rsrc, offset, /*soffset=*/0, /*aux=*/0); } @@ -86,7 +86,7 @@ void test_amdgcn_raw_ptr_buffer_store_b16_non_const_offset(i16 vdata, __amdgpu_b // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.i32(i32 [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 [[OFFSET:%.*]], i32 0, i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b32_non_const_offset(i32 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b32_non_const_offset(u32 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b32(vdata, rsrc, offset, /*soffset=*/0, /*aux=*/0); } @@ -95,7 +95,7 @@ void test_amdgcn_raw_ptr_buffer_store_b32_non_const_offset(i32 vdata, __amdgpu_b // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.v2i32(<2 x i32> [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 [[OFFSET:%.*]], i32 0, i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b64_non_const_offset(i64 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b64_non_const_offset(v2u32 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b64(vdata, rsrc, offset, /*soffset=*/0, /*aux=*/0); } @@ -104,7 +104,7 @@ void test_amdgcn_raw_ptr_buffer_store_b64_non_const_offset(i64 vdata, __amdgpu_b // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.v3i32(<3 x i32> [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 [[OFFSET:%.*]], i32 0, i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b96_non_const_offset(i96 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b96_non_const_offset(v3u32 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b96(vdata, rsrc, offset, /*soffset=*/0, /*aux=*/0); } @@ -113,7 +113,7 @@ void test_amdgcn_raw_ptr_buffer_store_b96_non_const_offset(i96 vdata, __amdgpu_b // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.v4i32(<4 x i32> [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 [[OFFSET:%.*]], i32 0, i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b128_non_const_offset(i128 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b128_non_const_offset(v4u32 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b128(vdata, rsrc, offset, /*soffset=*/0, /*aux=*/0); } @@ -122,7 +122,7 @@ void test_amdgcn_raw_ptr_buffer_store_b128_non_const_offset(i128 vdata, __amdgpu // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.i8(i8 [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 [[SOFFSET:%.*]], i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b8_non_const_soffset(i8 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b8_non_const_soffset(u8 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b8(vdata, rsrc, /*offset=*/0, soffset, /*aux=*/0); } @@ -131,7 +131,7 @@ void test_amdgcn_raw_ptr_buffer_store_b8_non_const_soffset(i8 vdata, __amdgpu_bu // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.i16(i16 [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 [[SOFFSET:%.*]], i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b16_non_const_soffset(i16 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b16_non_const_soffset(u16 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b16(vdata, rsrc, /*offset=*/0, soffset, /*aux=*/0); } @@ -140,7 +140,7 @@ void test_amdgcn_raw_ptr_buffer_store_b16_non_const_soffset(i16 vdata, __amdgpu_ // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.i32(i32 [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 [[SOFFSET:%.*]], i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b32_non_const_soffset(i32 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b32_non_const_soffset(u32 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b32(vdata, rsrc, /*offset=*/0, soffset, /*aux=*/0); } @@ -149,7 +149,7 @@ void test_amdgcn_raw_ptr_buffer_store_b32_non_const_soffset(i32 vdata, __amdgpu_ // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.v2i32(<2 x i32> [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 [[SOFFSET:%.*]], i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b64_non_const_soffset(i64 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b64_non_const_soffset(v2u32 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b64(vdata, rsrc, /*offset=*/0, soffset, /*aux=*/0); } @@ -158,7 +158,7 @@ void test_amdgcn_raw_ptr_buffer_store_b64_non_const_soffset(i64 vdata, __amdgpu_ // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.v3i32(<3 x i32> [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 [[SOFFSET:%.*]], i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b96_non_const_soffset(i96 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b96_non_const_soffset(v3u32 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b96(vdata, rsrc, /*offset=*/0, soffset, /*aux=*/0); } @@ -167,6 +167,6 @@ void test_amdgcn_raw_ptr_buffer_store_b96_non_const_soffset(i96 vdata, __amdgpu_ // CHECK-NEXT: tail call void @llvm.amdgcn.raw.ptr.buffer.store.v4i32(<4 x i32> [[VDATA:%.*]], ptr addrspace(8) [[RSRC:%.*]], i32 0, i32 [[SOFFSET:%.*]], i32 0) // CHECK-NEXT: ret void // -void test_amdgcn_raw_ptr_buffer_store_b128_non_const_soffset(i128 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { +void test_amdgcn_raw_ptr_buffer_store_b128_non_const_soffset(v4u32 vdata, __amdgpu_buffer_rsrc_t rsrc, int offset, int soffset) { __builtin_amdgcn_raw_buffer_store_b128(vdata, rsrc, /*offset=*/0, soffset, /*aux=*/0); } diff --git a/clang/test/CodeGenOpenCL/builtins-f16.cl b/clang/test/CodeGenOpenCL/builtins-f16.cl index d7bffdad5c548..8150bc1ac9e2d 100644 --- a/clang/test/CodeGenOpenCL/builtins-f16.cl +++ b/clang/test/CodeGenOpenCL/builtins-f16.cl @@ -6,6 +6,15 @@ void test_half_builtins(half h0, half h1, half h2, int i0) { volatile half res; + // CHECK: call half @llvm.acos.f16(half %h0) + res = __builtin_acosf16(h0); + + // CHECK: call half @llvm.asin.f16(half %h0) + res = __builtin_asinf16(h0); + + // CHECK: call half @llvm.atan.f16(half %h0) + res = __builtin_atanf16(h0); + // CHECK: call half @llvm.copysign.f16(half %h0, half %h1) res = __builtin_copysignf16(h0, h1); @@ -18,6 +27,9 @@ void test_half_builtins(half h0, half h1, half h2, int i0) { // CHECK: call half @llvm.cos.f16(half %h0) res = __builtin_cosf16(h0); + // CHECK: call half @llvm.cosh.f16(half %h0) + res = __builtin_coshf16(h0); + // CHECK: call half @llvm.exp.f16(half %h0) res = __builtin_expf16(h0); @@ -63,12 +75,18 @@ void test_half_builtins(half h0, half h1, half h2, int i0) { // CHECK: call half @llvm.sin.f16(half %h0) res = __builtin_sinf16(h0); + // CHECK: call half @llvm.sinh.f16(half %h0) + res = __builtin_sinhf16(h0); + // CHECK: call half @llvm.sqrt.f16(half %h0) res = __builtin_sqrtf16(h0); // CHECK: call half @llvm.tan.f16(half %h0) res = __builtin_tanf16(h0); + // CHECK: call half @llvm.tanh.f16(half %h0) + res = __builtin_tanhf16(h0); + // CHECK: call half @llvm.trunc.f16(half %h0) res = __builtin_truncf16(h0); diff --git a/clang/test/CodeGenOpenCL/relaxed-fpmath.cl b/clang/test/CodeGenOpenCL/relaxed-fpmath.cl index 2751caa973072..a5f0019dbc1e5 100644 --- a/clang/test/CodeGenOpenCL/relaxed-fpmath.cl +++ b/clang/test/CodeGenOpenCL/relaxed-fpmath.cl @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s -check-prefix=NORMAL // RUN: %clang_cc1 %s -emit-llvm -cl-fast-relaxed-math -o - | FileCheck %s -check-prefix=FAST -// RUN: %clang_cc1 %s -emit-llvm -cl-finite-math-only -o - | FileCheck %s -check-prefix=FINITE +// RUN: %clang_cc1 %s -emit-llvm -menable-no-infs -menable-no-nans -cl-finite-math-only -o - | FileCheck %s -check-prefix=FINITE // RUN: %clang_cc1 %s -emit-llvm -cl-unsafe-math-optimizations -o - | FileCheck %s -check-prefix=UNSAFE // RUN: %clang_cc1 %s -emit-llvm -cl-mad-enable -o - | FileCheck %s -check-prefix=MAD // RUN: %clang_cc1 %s -emit-llvm -cl-no-signed-zeros -o - | FileCheck %s -check-prefix=NOSIGNED @@ -9,7 +9,7 @@ // RUN: %clang_cc1 %s -DGEN_PCH=1 -finclude-default-header -triple spir-unknown-unknown -emit-pch -o %t.pch // RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -o - | FileCheck %s -check-prefix=NORMAL // RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-fast-relaxed-math -o - | FileCheck %s -check-prefix=FAST -// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-finite-math-only -o - | FileCheck %s -check-prefix=FINITE +// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -menable-no-infs -menable-no-nans -cl-finite-math-only -o - | FileCheck %s -check-prefix=FINITE // RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-unsafe-math-optimizations -o - | FileCheck %s -check-prefix=UNSAFE // RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-mad-enable -o - | FileCheck %s -check-prefix=MAD // RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-no-signed-zeros -o - | FileCheck %s -check-prefix=NOSIGNED diff --git a/clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-gnu/.keep b/clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-gnu/.keep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-pauthtest/.keep b/clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-pauthtest/.keep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/Ofast.c b/clang/test/Driver/Ofast.c index 8b7f2217eca2f..91de296a4c3ff 100644 --- a/clang/test/Driver/Ofast.c +++ b/clang/test/Driver/Ofast.c @@ -3,19 +3,21 @@ // RUN: %clang -fno-fast-math -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s // RUN: %clang -fno-strict-aliasing -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s // RUN: %clang -fno-vectorize -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s -// RUN: %clang -Ofast -O2 -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-O2 \ +// RUN: %clang -Ofast -O2 -### -Werror %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-O2 \ // RUN: %if target={{.*-windows-msvc.*}} %{ --check-prefix=CHECK-OFAST-O2-ALIASING-MSVC %} \ // RUN: %else %{ --check-prefix=CHECK-OFAST-O2-ALIASING %} %s // RUN: %clang -Ofast -fno-fast-math -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-FAST-MATH %s // RUN: %clang -Ofast -fno-strict-aliasing -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-STRICT-ALIASING %s // RUN: %clang -Ofast -fno-vectorize -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-VECTORIZE %s +// CHECK-OFAST: use '-O3 -ffast-math' for the same behavior, or '-O3' to enable only conforming optimizations // CHECK-OFAST: -cc1 // CHECK-OFAST-NOT: -relaxed-aliasing // CHECK-OFAST: -ffast-math // CHECK-OFAST: -Ofast // CHECK-OFAST: -vectorize-loops +// Lack of warning about '-Ofast' deprecation is checked via -Werror // CHECK-OFAST-O2: -cc1 // CHECK-OFAST-O2-ALIASING-NOT: -relaxed-aliasing // CHECK-OFAST-O2-ALIASING-MSVC: -relaxed-aliasing @@ -23,18 +25,21 @@ // CHECK-OFAST-O2-NOT: -Ofast // CHECK-OFAST-O2: -vectorize-loops +// CHECK-OFAST-NO-FAST-MATH: use '-O3 -ffast-math' for the same behavior, or '-O3' to enable only conforming optimizations // CHECK-OFAST-NO-FAST-MATH: -cc1 // CHECK-OFAST-NO-FAST-MATH-NOT: -relaxed-aliasing // CHECK-OFAST-NO-FAST-MATH-NOT: -ffast-math // CHECK-OFAST-NO-FAST-MATH: -Ofast // CHECK-OFAST-NO-FAST-MATH: -vectorize-loops +// CHECK-OFAST-NO-STRICT-ALIASING: use '-O3 -ffast-math' for the same behavior, or '-O3' to enable only conforming optimizations // CHECK-OFAST-NO-STRICT-ALIASING: -cc1 // CHECK-OFAST-NO-STRICT-ALIASING: -relaxed-aliasing // CHECK-OFAST-NO-STRICT-ALIASING: -ffast-math // CHECK-OFAST-NO-STRICT-ALIASING: -Ofast // CHECK-OFAST-NO-STRICT-ALIASING: -vectorize-loops +// CHECK-OFAST-NO-VECTORIZE: use '-O3 -ffast-math' for the same behavior, or '-O3' to enable only conforming optimizations // CHECK-OFAST-NO-VECTORIZE: -cc1 // CHECK-OFAST-NO-VECTORIZE-NOT: -relaxed-aliasing // CHECK-OFAST-NO-VECTORIZE: -ffast-math diff --git a/clang/test/Driver/aarch64-multilib-pauthabi.c b/clang/test/Driver/aarch64-multilib-pauthabi.c new file mode 100644 index 0000000000000..3046cb856e83c --- /dev/null +++ b/clang/test/Driver/aarch64-multilib-pauthabi.c @@ -0,0 +1,4 @@ +// RUN: %clang --target=aarch64-linux-pauthtest --sysroot=%S/Inputs/multilib_aarch64_linux_tree -### -c %s 2>&1 | FileCheck %s +// RUN: %clang --target=aarch64-linux -mabi=pauthtest --sysroot=%S/Inputs/multilib_aarch64_linux_tree -### -c %s 2>&1 | FileCheck %s + +// CHECK: "-internal-externc-isystem" "{{.*}}/usr/include/aarch64-linux-pauthtest" diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c index fa0125f4b22a9..75190c4380826 100644 --- a/clang/test/Driver/aarch64-ptrauth.c +++ b/clang/test/Driver/aarch64-ptrauth.c @@ -1,5 +1,7 @@ +// REQUIRES: aarch64-registered-target + // RUN: %clang -### -c --target=aarch64 %s 2>&1 | FileCheck %s --check-prefix NONE -// NONE: "-cc1" +// NONE: "-cc1" // NONE-NOT: "-fptrauth- // RUN: %clang -### -c --target=aarch64 \ @@ -9,17 +11,87 @@ // RUN: -fno-ptrauth-auth-traps -fptrauth-auth-traps \ // RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-address-discrimination \ // RUN: -fno-ptrauth-vtable-pointer-type-discrimination -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -fno-ptrauth-type-info-vtable-pointer-discrimination -fptrauth-type-info-vtable-pointer-discrimination \ // RUN: -fno-ptrauth-init-fini -fptrauth-init-fini \ +// RUN: -fno-ptrauth-indirect-gotos -fptrauth-indirect-gotos \ // RUN: %s 2>&1 | FileCheck %s --check-prefix=ALL -// ALL: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini" +// ALL: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-type-info-vtable-pointer-discrimination" "-fptrauth-init-fini" "-fptrauth-indirect-gotos" + +// RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI1 +// RUN: %clang -### -c --target=aarch64-linux-pauthtest %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI1 +// PAUTHABI1: "-cc1"{{.*}} "-triple" "aarch64-unknown-linux-pauthtest" +// PAUTHABI1-SAME: "-target-abi" "pauthtest" +// PAUTHABI1-SAME: "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-indirect-gotos" "-fptrauth-init-fini" + +// RUN: %clang -### -c --target=aarch64 -mabi=pauthtest -fno-ptrauth-intrinsics \ +// RUN: -fno-ptrauth-calls -fno-ptrauth-returns -fno-ptrauth-auth-traps \ +// RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fno-ptrauth-vtable-pointer-type-discrimination \ +// RUN: -fno-ptrauth-indirect-gotos -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2 +// RUN: %clang -### -c --target=aarch64-pauthtest -fno-ptrauth-intrinsics \ +// RUN: -fno-ptrauth-calls -fno-ptrauth-returns -fno-ptrauth-auth-traps \ +// RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fno-ptrauth-vtable-pointer-type-discrimination \ +// RUN: -fno-ptrauth-indirect-gotos -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2 +// PAUTHABI2: "-cc1" +// PAUTHABI2-NOT: "-fptrauth- // RUN: not %clang -### -c --target=x86_64 -fptrauth-intrinsics -fptrauth-calls -fptrauth-returns -fptrauth-auth-traps \ // RUN: -fptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-type-discrimination \ -// RUN: -fptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=ERR -// ERR: error: unsupported option '-fptrauth-intrinsics' for target '{{.*}}' -// ERR-NEXT: error: unsupported option '-fptrauth-calls' for target '{{.*}}' -// ERR-NEXT: error: unsupported option '-fptrauth-returns' for target '{{.*}}' -// ERR-NEXT: error: unsupported option '-fptrauth-auth-traps' for target '{{.*}}' -// ERR-NEXT: error: unsupported option '-fptrauth-vtable-pointer-address-discrimination' for target '{{.*}}' -// ERR-NEXT: error: unsupported option '-fptrauth-vtable-pointer-type-discrimination' for target '{{.*}}' -// ERR-NEXT: error: unsupported option '-fptrauth-init-fini' for target '{{.*}}' +// RUN: -fptrauth-type-info-vtable-pointer-discrimination -fptrauth-indirect-gotos -fptrauth-init-fini %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR1 +// ERR1: error: unsupported option '-fptrauth-intrinsics' for target '{{.*}}' +// ERR1-NEXT: error: unsupported option '-fptrauth-calls' for target '{{.*}}' +// ERR1-NEXT: error: unsupported option '-fptrauth-returns' for target '{{.*}}' +// ERR1-NEXT: error: unsupported option '-fptrauth-auth-traps' for target '{{.*}}' +// ERR1-NEXT: error: unsupported option '-fptrauth-vtable-pointer-address-discrimination' for target '{{.*}}' +// ERR1-NEXT: error: unsupported option '-fptrauth-vtable-pointer-type-discrimination' for target '{{.*}}' +// ERR1-NEXT: error: unsupported option '-fptrauth-type-info-vtable-pointer-discrimination' for target '{{.*}}' +// ERR1-NEXT: error: unsupported option '-fptrauth-indirect-gotos' for target '{{.*}}' +// ERR1-NEXT: error: unsupported option '-fptrauth-init-fini' for target '{{.*}}' + +//// Only support PAuth ABI for Linux as for now. +// RUN: not %clang -o /dev/null -c --target=aarch64-unknown -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=ERR2 +// RUN: not %clang -o /dev/null -c --target=aarch64-unknown-pauthtest %s 2>&1 | FileCheck %s --check-prefix=ERR2 +// ERR2: error: ABI 'pauthtest' is not supported for 'aarch64-unknown-unknown-pauthtest' + +//// PAuth ABI is encoded as environment part of the triple, so don't allow to explicitly set other environments. +// RUN: not %clang -### -c --target=aarch64-linux-gnu -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=ERR3 +// ERR3: error: unsupported option '-mabi=pauthtest' for target 'aarch64-unknown-linux-gnu' +// RUN: %clang -### -c --target=aarch64-linux-pauthtest -mabi=pauthtest %s + +//// The only branch protection option compatible with PAuthABI is BTI. +// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=pac-ret %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR4 +// RUN: not %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=pac-ret %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR4 +// ERR4: error: unsupported option '-mbranch-protection=pac-ret' for target 'aarch64-unknown-linux-pauthtest' + +// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=gcs %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR5 +// RUN: not %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=gcs %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR5 +// ERR5: error: unsupported option '-mbranch-protection=gcs' for target 'aarch64-unknown-linux-pauthtest' + +// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=standard %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR6 +// RUN: not %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=standard %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR6 +// ERR6: error: unsupported option '-mbranch-protection=standard' for target 'aarch64-unknown-linux-pauthtest' + +// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -msign-return-address=all %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR7 +// RUN: not %clang -### -c --target=aarch64-linux-pauthtest -msign-return-address=all %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR7 +// ERR7: error: unsupported option '-msign-return-address=all' for target 'aarch64-unknown-linux-pauthtest' + +// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -msign-return-address=non-leaf %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR8 +// RUN: not %clang -### -c --target=aarch64-linux-pauthtest -msign-return-address=non-leaf %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR8 +// ERR8: error: unsupported option '-msign-return-address=non-leaf' for target 'aarch64-unknown-linux-pauthtest' + +// RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest -msign-return-address=none %s +// RUN: %clang -### -c --target=aarch64-linux-pauthtest -msign-return-address=none %s +// RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=bti %s +// RUN: %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=bti %s +// RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=none %s +// RUN: %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=none %s diff --git a/clang/test/Driver/aix-save-reg-params.c b/clang/test/Driver/aix-save-reg-params.c new file mode 100644 index 0000000000000..ac58ef136061c --- /dev/null +++ b/clang/test/Driver/aix-save-reg-params.c @@ -0,0 +1,7 @@ +// RUN: %clang -### -target powerpc-ibm-aix-xcoff -msave-reg-params -c %s -o /dev/null 2>&1 | FileCheck %s +// RUN: %clang -### -target powerpc64-ibm-aix-xcoff -msave-reg-params -c %s -o /dev/null 2>&1 | FileCheck %s +// RUN: %clang -### -target powerpc-ibm-aix-xcoff -c %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=DISABLE +// RUN: %clang -### -target powerpc64-ibm-aix-xcoff -c %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=DISABLE + +// CHECK: "-msave-reg-params" +// DISABLE-NOT: "-msave-reg-params" diff --git a/clang/test/Driver/amdgpu-toolchain.c b/clang/test/Driver/amdgpu-toolchain.c index 8ab6a07131474..b60d31bae6270 100644 --- a/clang/test/Driver/amdgpu-toolchain.c +++ b/clang/test/Driver/amdgpu-toolchain.c @@ -18,13 +18,17 @@ // AS_LINK_UR: "-cc1as" // AS_LINK_UR: ld.lld{{.*}} "--no-undefined"{{.*}} "--unresolved-symbols=ignore-all" -// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -nogpulib \ +// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx90a:xnack+:sramecc- -nogpulib \ // RUN: -L. -flto -fconvergent-functions %s 2>&1 | FileCheck -check-prefixes=LTO,MCPU %s -// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -nogpulib \ +// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx90a:xnack+:sramecc- -nogpulib \ // RUN: -L. -fconvergent-functions %s 2>&1 | FileCheck -check-prefix=MCPU %s // LTO: clang{{.*}} "-flto=full"{{.*}}"-fconvergent-functions" -// MCPU: ld.lld{{.*}}"-L."{{.*}}"-plugin-opt=mcpu=gfx906" +// MCPU: ld.lld{{.*}}"-L."{{.*}}"-plugin-opt=mcpu=gfx90a"{{.*}}"-plugin-opt=-mattr=-sramecc,+xnack" // RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -nogpulib \ // RUN: -fuse-ld=ld %s 2>&1 | FileCheck -check-prefixes=LD %s // LD: ld.lld + +// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -nogpulib \ +// RUN: -r %s 2>&1 | FileCheck -check-prefixes=RELO %s +// RELO-NOT: -shared diff --git a/clang/test/Driver/cuda-cross-compiling.c b/clang/test/Driver/cuda-cross-compiling.c index a5e392150d757..d055cda1b7461 100644 --- a/clang/test/Driver/cuda-cross-compiling.c +++ b/clang/test/Driver/cuda-cross-compiling.c @@ -32,8 +32,8 @@ // RUN: | FileCheck -check-prefix=ARGS %s // ARGS: -cc1" "-triple" "nvptx64-nvidia-cuda" "-S" {{.*}} "-target-cpu" "sm_61" "-target-feature" "+ptx{{[0-9]+}}" {{.*}} "-o" "[[PTX:.+]].s" -// ARGS-NEXT: ptxas{{.*}}"-m64" "-O3" "--gpu-name" "sm_61" "--output-file" "[[CUBIN:.+]].cubin" "[[PTX]].s" "-c" -// ARGS-NEXT: nvlink{{.*}}"-o" "a.out" "-arch" "sm_61" {{.*}} "[[CUBIN]].cubin" +// ARGS-NEXT: ptxas{{.*}}"-m64" "-O3" "--gpu-name" "sm_61" "--output-file" "[[CUBIN:.+]].o" "[[PTX]].s" "-c" +// ARGS-NEXT: clang-nvlink-wrapper{{.*}}"-o" "a.out" "-arch" "sm_61"{{.*}}"[[CUBIN]].o" // // Test the generated arguments to the CUDA binary utils when targeting NVPTX. @@ -55,7 +55,7 @@ // RUN: %clang -target nvptx64-nvidia-cuda -march=sm_61 -### %t.o 2>&1 \ // RUN: | FileCheck -check-prefix=LINK %s -// LINK: nvlink{{.*}}"-o" "a.out" "-arch" "sm_61" {{.*}} "{{.*}}.cubin" +// LINK: clang-nvlink-wrapper{{.*}}"-o" "a.out" "-arch" "sm_61"{{.*}}[[CUBIN:.+]].o // // Test to ensure that we enable handling global constructors in a freestanding @@ -72,7 +72,7 @@ // RUN: %clang -target nvptx64-nvidia-cuda -Wl,-v -Wl,a,b -march=sm_52 -### %s 2>&1 \ // RUN: | FileCheck -check-prefix=LINKER-ARGS %s -// LINKER-ARGS: nvlink{{.*}}"-v"{{.*}}"a" "b" +// LINKER-ARGS: clang-nvlink-wrapper{{.*}}"-v"{{.*}}"a" "b" // Tests for handling a missing architecture. // @@ -84,9 +84,24 @@ // MISSING: error: must pass in an explicit nvptx64 gpu architecture to 'ptxas' // MISSING: error: must pass in an explicit nvptx64 gpu architecture to 'nvlink' +// Do not error when performing LTO. +// +// RUN: %clang -target nvptx64-nvidia-cuda -flto %s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=MISSING-LTO %s + +// MISSING-LTO-NOT: error: must pass in an explicit nvptx64 gpu architecture to 'nvlink' + // RUN: %clang -target nvptx64-nvidia-cuda -flto -c %s -### 2>&1 \ // RUN: | FileCheck -check-prefix=GENERIC %s // RUN: %clang -target nvptx64-nvidia-cuda -march=sm_52 -march=generic -flto -c %s -### 2>&1 \ // RUN: | FileCheck -check-prefix=GENERIC %s // GENERIC-NOT: -cc1" "-triple" "nvptx64-nvidia-cuda" {{.*}} "-target-cpu" + +// +// Test forwarding the necessary +ptx feature. +// +// RUN: %clang -target nvptx64-nvidia-cuda --cuda-feature=+ptx63 -march=sm_52 -### %s 2>&1 \ +// RUN: | FileCheck -check-prefix=FEATURE %s + +// FEATURE: clang-nvlink-wrapper{{.*}}"--feature" "+ptx63" diff --git a/clang/test/Driver/darwin-print-libgcc-file-name.c b/clang/test/Driver/darwin-print-libgcc-file-name.c new file mode 100644 index 0000000000000..73e89b6718642 --- /dev/null +++ b/clang/test/Driver/darwin-print-libgcc-file-name.c @@ -0,0 +1,91 @@ +// Test the output of -print-libgcc-file-name on Darwin. + +// +// All platforms +// + +// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \ +// RUN: --target=x86_64-apple-macos \ +// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-MACOS %s +// CHECK-CLANGRT-MACOS: libclang_rt.osx.a + +// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \ +// RUN: --target=arm64-apple-ios \ +// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-IOS %s +// CHECK-CLANGRT-IOS: libclang_rt.ios.a + +// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \ +// RUN: --target=arm64-apple-watchos \ +// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-WATCHOS %s +// CHECK-CLANGRT-WATCHOS: libclang_rt.watchos.a + +// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \ +// RUN: --target=arm64-apple-tvos \ +// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-TVOS %s +// CHECK-CLANGRT-TVOS: libclang_rt.tvos.a + +// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \ +// RUN: --target=arm64-apple-driverkit \ +// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-DRIVERKIT %s +// CHECK-CLANGRT-DRIVERKIT: libclang_rt.driverkit.a + +// +// Simulators +// + +// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \ +// RUN: --target=arm64-apple-ios-simulator \ +// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-IOS-SIMULATOR %s +// CHECK-CLANGRT-IOS-SIMULATOR: libclang_rt.iossim.a + +// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \ +// RUN: --target=arm64-apple-watchos-simulator \ +// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-WATCHOS-SIMULATOR %s +// CHECK-CLANGRT-WATCHOS-SIMULATOR: libclang_rt.watchossim.a + +// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \ +// RUN: --target=arm64-apple-tvos-simulator \ +// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-TVOS-SIMULATOR %s +// CHECK-CLANGRT-TVOS-SIMULATOR: libclang_rt.tvossim.a + +// Check the sanitizer and profile variants +// While the driver also links in sanitizer-specific dylibs, the result of +// -print-libgcc-file-name is the path of the basic compiler-rt library. + +// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \ +// RUN: -fsanitize=address --target=x86_64-apple-macos \ +// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-MACOS-SAN %s +// CHECK-CLANGRT-MACOS-SAN: libclang_rt.osx.a + +// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \ +// RUN: -fsanitize=address --target=arm64-apple-ios \ +// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-IOS-SAN %s +// CHECK-CLANGRT-IOS-SAN: libclang_rt.ios.a + +// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \ +// RUN: -fsanitize=address --target=arm64-apple-watchos \ +// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-WATCHOS-SAN %s +// CHECK-CLANGRT-WATCHOS-SAN: libclang_rt.watchos.a + +// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \ +// RUN: -fsanitize=address --target=arm64-apple-tvos \ +// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-TVOS-SAN %s +// CHECK-CLANGRT-TVOS-SAN: libclang_rt.tvos.a + +// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \ +// RUN: -fsanitize=address --target=arm64-apple-driverkit \ +// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-DRIVERKIT-SAN %s +// CHECK-CLANGRT-DRIVERKIT-SAN: libclang_rt.driverkit.a diff --git a/clang/test/Driver/debug-options.c b/clang/test/Driver/debug-options.c index 0a665f7017d63..21785ba01cb41 100644 --- a/clang/test/Driver/debug-options.c +++ b/clang/test/Driver/debug-options.c @@ -118,27 +118,28 @@ // RUN: %clang_cl -### -c -Z7 -target x86_64-windows-msvc -- %s 2>&1 \ // RUN: | FileCheck -check-prefix=G_NOTUNING %s -// On the PS4/PS5, -g defaults to -gno-column-info, and we always generate the -// arange section. +// On the PS4/PS5, -g defaults to -gno-column-info. We default to always +// generating the arange section, but keyed off SCE DebuggerTuning being in +// play during codegen, instead of -generate-arange-section. // RUN: %clang -### -c %s -target x86_64-scei-ps4 2>&1 \ // RUN: | FileCheck -check-prefix=NOG_PS %s // RUN: %clang -### -c %s -target x86_64-sie-ps5 2>&1 \ // RUN: | FileCheck -check-prefix=NOG_PS %s /// PS4 will stay on v4 even if the generic default version changes. // RUN: %clang -### -c %s -g -target x86_64-scei-ps4 2>&1 \ -// RUN: | FileCheck -check-prefixes=G_DWARF4,GARANGE,G_SCE,NOCI,FWD_TMPL_PARAMS %s +// RUN: | FileCheck -check-prefixes=G_DWARF4,G_SCE,NOCI,FWD_TMPL_PARAMS %s // RUN: %clang -### -c %s -g -target x86_64-sie-ps5 2>&1 \ -// RUN: | FileCheck -check-prefixes=G_DWARF5,GARANGE,G_SCE,NOCI,FWD_TMPL_PARAMS %s +// RUN: | FileCheck -check-prefixes=G_DWARF5,G_SCE,NOCI,FWD_TMPL_PARAMS %s // RUN: %clang -### -c %s -g -gcolumn-info -target x86_64-scei-ps4 2>&1 \ // RUN: | FileCheck -check-prefix=CI %s // RUN: %clang -### -c %s -gsce -target x86_64-unknown-linux 2>&1 \ // RUN: | FileCheck -check-prefix=NOCI %s // RUN: %clang -### %s -g -flto=thin -target x86_64-scei-ps4 2>&1 \ -// RUN: | FileCheck -check-prefix=SNLDTLTOGARANGE %s +// RUN: | FileCheck -check-prefix=LDGARANGE %s // RUN: %clang -### %s -g -flto=full -target x86_64-scei-ps4 2>&1 \ -// RUN: | FileCheck -check-prefix=SNLDFLTOGARANGE %s +// RUN: | FileCheck -check-prefix=LDGARANGE %s // RUN: %clang -### %s -g -flto -target x86_64-scei-ps5 2>&1 \ -// RUN: | FileCheck -check-prefix=LLDGARANGE %s +// RUN: | FileCheck -check-prefix=LDGARANGE %s // RUN: %clang -### %s -g -target x86_64-scei-ps5 2>&1 \ // RUN: | FileCheck -check-prefix=LDGARANGE %s @@ -321,8 +322,7 @@ // // NOG_PS: "-cc1" // NOG_PS-NOT: "-dwarf-version= -// NOG_PS: "-generate-arange-section" -// NOG_PS-NOT: "-dwarf-version= +// NOG_PS-NOT: "-generate-arange-section" // // G_ERR: error: unknown argument: // @@ -402,8 +402,7 @@ // // LDGARANGE: {{".*ld.*"}} {{.*}} -// LDGARANGE-NOT: "-plugin-opt=-generate-arange-section" -// LLDGARANGE: {{".*lld.*"}} {{.*}} "-plugin-opt=-generate-arange-section" +// LDGARANGE-NOT: -generate-arange-section" // SNLDTLTOGARANGE: {{".*orbis-ld.*"}} {{.*}} "-lto-thin-debug-options= -generate-arange-section" // SNLDFLTOGARANGE: {{".*orbis-ld.*"}} {{.*}} "-lto-debug-options= -generate-arange-section" diff --git a/clang/test/Driver/fp-contract.c b/clang/test/Driver/fp-contract.c index e2691dc211cc3..cab63683ee813 100644 --- a/clang/test/Driver/fp-contract.c +++ b/clang/test/Driver/fp-contract.c @@ -2,6 +2,14 @@ // the options -ffast-math, -fno-fast-math, funsafe-math-optimizations, // fno-unsafe-math-optimizations. +// These warning checks are above the run lines because the warning is reported +// before the drive options that are checked below the run lines. +// WARN_FM_OFF: warning: overriding '-ffast-math' option with '-ffp-contract=off' +// WARN_FM_ON: warning: overriding '-ffast-math' option with '-ffp-contract=on' +// WARN_FM_FHP: warning: overriding '-ffast-math' option with '-ffp-contract=fast-honor-pragmas' +// WARN_UM_OFF: warning: overriding '-funsafe-math-optimizations' option with '-ffp-contract=off' +// WARN_UM_ON: warning: overriding '-funsafe-math-optimizations' option with '-ffp-contract=on' + // ffast-math, fno-fast-math // RUN: %clang -### -ffast-math -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FPC-FAST %s @@ -10,19 +18,19 @@ // RUN: %clang -### -fno-fast-math -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FPC-ON %s -// RUN: %clang -### -Werror -ffast-math -ffp-contract=on -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-FPC-ON %s +// RUN: %clang -### -ffast-math -ffp-contract=on -c %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=CHECK-FPC-ON,WARN_FM_ON %s // CHECK-FPC-ON: "-ffp-contract=on" -// RUN: %clang -### -Werror -ffast-math -ffp-contract=off -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-FPC-OFF %s +// RUN: %clang -### -ffast-math -ffp-contract=off -c %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=CHECK-FPC-OFF,WARN_FM_OFF %s // CHECK-FPC-OFF: "-ffp-contract=off" // RUN: %clang -### -Werror -ffast-math -ffp-contract=fast -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FPC-FAST %s -// RUN: %clang -### -Werror -ffast-math -ffp-contract=fast-honor-pragmas -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-FPC-FAST-HONOR %s +// RUN: %clang -### -ffast-math -ffp-contract=fast-honor-pragmas -c %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=CHECK-FPC-FAST-HONOR,WARN_FM_FHP %s // CHECK-FPC-FAST-HONOR: "-ffp-contract=fast-honor-pragmas" // RUN: %clang -### -Werror -ffp-contract=fast -ffast-math -c %s 2>&1 \ @@ -43,23 +51,23 @@ // RUN: %clang -### -Werror -ffast-math -ffp-contract=fast -ffp-contract=on -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FPC-ON %s -// RUN: %clang -### -Werror -ffast-math -ffp-contract=on -ffp-contract=off -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-FPC-OFF %s +// RUN: %clang -### -ffast-math -ffp-contract=on -ffp-contract=off -c %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=CHECK-FPC-OFF,WARN_FM_ON %s -// RUN: %clang -### -Werror -ffast-math -ffp-contract=on -ffp-contract=fast -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-FPC-FAST %s +// RUN: %clang -### -ffast-math -ffp-contract=on -ffp-contract=fast -c %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=CHECK-FPC-FAST,WARN_FM_ON %s -// RUN: %clang -### -Werror -ffast-math -ffp-contract=off -ffp-contract=on -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-FPC-ON %s +// RUN: %clang -### -ffast-math -ffp-contract=off -ffp-contract=on -c %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=CHECK-FPC-ON,WARN_FM_OFF %s -// RUN: %clang -### -Werror -ffast-math -ffp-contract=off -ffp-contract=fast \ -// RUN: -c %s 2>&1 | FileCheck --check-prefix=CHECK-FPC-FAST %s +// RUN: %clang -### -ffast-math -ffp-contract=off -ffp-contract=fast \ +// RUN: -c %s 2>&1 | FileCheck --check-prefixes=CHECK-FPC-FAST,WARN_FM_OFF %s -// RUN: %clang -### -Werror -ffast-math -ffp-contract=on -fno-fast-math -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-FPC-ON %s +// RUN: %clang -### -ffast-math -ffp-contract=on -fno-fast-math -c %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=CHECK-FPC-ON,WARN_FM_ON %s -// RUN: %clang -### -Werror -ffast-math -ffp-contract=off -fno-fast-math -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-FPC-OFF %s +// RUN: %clang -### -ffast-math -ffp-contract=off -fno-fast-math -c %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=CHECK-FPC-OFF,WARN_FM_OFF %s // RUN: %clang -### -Werror -ffast-math -ffp-contract=fast -fno-fast-math -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FPC-FAST %s @@ -112,24 +120,24 @@ // RUN: %clang -### -Werror -fno-fast-math -ffast-math -ffp-contract=fast \ // RUN: -c %s 2>&1 | FileCheck --check-prefix=CHECK-FPC-FAST %s -// RUN: %clang -### -Werror -fno-fast-math -ffast-math -ffp-contract=on \ -// RUN: -c %s 2>&1 | FileCheck --check-prefix=CHECK-FPC-ON %s +// RUN: %clang -### -fno-fast-math -ffast-math -ffp-contract=on \ +// RUN: -c %s 2>&1 | FileCheck --check-prefixes=CHECK-FPC-ON,WARN_FM_ON %s -// RUN: %clang -### -Werror -fno-fast-math -ffast-math -ffp-contract=off \ -// RUN: -c %s 2>&1 | FileCheck --check-prefix=CHECK-FPC-OFF %s +// RUN: %clang -### -fno-fast-math -ffast-math -ffp-contract=off \ +// RUN: -c %s 2>&1 | FileCheck --check-prefixes=CHECK-FPC-OFF,WARN_FM_OFF %s // funsafe-math-optimizations, fno-unsafe-math-optimizations -// RUN: %clang -### -funsafe-math-optimizations -c %s 2>&1 \ +// RUN: %clang -### -Werror -funsafe-math-optimizations -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FPC-FAST %s -// RUN: %clang -### -fno-unsafe-math-optimizations -c %s 2>&1 \ +// RUN: %clang -### -Werror -fno-unsafe-math-optimizations -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FPC-ON %s -// RUN: %clang -### -Werror -funsafe-math-optimizations -ffp-contract=on -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-FPC-ON %s +// RUN: %clang -### -funsafe-math-optimizations -ffp-contract=on -c %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=CHECK-FPC-ON,WARN_UM_ON %s -// RUN: %clang -### -Werror -funsafe-math-optimizations -ffp-contract=off -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-FPC-OFF %s +// RUN: %clang -### -funsafe-math-optimizations -ffp-contract=off -c %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=CHECK-FPC-OFF,WARN_UM_OFF %s // RUN: %clang -### -Werror -funsafe-math-optimizations -ffp-contract=fast -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FPC-FAST %s @@ -151,27 +159,27 @@ // RUN: %clang -### -Werror -funsafe-math-optimizations -ffp-contract=fast \ // RUN: -ffp-contract=on -c %s 2>&1 | FileCheck --check-prefix=CHECK-FPC-ON %s -// RUN: %clang -### -Werror -funsafe-math-optimizations -ffp-contract=on \ -// RUN: -ffp-contract=off -c %s 2>&1 | FileCheck --check-prefix=CHECK-FPC-OFF %s +// RUN: %clang -### -funsafe-math-optimizations -ffp-contract=on \ +// RUN: -ffp-contract=off -c %s 2>&1 | FileCheck --check-prefixes=CHECK-FPC-OFF,WARN_UM_ON %s -// RUN: %clang -### -Werror -funsafe-math-optimizations -ffp-contract=on \ +// RUN: %clang -### -funsafe-math-optimizations -ffp-contract=on \ // RUN: -ffp-contract=fast -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-FPC-FAST %s +// RUN: | FileCheck --check-prefixes=CHECK-FPC-FAST,WARN_UM_ON %s -// RUN: %clang -### -Werror -funsafe-math-optimizations -ffp-contract=off \ -// RUN: -ffp-contract=on -c %s 2>&1 | FileCheck --check-prefix=CHECK-FPC-ON %s +// RUN: %clang -### -funsafe-math-optimizations -ffp-contract=off \ +// RUN: -ffp-contract=on -c %s 2>&1 | FileCheck --check-prefixes=CHECK-FPC-ON,WARN_UM_OFF %s -// RUN: %clang -### -Werror -funsafe-math-optimizations -ffp-contract=off \ +// RUN: %clang -### -funsafe-math-optimizations -ffp-contract=off \ // RUN: -ffp-contract=fast \ -// RUN: -c %s 2>&1 | FileCheck --check-prefix=CHECK-FPC-FAST %s +// RUN: -c %s 2>&1 | FileCheck --check-prefixes=CHECK-FPC-FAST,WARN_UM_OFF %s -// RUN: %clang -### -Werror -funsafe-math-optimizations -ffp-contract=on \ +// RUN: %clang -### -funsafe-math-optimizations -ffp-contract=on \ // RUN: -fno-unsafe-math-optimizations -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-FPC-ON %s +// RUN: | FileCheck --check-prefixes=CHECK-FPC-ON,WARN_UM_ON %s -// RUN: %clang -### -Werror -funsafe-math-optimizations -ffp-contract=off \ +// RUN: %clang -### -funsafe-math-optimizations -ffp-contract=off \ // RUN: -fno-unsafe-math-optimizations -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-FPC-OFF %s +// RUN: | FileCheck --check-prefixes=CHECK-FPC-OFF,WARN_UM_OFF %s // RUN: %clang -### -Werror -funsafe-math-optimizations -ffp-contract=fast \ // RUN: -fno-unsafe-math-optimizations -c %s 2>&1 \ @@ -229,9 +237,21 @@ // RUN: -ffp-contract=fast \ // RUN: -c %s 2>&1 | FileCheck --check-prefix=CHECK-FPC-FAST %s -// RUN: %clang -### -Werror -fno-unsafe-math-optimizations -funsafe-math-optimizations \ -// RUN: -ffp-contract=on -c %s 2>&1 | FileCheck --check-prefix=CHECK-FPC-ON %s +// RUN: %clang -### -fno-unsafe-math-optimizations -funsafe-math-optimizations \ +// RUN: -ffp-contract=on -c %s 2>&1 | FileCheck --check-prefixes=CHECK-FPC-ON,WARN_UM_ON %s -// RUN: %clang -### -Werror -fno-unsafe-math-optimizations -funsafe-math-optimizations \ -// RUN: -ffp-contract=off -c %s 2>&1 | FileCheck --check-prefix=CHECK-FPC-OFF %s +// RUN: %clang -### -fno-unsafe-math-optimizations -funsafe-math-optimizations \ +// RUN: -ffp-contract=off -c %s 2>&1 | FileCheck --check-prefixes=CHECK-FPC-OFF,WARN_UM_OFF %s + +// RUN: %clang -### -funsafe-math-optimizations -ffp-contract=off -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN_UM_OFF %s + +// This case should not warn +// RUN: %clang -### -Werror -funsafe-math-optimizations \ +// RUN: -fno-unsafe-math-optimizations -ffp-contract=off -c %s + +// RUN: %clang -### -ffast-math -ffp-contract=off -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN_FM_OFF %s +// This case should not warn +// RUN: %clang -### -Werror -ffast-math -fno-fast-math -ffp-contract=off -c %s diff --git a/clang/test/Driver/fp-model.c b/clang/test/Driver/fp-model.c index 644523394d6b1..2348d4b41f43a 100644 --- a/clang/test/Driver/fp-model.c +++ b/clang/test/Driver/fp-model.c @@ -81,6 +81,19 @@ // RUN: | FileCheck --check-prefix=WARN13 %s // WARN13: warning: overriding '-ffp-model=strict' option with '-fapprox-func' [-Woverriding-option] +// RUN: %clang -### -ffp-model=precise -ffp-contract=off -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN14 %s +// WARN14: warning: overriding '-ffp-model=precise' option with '-ffp-contract=off' [-Woverriding-option] + +// RUN: %clang -### -ffp-model=precise -ffp-contract=fast -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN15 %s +// WARN15: warning: overriding '-ffp-model=precise' option with '-ffp-contract=fast' [-Woverriding-option] + +// RUN: %clang -### -ffp-model=strict -fassociative-math -ffp-contract=on \ +// RUN: -c %s 2>&1 | FileCheck --check-prefix=WARN16 %s +// WARN16: warning: overriding '-ffp-model=strict' option with '-fassociative-math' [-Woverriding-option] +// WARN16: warning: overriding '-ffp-model=strict' option with '-ffp-contract=on' [-Woverriding-option] + // RUN: %clang -### -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOROUND %s // CHECK-NOROUND: "-cc1" diff --git a/clang/test/Driver/fpatchable-function-entry.c b/clang/test/Driver/fpatchable-function-entry.c index ab04fd39ffa1c..5f07ca99a69de 100644 --- a/clang/test/Driver/fpatchable-function-entry.c +++ b/clang/test/Driver/fpatchable-function-entry.c @@ -6,6 +6,8 @@ // RUN: %clang --target=loongarch64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s // RUN: %clang --target=riscv32 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s // RUN: %clang --target=riscv64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s +// RUN: %clang --target=powerpc-unknown-linux-gnu %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s +// RUN: %clang --target=powerpc64-unknown-linux-gnu %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s // CHECK: "-fpatchable-function-entry=1" // RUN: %clang --target=aarch64 -fsyntax-only %s -fpatchable-function-entry=1,1 -c -### 2>&1 | FileCheck --check-prefix=11 %s @@ -13,8 +15,11 @@ // RUN: %clang --target=aarch64 -fsyntax-only %s -fpatchable-function-entry=2,1 -c -### 2>&1 | FileCheck --check-prefix=21 %s // 21: "-fpatchable-function-entry=2" "-fpatchable-function-entry-offset=1" -// RUN: not %clang --target=ppc64 -fsyntax-only %s -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=TARGET %s -// TARGET: error: unsupported option '-fpatchable-function-entry=1' for target 'ppc64' +// RUN: not %clang --target=powerpc64-ibm-aix-xcoff -fsyntax-only %s -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=AIX64 %s +// AIX64: error: unsupported option '-fpatchable-function-entry=1' for target 'powerpc64-ibm-aix-xcoff' + +// RUN: not %clang --target=powerpc-ibm-aix-xcoff -fsyntax-only %s -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=AIX32 %s +// AIX32: error: unsupported option '-fpatchable-function-entry=1' for target 'powerpc-ibm-aix-xcoff' // RUN: not %clang --target=x86_64 -fsyntax-only %s -fpatchable-function-entry=1,0, 2>&1 | FileCheck --check-prefix=EXCESS %s // EXCESS: error: invalid argument '1,0,' to -fpatchable-function-entry= diff --git a/clang/test/Driver/ftime-trace-sections.cpp b/clang/test/Driver/ftime-trace-sections.cpp index 0c16052bc0c3a..da7109b9d81a6 100644 --- a/clang/test/Driver/ftime-trace-sections.cpp +++ b/clang/test/Driver/ftime-trace-sections.cpp @@ -1,5 +1,5 @@ // RUN: rm -rf %t && mkdir %t && cd %t -// RUN: %clangxx -S -ftime-trace -ftime-trace-granularity=0 -o out %s +// RUN: %clangxx -S -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s // RUN: %python %S/ftime-trace-sections.py < out.json template diff --git a/clang/test/Driver/ftime-trace.cpp b/clang/test/Driver/ftime-trace.cpp index 5fe63de915a71..60c5885704b58 100644 --- a/clang/test/Driver/ftime-trace.cpp +++ b/clang/test/Driver/ftime-trace.cpp @@ -1,18 +1,18 @@ // RUN: rm -rf %t && mkdir -p %t && cd %t -// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace -ftime-trace-granularity=0 -o out %s +// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s // RUN: cat out.json \ // RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ // RUN: | FileCheck %s -// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=new-name.json -ftime-trace-granularity=0 -o out %s +// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=new-name.json -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s // RUN: cat new-name.json \ // RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ // RUN: | FileCheck %s // RUN: mkdir dir1 dir2 -// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=dir1 -ftime-trace-granularity=0 -o out %s +// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=dir1 -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s // RUN: cat dir1/out.json \ // RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ // RUN: | FileCheck %s -// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=dir2/ -ftime-trace-granularity=0 -o out %s +// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=dir2/ -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s // RUN: cat dir2/out.json \ // RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ // RUN: | FileCheck %s @@ -34,32 +34,33 @@ // RUN: mkdir d e f && cp %s d/a.cpp && touch d/b.c /// TODO: Support -fno-integrated-as. -// RUN: %clang -### -c -ftime-trace -ftime-trace-granularity=0 -fintegrated-as d/a.cpp -o e/a.o 2>&1 | FileCheck %s --check-prefix=COMPILE1 -// COMPILE1: -cc1{{.*}} "-ftime-trace=e/a.json" "-ftime-trace-granularity=0" +// RUN: %clang -### -c -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose -fintegrated-as d/a.cpp -o e/a.o 2>&1 | FileCheck %s --check-prefix=COMPILE1 +// COMPILE1: -cc1{{.*}} "-ftime-trace=e/a.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" -// RUN: %clang -### -c -ftime-trace -ftime-trace-granularity=0 d/a.cpp d/b.c -dumpdir f/ 2>&1 | FileCheck %s --check-prefix=COMPILE2 -// COMPILE2: -cc1{{.*}} "-ftime-trace=f/a.json" "-ftime-trace-granularity=0" -// COMPILE2: -cc1{{.*}} "-ftime-trace=f/b.json" "-ftime-trace-granularity=0" +// RUN: %clang -### -c -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose d/a.cpp d/b.c -dumpdir f/ 2>&1 | FileCheck %s --check-prefix=COMPILE2 +// COMPILE2: -cc1{{.*}} "-ftime-trace=f/a.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" +// COMPILE2: -cc1{{.*}} "-ftime-trace=f/b.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" /// -o specifies the link output. Create ${output}-${basename}.json. -// RUN: %clang -### -ftime-trace -ftime-trace-granularity=0 d/a.cpp d/b.c -o e/x 2>&1 | FileCheck %s --check-prefix=LINK1 -// LINK1: -cc1{{.*}} "-ftime-trace=e/x-a.json" "-ftime-trace-granularity=0" -// LINK1: -cc1{{.*}} "-ftime-trace=e/x-b.json" "-ftime-trace-granularity=0" +// RUN: %clang -### -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose d/a.cpp d/b.c -o e/x 2>&1 | FileCheck %s --check-prefix=LINK1 +// LINK1: -cc1{{.*}} "-ftime-trace=e/x-a.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" +// LINK1: -cc1{{.*}} "-ftime-trace=e/x-b.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" /// -dumpdir is f/g, not ending with a path separator. We create f/g${basename}.json. -// RUN: %clang -### -ftime-trace -ftime-trace-granularity=0 d/a.cpp d/b.c -o e/x -dumpdir f/g 2>&1 | FileCheck %s --check-prefix=LINK2 -// LINK2: -cc1{{.*}} "-ftime-trace=f/ga.json" "-ftime-trace-granularity=0" -// LINK2: -cc1{{.*}} "-ftime-trace=f/gb.json" "-ftime-trace-granularity=0" +// RUN: %clang -### -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose d/a.cpp d/b.c -o e/x -dumpdir f/g 2>&1 | FileCheck %s --check-prefix=LINK2 +// LINK2: -cc1{{.*}} "-ftime-trace=f/ga.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" +// LINK2: -cc1{{.*}} "-ftime-trace=f/gb.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" -// RUN: %clang -### -ftime-trace=e -ftime-trace-granularity=0 d/a.cpp d/b.c -o f/x -dumpdir f/ 2>&1 | FileCheck %s --check-prefix=LINK3 -// LINK3: -cc1{{.*}} "-ftime-trace=e{{/|\\\\}}a-{{[^.]*}}.json" "-ftime-trace-granularity=0" -// LINK3: -cc1{{.*}} "-ftime-trace=e{{/|\\\\}}b-{{[^.]*}}.json" "-ftime-trace-granularity=0" +// RUN: %clang -### -ftime-trace=e -ftime-trace-granularity=0 -ftime-trace-verbose d/a.cpp d/b.c -o f/x -dumpdir f/ 2>&1 | FileCheck %s --check-prefix=LINK3 +// LINK3: -cc1{{.*}} "-ftime-trace=e{{/|\\\\}}a-{{[^.]*}}.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" +// LINK3: -cc1{{.*}} "-ftime-trace=e{{/|\\\\}}b-{{[^.]*}}.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" -// RUN: %clang -### -ftime-trace -ftime-trace=e -ftime-trace-granularity=1 -xassembler d/a.cpp 2>&1 | \ +// RUN: %clang -### -ftime-trace -ftime-trace=e -ftime-trace-granularity=1 -ftime-trace-verbose -xassembler d/a.cpp 2>&1 | \ // RUN: FileCheck %s --check-prefix=UNUSED // UNUSED: warning: argument unused during compilation: '-ftime-trace' // UNUSED-NEXT: warning: argument unused during compilation: '-ftime-trace=e' // UNUSED-NEXT: warning: argument unused during compilation: '-ftime-trace-granularity=1' +// UNUSED-NEXT: warning: argument unused during compilation: '-ftime-trace-verbose' // UNUSED-NOT: warning: template diff --git a/clang/test/Driver/gpu-libc-headers.c b/clang/test/Driver/gpu-libc-headers.c index 32a5edb175e61..53c016837dde6 100644 --- a/clang/test/Driver/gpu-libc-headers.c +++ b/clang/test/Driver/gpu-libc-headers.c @@ -4,15 +4,15 @@ // RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --sysroot=./ \ // RUN: -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target=nvptx64-nvidia-cuda --offload-arch=sm_70 \ // RUN: -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS -// CHECK-HEADERS: "-cc1"{{.*}}"-internal-isystem" "{{.*}}include{{.*}}llvm_libc_wrappers"{{.*}}"-isysroot" "./" -// CHECK-HEADERS: "-cc1"{{.*}}"-internal-isystem" "{{.*}}include{{.*}}llvm_libc_wrappers"{{.*}}"-isysroot" "./" +// CHECK-HEADERS: "-cc1"{{.*}}"-isysroot" "./"{{.*}}"-internal-isystem" "{{.*}}include{{.*}}llvm_libc_wrappers" +// CHECK-HEADERS: "-cc1"{{.*}}"-isysroot" "./"{{.*}}"-internal-isystem" "{{.*}}include{{.*}}llvm_libc_wrappers" // RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx90a --sysroot=./ \ // RUN: -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS-AMDGPU // RUN: %clang -### --target=nvptx64-nvidia-cuda -march=sm_89 --sysroot=./ \ // RUN: -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS-NVPTX -// CHECK-HEADERS-AMDGPU: "-cc1"{{.*}}"-internal-isystem" "{{.*}}include{{.*}}amdgcn-amd-amdhsa"{{.*}}"-isysroot" "./" -// CHECK-HEADERS-NVPTX: "-cc1"{{.*}}"-internal-isystem" "{{.*}}include{{.*}}nvptx64-nvidia-cuda"{{.*}}"-isysroot" "./" +// CHECK-HEADERS-AMDGPU: "-cc1"{{.*}}"-isysroot" "./"{{.*}}"-internal-isystem" "{{.*}}include{{.*}}amdgcn-amd-amdhsa" +// CHECK-HEADERS-NVPTX: "-cc1"{{.*}}"-isysroot" "./"{{.*}}"-internal-isystem" "{{.*}}include{{.*}}nvptx64-nvidia-cuda" // RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx1030 -nogpulib \ // RUN: -nogpuinc %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS-DISABLED diff --git a/clang/test/Driver/hexagon-toolchain-linux.c b/clang/test/Driver/hexagon-toolchain-linux.c index fe32638417ea4..86cc9a30e932c 100644 --- a/clang/test/Driver/hexagon-toolchain-linux.c +++ b/clang/test/Driver/hexagon-toolchain-linux.c @@ -119,3 +119,36 @@ // CHECK010: crt1.o // CHECK010: "-L/tmp" // CHECK010-NOT: "-lstandalone" + +// ----------------------------------------------------------------------------- +// unwindlib +// ----------------------------------------------------------------------------- +// RUN: %clangxx --unwindlib=none \ +// RUN: --target=hexagon-unknown-linux-musl %s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK011 %s +// CHECK011: InstalledDir: [[INSTALLED_DIR:.+]] +// CHECK011: crt1.o +// CHECK011-NOT: "-lunwind" +// CHECK011-NOT: "-lgcc_eh" +// CHECK012-NOT: "-lgcc_s" + + +// RUN: %clangxx --rtlib=compiler-rt --unwindlib=libunwind \ +// RUN: --target=hexagon-unknown-linux-musl %s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK012 %s +// RUN: %clangxx \ +// RUN: --target=hexagon-unknown-linux-musl %s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK012 %s +// CHECK012: InstalledDir: [[INSTALLED_DIR:.+]] +// CHECK012: crt1.o +// CHECK012: "-lunwind" +// CHECK012-NOT: "-lgcc_eh" +// CHECK012-NOT: "-lgcc_s" + +// RUN: not %clangxx --rtlib=compiler-rt --unwindlib=libgcc \ +// RUN: --target=hexagon-unknown-linux-musl %s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK013 %s +// CHECK013: error: unsupported unwind library 'libgcc' for platform 'hexagon-unknown-linux-musl' +// CHECK013-NOT: "-lgcc_eh" +// CHECK013-NOT: "-lgcc_s" +// CHECK013-NOT: "-lunwind" diff --git a/clang/test/Driver/immediate-options.c b/clang/test/Driver/immediate-options.c index 77878fe2e9c58..b74f6b41f22a0 100644 --- a/clang/test/Driver/immediate-options.c +++ b/clang/test/Driver/immediate-options.c @@ -2,6 +2,8 @@ // HELP: isystem // HELP-NOT: ast-dump // HELP-NOT: driver-mode +// HELP: -Wa, +// HELP-NOT: -W{{[a-z][a-z]}} // Make sure that Flang-only options are not available in Clang // HELP-NOT: test-io diff --git a/clang/test/Driver/linker-wrapper-libs.c b/clang/test/Driver/linker-wrapper-libs.c index 22cc24f2e258a..44331b90e7d93 100644 --- a/clang/test/Driver/linker-wrapper-libs.c +++ b/clang/test/Driver/linker-wrapper-libs.c @@ -48,7 +48,7 @@ int bar() { return weak; } // RUN: --linker-path=/usr/bin/ld %t.a %t.o -o a.out 2>&1 \ // RUN: | FileCheck %s --check-prefix=LIBRARY-RESOLVES -// LIBRARY-RESOLVES: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.s {{.*}}.o +// LIBRARY-RESOLVES: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o // LIBRARY-RESOLVES: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o // @@ -72,7 +72,7 @@ int bar() { return weak; } // RUN: --linker-path=/usr/bin/ld %t.a %t.o -o a.out 2>&1 \ // RUN: | FileCheck %s --check-prefix=LIBRARY-GLOBAL -// LIBRARY-GLOBAL: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.s {{.*}}.o +// LIBRARY-GLOBAL: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o // LIBRARY-GLOBAL: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o // @@ -96,7 +96,7 @@ int bar() { return weak; } // RUN: | FileCheck %s --check-prefix=LIBRARY-GLOBAL-NONE // LIBRARY-GLOBAL-NONE-NOT: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o -// LIBRARY-GLOBAL-NONE-NOT: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.s {{.*}}.o +// LIBRARY-GLOBAL-NONE-NOT: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o // // Check that we do not extract an external weak symbol. @@ -161,7 +161,7 @@ int bar() { return weak; } // RUN: --linker-path=/usr/bin/ld %t.o %t.a %t.a -o a.out 2>&1 \ // RUN: | FileCheck %s --check-prefix=LIBRARY-GLOBAL-DEFINED -// LIBRARY-GLOBAL-DEFINED: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.s {{.*}}.o +// LIBRARY-GLOBAL-DEFINED: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}} {{.*}}.o // LIBRARY-GLOBAL-DEFINED-NOT: {{.*}}gfx1030{{.*}}.o // LIBRARY-GLOBAL-DEFINED: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o @@ -185,7 +185,7 @@ int bar() { return weak; } // RUN: --linker-path=/usr/bin/ld %t.o --whole-archive %t.a -o a.out 2>&1 \ // RUN: | FileCheck %s --check-prefix=LIBRARY-WHOLE-ARCHIVE -// LIBRARY-WHOLE-ARCHIVE: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.s {{.*}}.o +// LIBRARY-WHOLE-ARCHIVE: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}} {{.*}}.o // LIBRARY-WHOLE-ARCHIVE: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o -// LIBRARY-WHOLE-ARCHIVE: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_52 {{.*}}.s +// LIBRARY-WHOLE-ARCHIVE: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_52 {{.*}}.o // LIBRARY-WHOLE-ARCHIVE: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx90a {{.*}}.o diff --git a/clang/test/Driver/linker-wrapper-passes.c b/clang/test/Driver/linker-wrapper-passes.c index aadcf472e9b63..fb63ef7970ac7 100644 --- a/clang/test/Driver/linker-wrapper-passes.c +++ b/clang/test/Driver/linker-wrapper-passes.c @@ -4,6 +4,9 @@ // REQUIRES: x86-registered-target // REQUIRES: amdgpu-registered-target +// https://github.com/llvm/llvm-project/issues/100212 +// XFAIL: * + // Setup. // RUN: mkdir -p %t // RUN: %clang -cc1 -emit-llvm-bc -o %t/host-x86_64-unknown-linux-gnu.bc \ @@ -13,7 +16,7 @@ // RUN: opt %t/openmp-amdgcn-amd-amdhsa.bc -o %t/openmp-amdgcn-amd-amdhsa.bc \ // RUN: -passes=forceattrs -force-remove-attribute=f:noinline // RUN: clang-offload-packager -o %t/openmp-x86_64-unknown-linux-gnu.out \ -// RUN: --image=file=%t/openmp-amdgcn-amd-amdhsa.bc,triple=amdgcn-amd-amdhsa +// RUN: --image=file=%t/openmp-amdgcn-amd-amdhsa.bc,arch=gfx90a,triple=amdgcn-amd-amdhsa // RUN: %clang -cc1 -S -o %t/host-x86_64-unknown-linux-gnu.s \ // RUN: -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa \ // RUN: -fembed-offload-object=%t/openmp-x86_64-unknown-linux-gnu.out \ diff --git a/clang/test/Driver/linker-wrapper.c b/clang/test/Driver/linker-wrapper.c index b9fa08ace0ff7..a205247c77161 100644 --- a/clang/test/Driver/linker-wrapper.c +++ b/clang/test/Driver/linker-wrapper.c @@ -48,7 +48,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run --save-temps -O2 \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=AMDGPU-LTO-TEMPS -// AMDGPU-LTO-TEMPS: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx1030 -O2 -Wl,--no-undefined {{.*}}.s -save-temps +// AMDGPU-LTO-TEMPS: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx1030 -O2 -Wl,--no-undefined {{.*}} -save-temps // RUN: clang-offload-packager -o %t.out \ // RUN: --image=file=%t.elf.o,kind=openmp,triple=x86_64-unknown-linux-gnu \ @@ -128,14 +128,15 @@ __attribute__((visibility("protected"), used)) int x; // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o \ // RUN: -fembed-offload-object=%t.out // RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu \ -// RUN: --linker-path=/usr/bin/ld --device-linker=a --device-linker=nvptx64-nvidia-cuda=b \ +// RUN: --linker-path=/usr/bin/ld --device-linker=foo=bar --device-linker=a \ +// RUN: --device-linker=nvptx64-nvidia-cuda=b --device-compiler=foo\ // RUN: %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=LINKER-ARGS -// LINKER-ARGS: clang{{.*}}--target=amdgcn-amd-amdhsa{{.*}}a -// LINKER-ARGS: clang{{.*}}--target=nvptx64-nvidia-cuda{{.*}}a b +// LINKER-ARGS: clang{{.*}}--target=amdgcn-amd-amdhsa{{.*}}-Xlinker foo=bar{{.*}}-Xlinker a{{.*}}foo +// LINKER-ARGS: clang{{.*}}--target=nvptx64-nvidia-cuda{{.*}}-Xlinker foo=bar{{.*}}-Xlinker a -Xlinker b{{.*}}foo -// RUN: not clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu -ldummy \ -// RUN: --linker-path=/usr/bin/ld --device-linker=a --device-linker=nvptx64-nvidia-cuda=b \ +// RUN: not clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu \ +// RUN: -ldummy --linker-path=/usr/bin/ld \ // RUN: -o a.out 2>&1 | FileCheck %s --check-prefix=MISSING-LIBRARY // MISSING-LIBRARY: error: unable to find library -ldummy @@ -147,7 +148,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run --clang-backend \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=CLANG-BACKEND -// CLANG-BACKEND: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx908 -O2 -Wl,--no-undefined {{.*}}.bc +// CLANG-BACKEND: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx908 -O2 -Wl,--no-undefined {{.*}}.o // RUN: clang-offload-packager -o %t.out \ // RUN: --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 @@ -233,3 +234,13 @@ __attribute__((visibility("protected"), used)) int x; // RUN: | FileCheck %s --check-prefix=OVERRIDE // OVERRIDE-NOT: clang // OVERRIDE: /usr/bin/ld + +// RUN: clang-offload-packager -o %t.out \ +// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 +// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out +// RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run --offload-opt=-pass-remarks=foo \ +// RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=OFFLOAD-OPT +// RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run -mllvm -pass-remarks=foo \ +// RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=OFFLOAD-OPT + +// OFFLOAD-OPT: clang{{.*}}-Wl,--plugin-opt=-pass-remarks=foo diff --git a/clang/test/Driver/loongarch-features.c b/clang/test/Driver/loongarch-features.c index 3cdf3ba3d23e1..90634bbcf0035 100644 --- a/clang/test/Driver/loongarch-features.c +++ b/clang/test/Driver/loongarch-features.c @@ -2,7 +2,7 @@ // RUN: %clang --target=loongarch64 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA64 // LA32: "target-features"="+32bit" -// LA64: "target-features"="+64bit,+d,+f,+ual" +// LA64: "target-features"="+64bit,+d,+f,+lsx,+ual" int foo(void) { return 3; diff --git a/clang/test/Driver/loongarch-march.c b/clang/test/Driver/loongarch-march.c index 9214130cd034f..2d5b315d962a1 100644 --- a/clang/test/Driver/loongarch-march.c +++ b/clang/test/Driver/loongarch-march.c @@ -2,10 +2,22 @@ // RUN: FileCheck %s --check-prefix=CC1-LOONGARCH64 // RUN: %clang --target=loongarch64 -march=la464 -fsyntax-only %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefix=CC1-LA464 +// RUN: %clang --target=loongarch64 -march=la64v1.0 -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-LA64V1P0 +// RUN: %clang --target=loongarch64 -march=la64v1.1 -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-LA64V1P1 +// RUN: %clang --target=loongarch64 -march=la664 -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-LA664 // RUN: %clang --target=loongarch64 -march=loongarch64 -S -emit-llvm %s -o - | \ // RUN: FileCheck %s --check-prefix=IR-LOONGARCH64 // RUN: %clang --target=loongarch64 -march=la464 -S -emit-llvm %s -o - | \ // RUN: FileCheck %s --check-prefix=IR-LA464 +// RUN: %clang --target=loongarch64 -march=la64v1.0 -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-LA64V1P0 +// RUN: %clang --target=loongarch64 -march=la64v1.1 -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-LA64V1P1 +// RUN: %clang --target=loongarch64 -march=la664 -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-LA664 // CC1-LOONGARCH64: "-target-cpu" "loongarch64" // CC1-LOONGARCH64-NOT: "-target-feature" @@ -19,8 +31,29 @@ // CC1-LA464-NOT: "-target-feature" // CC1-LA464: "-target-abi" "lp64d" +// CC1-LA64V1P0: "-target-cpu" "loongarch64" +// CC1-LA64V1P0-NOT: "-target-feature" +// CC1-LA64V1P0: "-target-feature" "+64bit" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+ual" +// CC1-LA64V1P0-NOT: "-target-feature" +// CC1-LA64V1P0: "-target-abi" "lp64d" + +// CC1-LA64V1P1: "-target-cpu" "loongarch64" +// CC1-LA64V1P1-NOT: "-target-feature" +// CC1-LA64V1P1: "-target-feature" "+64bit" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+ual" "-target-feature" "+frecipe" +// CC1-LA64V1P1-NOT: "-target-feature" +// CC1-LA64V1P1: "-target-abi" "lp64d" + +// CC1-LA664: "-target-cpu" "la664" +// CC1-LA664-NOT: "-target-feature" +// CC1-LA664: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" "-target-feature" "+ual" "-target-feature" "+frecipe" +// CC1-LA664-NOT: "-target-feature" +// CC1-LA664: "-target-abi" "lp64d" + // IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+f,+ual" // IR-LA464: attributes #[[#]] ={{.*}}"target-cpu"="la464" {{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+ual" +// IR-LA64V1P0: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+lsx,+ual" +// IR-LA64V1P1: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+frecipe,+lsx,+ual" +// IR-LA664: attributes #[[#]] ={{.*}}"target-cpu"="la664" {{.*}}"target-features"="+64bit,+d,+f,+frecipe,+lasx,+lsx,+ual" int foo(void) { return 3; diff --git a/clang/test/Driver/loongarch-mlasx.c b/clang/test/Driver/loongarch-mlasx.c index 0b934f125c9e4..87634ff5a9a40 100644 --- a/clang/test/Driver/loongarch-mlasx.c +++ b/clang/test/Driver/loongarch-mlasx.c @@ -5,7 +5,7 @@ // RUN: %clang --target=loongarch64 -mno-lasx -fsyntax-only %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefix=CC1-NOLASX // RUN: %clang --target=loongarch64 -mlasx -mno-lasx -fsyntax-only %s -### 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CC1-NOLASX +// RUN: FileCheck %s --check-prefix=CC1-LSX // RUN: %clang --target=loongarch64 -mno-lasx -mlasx -fsyntax-only %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefix=CC1-LASX // RUN: %clang --target=loongarch64 -mlsx -mlasx -fsyntax-only %s -### 2>&1 | \ @@ -18,7 +18,7 @@ // RUN: %clang --target=loongarch64 -mno-lasx -S -emit-llvm %s -o - | \ // RUN: FileCheck %s --check-prefix=IR-NOLASX // RUN: %clang --target=loongarch64 -mlasx -mno-lasx -S -emit-llvm %s -o - | \ -// RUN: FileCheck %s --check-prefix=IR-NOLASX +// RUN: FileCheck %s --check-prefix=IR-LSX // RUN: %clang --target=loongarch64 -mno-lasx -mlasx -S -emit-llvm %s -o - | \ // RUN: FileCheck %s --check-prefix=IR-LASX // RUN: %clang --target=loongarch64 -mlsx -mlasx -S -emit-llvm %s -o - | \ @@ -26,9 +26,11 @@ // RUN: %clang --target=loongarch64 -mlasx -mlsx -S -emit-llvm %s -o - | \ // RUN: FileCheck %s --check-prefix=IR-LASX +// CC1-LSX: "-target-feature" "+lsx" // CC1-LASX: "-target-feature" "+lsx" "-target-feature" "+lasx" // CC1-NOLASX: "-target-feature" "-lasx" +// IR-LSX: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}+lsx{{(,.*)?}}" // IR-LASX: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}+lasx{{(,.*)?}}" // IR-NOLASX: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}-lasx{{(,.*)?}}" diff --git a/clang/test/Driver/loongarch-msimd.c b/clang/test/Driver/loongarch-msimd.c index cd463300c8747..49d298e1b2e3f 100644 --- a/clang/test/Driver/loongarch-msimd.c +++ b/clang/test/Driver/loongarch-msimd.c @@ -75,9 +75,9 @@ // RUN: FileCheck %s --check-prefixes=LSX,LASX // RUN: %clang --target=loongarch64 -mlasx -mno-lasx -msimd=lasx -fsyntax-only %s -### 2>&1 | \ -// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX +// RUN: FileCheck %s --check-prefixes=LSX,NOLASX // RUN: %clang --target=loongarch64 -mno-lasx -msimd=lasx -fsyntax-only %s -### 2>&1 | \ -// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX +// RUN: FileCheck %s --check-prefixes=LSX,NOLASX // RUN: %clang --target=loongarch64 -mlasx -mno-lasx -mlsx -msimd=lasx -fsyntax-only %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefixes=LSX,NOLASX diff --git a/clang/test/Driver/loongarch-msingle-float.c b/clang/test/Driver/loongarch-msingle-float.c index bd9b3e8a8c019..4eb0865b53a59 100644 --- a/clang/test/Driver/loongarch-msingle-float.c +++ b/clang/test/Driver/loongarch-msingle-float.c @@ -11,10 +11,10 @@ // WARN: warning: ignoring '-mabi=lp64s' as it conflicts with that implied by '-msingle-float' (lp64f) // WARN: warning: ignoring '-mfpu=64' as it conflicts with that implied by '-msingle-float' (32) -// CC1: "-target-feature" "+f"{{.*}} "-target-feature" "-d" +// CC1: "-target-feature" "+f"{{.*}} "-target-feature" "-d" "-target-feature" "-lsx" // CC1: "-target-abi" "lp64f" -// IR: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}+f,{{(.*,)?}}-d" +// IR: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}+f,{{(.*,)?}}-d,-lsx" int foo(void) { return 3; diff --git a/clang/test/Driver/loongarch-msoft-float.c b/clang/test/Driver/loongarch-msoft-float.c index 0e5121ac84b4c..ebf27fb00e309 100644 --- a/clang/test/Driver/loongarch-msoft-float.c +++ b/clang/test/Driver/loongarch-msoft-float.c @@ -11,10 +11,10 @@ // WARN: warning: ignoring '-mabi=lp64d' as it conflicts with that implied by '-msoft-float' (lp64s) // WARN: warning: ignoring '-mfpu=64' as it conflicts with that implied by '-msoft-float' (0) -// CC1: "-target-feature" "-f"{{.*}} "-target-feature" "-d" +// CC1: "-target-feature" "-f"{{.*}} "-target-feature" "-d" "-target-feature" "-lsx" // CC1: "-target-abi" "lp64s" -// IR: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}-d,{{(.*,)?}}-f{{(,.*)?}}" +// IR: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}-d,{{(.*,)?}}-f,-lsx" int foo(void) { return 3; diff --git a/clang/test/Driver/loongarch-mtune.c b/clang/test/Driver/loongarch-mtune.c index 6f3f39e9bbd86..face12e1a1a82 100644 --- a/clang/test/Driver/loongarch-mtune.c +++ b/clang/test/Driver/loongarch-mtune.c @@ -8,6 +8,11 @@ // RUN: %clang --target=loongarch64 -mtune=la464 -S -emit-llvm %s -o - | \ // RUN: FileCheck %s --check-prefix=IRATTR -DCPU=la464 +// RUN: %clang --target=loongarch64 -mtune=la664 -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=la664 +// RUN: %clang --target=loongarch64 -mtune=la664 -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IRATTR -DCPU=la664 + // RUN: %clang --target=loongarch64 -mtune=invalidcpu -fsyntax-only %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=invalidcpu // RUN: not %clang --target=loongarch64 -mtune=invalidcpu -S -emit-llvm %s -o /dev/null 2>&1 | \ diff --git a/clang/test/Driver/lto-jobs.c b/clang/test/Driver/lto-jobs.c index 43a478b0664d8..2c7ca02ea4779 100644 --- a/clang/test/Driver/lto-jobs.c +++ b/clang/test/Driver/lto-jobs.c @@ -6,12 +6,15 @@ // RUN: %clang --target=x86_64-sie-ps5 -### %s -flto=thin -flto-jobs=5 2> %t // RUN: FileCheck -check-prefix=CHECK-LINK-THIN-JOBS-ACTION < %t %s // +// RUN: %clang --target=x86_64-sie-ps5 -### %s -flto-jobs=5 2> %t +// RUN: FileCheck -check-prefix=CHECK-LINK-THIN-JOBS-ACTION < %t %s +// // CHECK-LINK-THIN-JOBS-ACTION: "-plugin-opt=jobs=5" // // RUN: %clang --target=x86_64-scei-ps4 -### %s -flto=thin -flto-jobs=5 2> %t // RUN: FileCheck -check-prefix=CHECK-PS4-LINK-THIN-JOBS-ACTION < %t %s // -// CHECK-PS4-LINK-THIN-JOBS-ACTION: "-lto-thin-debug-options= -generate-arange-section -threads=5" +// CHECK-PS4-LINK-THIN-JOBS-ACTION: "-lto-debug-options= -threads=5" // RUN: %clang --target=x86_64-apple-darwin13.3.0 -### %s -flto=thin -flto-jobs=5 2> %t // RUN: FileCheck -check-prefix=CHECK-LINK-THIN-JOBS2-ACTION < %t %s diff --git a/clang/test/Driver/modulemap-allow-subdirectory-search.c b/clang/test/Driver/modulemap-allow-subdirectory-search.c new file mode 100644 index 0000000000000..ee993a75b5272 --- /dev/null +++ b/clang/test/Driver/modulemap-allow-subdirectory-search.c @@ -0,0 +1,27 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t + +// Check that with a sufficiently new SDK not searching for module maps in subdirectories. + +// New SDK. +// RUN: %clang -target x86_64-apple-macos10.13 -isysroot %t/MacOSX15.0.sdk -fmodules %t/test.c -### 2>&1 \ +// RUN: | FileCheck --check-prefix=NO-SUBDIRECTORIES %t/test.c +// Old SDK. +// RUN: %clang -target x86_64-apple-macos10.13 -isysroot %t/MacOSX14.0.sdk -fmodules %t/test.c -### 2>&1 \ +// RUN: | FileCheck --check-prefix=SEARCH-SUBDIRECTORIES %t/test.c +// Non-Darwin platform. +// RUN: %clang -target i386-unknown-linux -isysroot %t/MacOSX15.0.sdk -fmodules %t/test.c -### 2>&1 \ +// RUN: | FileCheck --check-prefix=SEARCH-SUBDIRECTORIES %t/test.c +// New SDK overriding the default. +// RUN: %clang -target x86_64-apple-macos10.13 -isysroot %t/MacOSX15.0.sdk -fmodules %t/test.c -fmodulemap-allow-subdirectory-search -### 2>&1 \ +// RUN: | FileCheck --check-prefix=SEARCH-SUBDIRECTORIES %t/test.c + +//--- test.c +// NO-SUBDIRECTORIES: "-fno-modulemap-allow-subdirectory-search" +// SEARCH-SUBDIRECTORIES-NOT: "-fno-modulemap-allow-subdirectory-search" + +//--- MacOSX15.0.sdk/SDKSettings.json +{"Version":"15.0", "MaximumDeploymentTarget": "15.0.99"} + +//--- MacOSX14.0.sdk/SDKSettings.json +{"Version":"14.0", "MaximumDeploymentTarget": "14.0.99"} diff --git a/clang/test/Driver/nvlink-wrapper.c b/clang/test/Driver/nvlink-wrapper.c new file mode 100644 index 0000000000000..318315ddaca34 --- /dev/null +++ b/clang/test/Driver/nvlink-wrapper.c @@ -0,0 +1,72 @@ +// REQUIRES: x86-registered-target +// REQUIRES: nvptx-registered-target + +#if defined(X) +extern int y; +int foo() { return y; } + +int x = 0; +#elif defined(Y) +int y = 42; +#elif defined(Z) +int z = 42; +#elif defined(W) +int w = 42; +#elif defined(U) +extern int x; +extern int __attribute__((weak)) w; + +int bar() { + return x + w; +} +#else +extern int y; +int __attribute__((visibility("hidden"))) x = 999; +int baz() { return y + x; } +#endif + +// Create various inputs to test basic linking and LTO capabilities. Creating a +// CUDA binary requires access to the `ptxas` executable, so we just use x64. +// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -DX -o %t-x.o +// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -DY -o %t-y.o +// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -DZ -o %t-z.o +// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -DW -o %t-w.o +// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -DU -o %t-u.o +// RUN: llvm-ar rcs %t-x.a %t-x.o +// RUN: llvm-ar rcs %t-y.a %t-y.o +// RUN: llvm-ar rcs %t-z.a %t-z.o +// RUN: llvm-ar rcs %t-w.a %t-w.o + +// +// Check that we forward any unrecognized argument to 'nvlink'. +// +// RUN: clang-nvlink-wrapper --dry-run -arch sm_52 %t-u.o -foo -o a.out 2>&1 \ +// RUN: | FileCheck %s --check-prefix=ARGS +// ARGS: nvlink{{.*}} -arch sm_52 -foo -o a.out [[INPUT:.+]].cubin + +// +// Check the symbol resolution for static archives. We expect to only link +// `libx.a` and `liby.a` because extern weak symbols do not extract and `libz.a` +// is not used at all. +// +// RUN: clang-nvlink-wrapper --dry-run %t-x.a %t-u.o %t-y.a %t-z.a %t-w.a \ +// RUN: -arch sm_52 -o a.out 2>&1 | FileCheck %s --check-prefix=LINK +// LINK: nvlink{{.*}} -arch sm_52 -o a.out [[INPUT:.+]].cubin {{.*}}-x-{{.*}}.cubin{{.*}}-y-{{.*}}.cubin + +// RUN: %clang -cc1 %s -triple nvptx64-nvidia-cuda -emit-llvm-bc -o %t.o + +// +// Check that the LTO interface works and properly preserves symbols used in a +// regular object file. +// +// RUN: clang-nvlink-wrapper --dry-run %t.o %t-u.o %t-y.a \ +// RUN: -arch sm_52 -o a.out 2>&1 | FileCheck %s --check-prefix=LTO +// LTO: ptxas{{.*}} -m64 -c [[PTX:.+]].s -O3 -arch sm_52 -o [[CUBIN:.+]].cubin +// LTO: nvlink{{.*}} -arch sm_52 -o a.out [[CUBIN]].cubin {{.*}}-u-{{.*}}.cubin {{.*}}-y-{{.*}}.cubin + +// +// Check that we don't forward some arguments. +// +// RUN: clang-nvlink-wrapper --dry-run %t.o %t-u.o %t-y.a \ +// RUN: -arch sm_52 --cuda-path/opt/cuda -o a.out 2>&1 | FileCheck %s --check-prefix=PATH +// PATH-NOT: --cuda-path=/opt/cuda diff --git a/clang/test/Driver/opencl.cl b/clang/test/Driver/opencl.cl index aba37fc328fbb..3b0b191827b4c 100644 --- a/clang/test/Driver/opencl.cl +++ b/clang/test/Driver/opencl.cl @@ -35,7 +35,7 @@ // CHECK-OPT-DISABLE: "-cc1" {{.*}} "-cl-opt-disable" // CHECK-STRICT-ALIASING: "-cc1" {{.*}} "-cl-strict-aliasing" // CHECK-SINGLE-PRECISION-CONST: "-cc1" {{.*}} "-cl-single-precision-constant" -// CHECK-FINITE-MATH-ONLY: "-cc1" {{.*}} "-cl-finite-math-only" +// CHECK-FINITE-MATH-ONLY: "-cc1" {{.*}} "-menable-no-infs" "-menable-no-nans" "-cl-finite-math-only" // CHECK-KERNEL-ARG-INFO: "-cc1" {{.*}} "-cl-kernel-arg-info" // CHECK-UNSAFE-MATH-OPT: "-cc1" {{.*}} "-cl-unsafe-math-optimizations" // CHECK-FAST-RELAXED-MATH: "-cc1" {{.*}} "-cl-fast-relaxed-math" diff --git a/clang/test/Driver/openmp-offload-gpu.c b/clang/test/Driver/openmp-offload-gpu.c index 31287b27deb5f..d3f9f04ae85d1 100644 --- a/clang/test/Driver/openmp-offload-gpu.c +++ b/clang/test/Driver/openmp-offload-gpu.c @@ -372,33 +372,9 @@ // XARCH-DEVICE: "-cc1" "-triple" "nvptx64-nvidia-cuda"{{.*}}"-O3" // XARCH-DEVICE-NOT: "-cc1" "-triple" "x86_64-unknown-linux-gnu"{{.*}}"-O3" -// -// Check that `-gpulibc` includes the LLVM C libraries for the GPU. -// -// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp \ -// RUN: --libomptarget-nvptx-bc-path=%S/Inputs/libomptarget/libomptarget-nvptx-test.bc \ -// RUN: --libomptarget-amdgpu-bc-path=%S/Inputs/hip_dev_lib/libomptarget-amdgpu-gfx803.bc \ -// RUN: --cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \ -// RUN: --rocm-path=%S/Inputs/rocm \ -// RUN: --offload-arch=sm_52,gfx803 -gpulibc -nogpuinc %s 2>&1 \ -// RUN: | FileCheck --check-prefix=LIBC-GPU %s -// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp \ -// RUN: --libomptarget-nvptx-bc-path=%S/Inputs/libomptarget/libomptarget-nvptx-test.bc \ -// RUN: --libomptarget-amdgpu-bc-path=%S/Inputs/hip_dev_lib/libomptarget-amdgpu-gfx803.bc \ -// RUN: --cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \ -// RUN: --rocm-path=%S/Inputs/rocm \ -// RUN: -Xopenmp-target=nvptx64-nvidia-cuda -march=sm_52 \ -// RUN: -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx803 \ -// RUN: -fopenmp-targets=nvptx64-nvidia-cuda,amdgcn-amd-amdhsa -gpulibc -nogpuinc %s 2>&1 \ -// RUN: | FileCheck --check-prefix=LIBC-GPU %s -// LIBC-GPU-DAG: "-lcgpu-amdgpu" -// LIBC-GPU-DAG: "-lmgpu-amdgpu" -// LIBC-GPU-DAG: "-lcgpu-nvptx" -// LIBC-GPU-DAG: "-lmgpu-nvptx" - // RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp \ // RUN: --libomptarget-nvptx-bc-path=%S/Inputs/libomptarget/libomptarget-nvptx-test.bc \ // RUN: --cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \ // RUN: --offload-arch=sm_52 -nogpulibc -nogpuinc %s 2>&1 \ -// RUN: | FileCheck --check-prefix=NO-LIBC-GPU %s -// NO-LIBC-GPU-NOT: -lmgpu{{.*}}-lcgpu +// RUN: | FileCheck --check-prefix=LIBC-GPU %s +// LIBC-GPU: clang-linker-wrapper{{.*}}"--device-compiler=-nolibc" diff --git a/clang/test/Driver/ppc-unsupported.c b/clang/test/Driver/ppc-unsupported.c index dde4d8d1c1935..c2746bba16129 100644 --- a/clang/test/Driver/ppc-unsupported.c +++ b/clang/test/Driver/ppc-unsupported.c @@ -16,4 +16,8 @@ // RUN: -c %s 2>&1 | FileCheck %s // RUN: not %clang -target powerpc-unknown-aix -mabi=quadword-atomics \ // RUN: -c %s 2>&1 | FileCheck %s +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -msave-reg-params \ +// RUN: -c %s 2>&1 | FileCheck %s +// RUN: not %clang -target powerpc-unknown-unknown -msave-reg-params \ +// RUN: -c %s 2>&1 | FileCheck %s // CHECK: unsupported option diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c index 1dc4580ec202e..91f12b8416b2a 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -35,7 +35,6 @@ // CHECK-NEXT: za64rs 1.0 'Za64rs' (Reservation Set Size of at Most 64 Bytes) // CHECK-NEXT: zaamo 1.0 'Zaamo' (Atomic Memory Operations) // CHECK-NEXT: zabha 1.0 'Zabha' (Byte and Halfword Atomic Memory Operations) -// CHECK-NEXT: zacas 1.0 'Zacas' (Atomic Compare-And-Swap Instructions) // CHECK-NEXT: zalrsc 1.0 'Zalrsc' (Load-Reserved/Store-Conditional) // CHECK-NEXT: zama16b 1.0 'Zama16b' (Atomic 16-byte misaligned loads, stores and AMOs) // CHECK-NEXT: zawrs 1.0 'Zawrs' (Wait on Reservation Set) @@ -171,6 +170,7 @@ // CHECK-NEXT: Experimental extensions // CHECK-NEXT: zicfilp 1.0 'Zicfilp' (Landing pad) // CHECK-NEXT: zicfiss 1.0 'Zicfiss' (Shadow stack) +// CHECK-NEXT: zacas 1.0 'Zacas' (Atomic Compare-And-Swap Instructions) // CHECK-NEXT: zalasr 0.1 'Zalasr' (Load-Acquire and Store-Release Instructions) // CHECK-NEXT: smmpm 1.0 'Smmpm' (Machine-level Pointer Masking for M-mode) // CHECK-NEXT: smnpm 1.0 'Smnpm' (Machine-level Pointer Masking for next lower privilege mode) diff --git a/clang/test/Driver/ps4-linker.c b/clang/test/Driver/ps4-linker.c index be0103bffe813..2a095d660bf36 100644 --- a/clang/test/Driver/ps4-linker.c +++ b/clang/test/Driver/ps4-linker.c @@ -1,20 +1,23 @@ // Test the driver's control over the JustMyCode behavior with linker flags. -// RUN: %clang --target=x86_64-scei-ps4 -fjmc %s -### 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-LIB %s -// RUN: %clang --target=x86_64-scei-ps4 -flto=thin -fjmc %s -### 2>&1 | FileCheck --check-prefixes=CHECK-THIN-LTO,CHECK-LIB %s -// RUN: %clang --target=x86_64-scei-ps4 -flto=full -fjmc %s -### 2>&1 | FileCheck --check-prefixes=CHECK-FULL-LTO,CHECK-LIB %s +// RUN: %clang --target=x86_64-scei-ps4 -fjmc %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LTO,CHECK-LIB %s +// RUN: %clang --target=x86_64-scei-ps4 -flto=thin -fjmc %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LTO,CHECK-LIB %s +// RUN: %clang --target=x86_64-scei-ps4 -flto=full -fjmc %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LTO,CHECK-LIB %s -// CHECK-NOT: -enable-jmc-instrument -// CHECK-THIN-LTO: "-lto-thin-debug-options= -generate-arange-section -enable-jmc-instrument" -// CHECK-FULL-LTO: "-lto-debug-options= -generate-arange-section -enable-jmc-instrument" +// CHECK-LTO: "-lto-debug-options= -enable-jmc-instrument" // Check the default library name. // CHECK-LIB: "--whole-archive" "-lSceDbgJmc" "--no-whole-archive" // Test the driver's control over the -fcrash-diagnostics-dir behavior with linker flags. -// RUN: %clang --target=x86_64-scei-ps4 -flto=thin -fcrash-diagnostics-dir=mydumps %s -### 2>&1 | FileCheck --check-prefixes=CHECK-DIAG-THIN-LTO %s -// RUN: %clang --target=x86_64-scei-ps4 -flto=full -fcrash-diagnostics-dir=mydumps %s -### 2>&1 | FileCheck --check-prefixes=CHECK-DIAG-FULL-LTO %s +// RUN: %clang --target=x86_64-scei-ps4 -fcrash-diagnostics-dir=mydumps %s -### 2>&1 | FileCheck --check-prefixes=CHECK-DIAG-LTO %s +// RUN: %clang --target=x86_64-scei-ps4 -flto=thin -fcrash-diagnostics-dir=mydumps %s -### 2>&1 | FileCheck --check-prefixes=CHECK-DIAG-LTO %s +// RUN: %clang --target=x86_64-scei-ps4 -flto=full -fcrash-diagnostics-dir=mydumps %s -### 2>&1 | FileCheck --check-prefixes=CHECK-DIAG-LTO %s -// CHECK-DIAG-THIN-LTO: "-lto-thin-debug-options= -generate-arange-section -crash-diagnostics-dir=mydumps" -// CHECK-DIAG-FULL-LTO: "-lto-debug-options= -generate-arange-section -crash-diagnostics-dir=mydumps" +// CHECK-DIAG-LTO: "-lto-debug-options= -crash-diagnostics-dir=mydumps" + +// Test that -lto-debug-options is only supplied to the linker when necessary + +// RUN: %clang --target=x86_64-scei-ps4 %s -### 2>&1 | FileCheck --check-prefixes=CHECK-NO-LTO %s +// CHECK-NO-LTO-NOT: -lto-debug-options diff --git a/clang/test/Driver/ps4-ps5-runtime-flags.c b/clang/test/Driver/ps4-ps5-runtime-flags.c index e75ba97948d23..4b00aead6fe5c 100644 --- a/clang/test/Driver/ps4-ps5-runtime-flags.c +++ b/clang/test/Driver/ps4-ps5-runtime-flags.c @@ -40,5 +40,5 @@ // RUN: %clang -target x86_64-sie-ps5 -fcs-profile-generate %s -### 2>&1 | FileCheck --check-prefix=CHECK-PS5-PROFILE %s // RUN: %clang -target x86_64-sie-ps5 -fcs-profile-generate -fno-profile-generate %s -### 2>&1 | FileCheck --check-prefix=CHECK-PS5-NO-PROFILE %s // -// CHECK-PS5-PROFILE: "--dependent-lib=libclang_rt.profile-x86_64_nosubmission.a" -// CHECK-PS5-NO-PROFILE-NOT: "--dependent-lib=libclang_rt.profile-x86_64_nosubmission.a" +// CHECK-PS5-PROFILE: "--dependent-lib=libclang_rt.profile_nosubmission.a" +// CHECK-PS5-NO-PROFILE-NOT: "--dependent-lib=libclang_rt.profile_nosubmission.a" diff --git a/clang/test/Driver/ps5-linker.c b/clang/test/Driver/ps5-linker.c index 9f1e3a273b2db..cf39d5bae97ac 100644 --- a/clang/test/Driver/ps5-linker.c +++ b/clang/test/Driver/ps5-linker.c @@ -1,10 +1,9 @@ // Test the driver's control over the JustMyCode behavior with linker flags. // RUN: %clang --target=x86_64-scei-ps5 -fjmc %s -### 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-LIB %s -// RUN: %clang --target=x86_64-scei-ps5 -flto -fjmc %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LTO,CHECK-LIB %s +// RUN: %clang --target=x86_64-scei-ps5 -flto -fjmc %s -### 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-LIB %s -// CHECK-NOT: -plugin-opt=-enable-jmc-instrument -// CHECK-LTO: -plugin-opt=-enable-jmc-instrument +// CHECK: -plugin-opt=-enable-jmc-instrument // Check the default library name. // CHECK-LIB: "--whole-archive" "-lSceJmc_nosubmission" "--no-whole-archive" @@ -12,7 +11,6 @@ // Test the driver's control over the -fcrash-diagnostics-dir behavior with linker flags. // RUN: %clang --target=x86_64-scei-ps5 -fcrash-diagnostics-dir=mydumps %s -### 2>&1 | FileCheck --check-prefixes=CHECK-DIAG %s -// RUN: %clang --target=x86_64-scei-ps5 -flto -fcrash-diagnostics-dir=mydumps %s -### 2>&1 | FileCheck --check-prefixes=CHECK-DIAG-LTO %s +// RUN: %clang --target=x86_64-scei-ps5 -flto -fcrash-diagnostics-dir=mydumps %s -### 2>&1 | FileCheck --check-prefixes=CHECK-DIAG %s -// CHECK-DIAG-NOT: -plugin-opt=-crash-diagnostics-dir=mydumps -// CHECK-DIAG-LTO: -plugin-opt=-crash-diagnostics-dir=mydumps +// CHECK-DIAG: -plugin-opt=-crash-diagnostics-dir=mydumps diff --git a/clang/test/Driver/stack-size-section.c b/clang/test/Driver/stack-size-section.c index 71b9f85692b99..7cd41e491a817 100644 --- a/clang/test/Driver/stack-size-section.c +++ b/clang/test/Driver/stack-size-section.c @@ -14,6 +14,7 @@ // RUN: %clang -### --target=x86_64-linux-gnu -flto -fstack-size-section %s 2>&1 | FileCheck %s --check-prefix=LTO // RUN: %clang -### --target=x86_64-linux-gnu -flto -fstack-size-section -fno-stack-size-section %s 2>&1 | FileCheck %s --check-prefix=LTO-NO +// RUN: %clang -### --target=x86_64-sie-ps5 -fstack-size-section %s 2>&1 | FileCheck %s --check-prefix=LTO // LTO: "-plugin-opt=-stack-size-section" // LTO-NO-NOT: "-plugin-opt=-stack-size-section" diff --git a/clang/test/Driver/sycl-spirv-ext-old-model.c b/clang/test/Driver/sycl-spirv-ext-old-model.c index 97ea39ff3ea46..643de972d9f70 100644 --- a/clang/test/Driver/sycl-spirv-ext-old-model.c +++ b/clang/test/Driver/sycl-spirv-ext-old-model.c @@ -61,8 +61,7 @@ // CHECK-DEFAULT-SAME:,+SPV_INTEL_tensor_float32_conversion // CHECK-DEFAULT-SAME:,+SPV_INTEL_optnone // CHECK-DEFAULT-SAME:,+SPV_KHR_non_semantic_info -// CHECK-DEFAULT-SAME:,+SPV_KHR_cooperative_matrix -// CHECK-DEFAULT-SAME:,+SPV_INTEL_memory_access_aliasing" +// CHECK-DEFAULT-SAME:,+SPV_KHR_cooperative_matrix" // CHECK-FPGA-HW: llvm-spirv{{.*}}"-spirv-ext=-all // CHECK-FPGA-HW-SAME:,+SPV_EXT_shader_atomic_float_add // CHECK-FPGA-HW-SAME:,+SPV_EXT_shader_atomic_float_min_max @@ -128,5 +127,4 @@ // CHECK-CPU-SAME:,+SPV_INTEL_optnone // CHECK-CPU-SAME:,+SPV_KHR_non_semantic_info // CHECK-CPU-SAME:,+SPV_KHR_cooperative_matrix -// CHECK-CPU-SAME:,+SPV_INTEL_memory_access_aliasing // CHECK-CPU-SAME:,+SPV_INTEL_fp_max_error" diff --git a/clang/test/Driver/sycl-spirv-metadata-old-model.cpp b/clang/test/Driver/sycl-spirv-metadata-old-model.cpp index 2e19dd9ed1dc4..4efbe45a080b2 100644 --- a/clang/test/Driver/sycl-spirv-metadata-old-model.cpp +++ b/clang/test/Driver/sycl-spirv-metadata-old-model.cpp @@ -9,7 +9,7 @@ // RUN: FileCheck -check-prefix CHECK-WITHOUT %s // CHECK-WITH: llvm-spirv{{.*}} "--spirv-preserve-auxdata" -// CHECK-WITH-SAME: "-spirv-ext=-all,{{.*}},+SPV_INTEL_memory_access_aliasing" +// CHECK-WITH-SAME: "-spirv-ext=-all,{{.*}},+SPV_KHR_cooperative_matrix" // CHECK-WITHOUT: "{{.*}}llvm-spirv" // CHECK-WITHOUT-NOT: --spirv-preserve-auxdata diff --git a/clang/test/Driver/sycl-spirv-obj-old-model.cpp b/clang/test/Driver/sycl-spirv-obj-old-model.cpp index 7a5f6215e31ae..809c52516fbb9 100644 --- a/clang/test/Driver/sycl-spirv-obj-old-model.cpp +++ b/clang/test/Driver/sycl-spirv-obj-old-model.cpp @@ -11,7 +11,7 @@ // SPIRV_DEVICE_OBJ-SAME: "-o" "[[DEVICE_BC:.+\.bc]]" // SPIRV_DEVICE_OBJ: llvm-spirv{{.*}} "-o" "[[DEVICE_SPV:.+\.spv]]" // SPIRV_DEVICE_OBJ-SAME: "--spirv-preserve-auxdata" -// SPIRV_DEVICE_OBJ-SAME: "-spirv-ext=-all,{{.*}},+SPV_INTEL_memory_access_aliasing" +// SPIRV_DEVICE_OBJ-SAME: "-spirv-ext=-all,{{.*}},+SPV_KHR_cooperative_matrix" // SPIRV_DEVICE_OBJ-SAME: "[[DEVICE_BC]]" // SPIRV_DEVICE_OBJ: clang{{.*}} "-cc1" "-triple" "x86_64-unknown-linux-gnu" // SPIRV_DEVICE_OBJ-SAME: "-fsycl-is-host" diff --git a/clang/test/Driver/sycl-spirv-obj.cpp b/clang/test/Driver/sycl-spirv-obj.cpp index 4c86daf4a1264..6c651129f2f3e 100644 --- a/clang/test/Driver/sycl-spirv-obj.cpp +++ b/clang/test/Driver/sycl-spirv-obj.cpp @@ -11,7 +11,7 @@ // SPIRV_DEVICE_OBJ-SAME: "-o" "[[DEVICE_BC:.+\.bc]]" // SPIRV_DEVICE_OBJ: llvm-spirv{{.*}} "-o" "[[DEVICE_SPV:.+\.spv]]" // SPIRV_DEVICE_OBJ-SAME: "--spirv-preserve-auxdata" -// SPIRV_DEVICE_OBJ-SAME: "-spirv-ext=-all,{{.*}},+SPV_INTEL_memory_access_aliasing" +// SPIRV_DEVICE_OBJ-SAME: "-spirv-ext=-all,{{.*}},+SPV_KHR_cooperative_matrix" // SPIRV_DEVICE_OBJ-SAME: "[[DEVICE_BC]]" // SPIRV_DEVICE_OBJ: clang-offload-packager{{.*}} "--image=file=[[DEVICE_SPV]]{{.*}}" // SPIRV_DEVICE_OBJ: clang{{.*}} "-cc1" "-triple" "x86_64-unknown-linux-gnu" diff --git a/clang/test/Driver/unified-lto.c b/clang/test/Driver/unified-lto.c index 3a6fe44f5b32d..445ca0bbf14f1 100644 --- a/clang/test/Driver/unified-lto.c +++ b/clang/test/Driver/unified-lto.c @@ -7,6 +7,27 @@ // NOUNIT-NOT: "-flto-unit" // RUN: %clang --target=x86_64-sie-ps5 -### %s -funified-lto 2>&1 | FileCheck --check-prefix=NOUNILTO %s -// NOUNILTO: clang: warning: argument unused during compilation: '-funified-lto' // NOUNILTO: "-cc1" // NOUNILTO-NOT: "-funified-lto + +// On PlayStation -funified-lto is the default. `-flto(=...)` influences the +// `--lto=...` option passed to linker, unless `-fno-unified-lto` is supplied. +// PS4: +// RUN: %clang --target=x86_64-sie-ps4 -### %s 2>&1 | FileCheck --check-prefixes=LD,LTOFULL %s +// RUN: %clang --target=x86_64-sie-ps4 -### %s -flto 2>&1 | FileCheck --check-prefixes=LD,LTOFULL %s +// RUN: %clang --target=x86_64-sie-ps4 -### %s -flto=full 2>&1 | FileCheck --check-prefixes=LD,LTOFULL %s +// RUN: %clang --target=x86_64-sie-ps4 -### %s -flto=thin 2>&1 | FileCheck --check-prefixes=LD,LTOTHIN %s +// RUN: %clang --target=x86_64-sie-ps4 -### %s -fno-unified-lto -flto=full 2>&1 | FileCheck --check-prefixes=LD,NOLTO %s +// RUN: %clang --target=x86_64-sie-ps4 -### %s -fno-unified-lto -flto=thin 2>&1 | FileCheck --check-prefixes=LD,NOLTO %s +// PS5: +// RUN: %clang --target=x86_64-sie-ps5 -### %s 2>&1 | FileCheck --check-prefixes=LD,LTOFULL %s +// RUN: %clang --target=x86_64-sie-ps5 -### %s -flto 2>&1 | FileCheck --check-prefixes=LD,LTOFULL %s +// RUN: %clang --target=x86_64-sie-ps5 -### %s -flto=full 2>&1 | FileCheck --check-prefixes=LD,LTOFULL %s +// RUN: %clang --target=x86_64-sie-ps5 -### %s -flto=thin 2>&1 | FileCheck --check-prefixes=LD,LTOTHIN %s +// RUN: %clang --target=x86_64-sie-ps5 -### %s -fno-unified-lto -flto=full 2>&1 | FileCheck --check-prefixes=LD,NOLTO %s +// RUN: %clang --target=x86_64-sie-ps5 -### %s -fno-unified-lto -flto=thin 2>&1 | FileCheck --check-prefixes=LD,NOLTO %s + +// LD: {{.*ld(\.exe)?}}" +// LTOFULL-SAME: "--lto=full" +// LTOTHIN-SAME: "--lto=thin" +// NOLTO-NOT: "--lto diff --git a/clang/test/Driver/warn-fsyntax-only.c b/clang/test/Driver/warn-fsyntax-only.c new file mode 100644 index 0000000000000..d13bab41c047a --- /dev/null +++ b/clang/test/Driver/warn-fsyntax-only.c @@ -0,0 +1,7 @@ +// RUN: %clang --target=x86_64 -fsyntax-only -E %s 2>&1 | FileCheck %s --check-prefix=CHECK-PP +// RUN: %clang --target=x86_64 -fsyntax-only -S %s 2>&1 | FileCheck %s --check-prefix=CHECK-ASM +// RUN: %clang --target=x86_64 -fsyntax-only -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-OBJ + +// CHECK-PP: warning: argument unused during compilation: '-fsyntax-only' [-Wunused-command-line-argument] +// CHECK-ASM: warning: argument unused during compilation: '-S' [-Wunused-command-line-argument] +// CHECK-OBJ: warning: argument unused during compilation: '-c' [-Wunused-command-line-argument] diff --git a/clang/test/Driver/x86-target-features.c b/clang/test/Driver/x86-target-features.c index ba61457102a57..7d77ae75f8c47 100644 --- a/clang/test/Driver/x86-target-features.c +++ b/clang/test/Driver/x86-target-features.c @@ -309,8 +309,8 @@ // HRESET: "-target-feature" "+hreset" // NO-HRESET: "-target-feature" "-hreset" -// RUN: %clang --target=i386 -march=i386 -muintr %s -### 2>&1 | FileCheck -check-prefix=UINTR %s -// RUN: %clang --target=i386 -march=i386 -mno-uintr %s -### 2>&1 | FileCheck -check-prefix=NO-UINTR %s +// RUN: %clang --target=x86_64 -muintr %s -### 2>&1 | FileCheck -check-prefix=UINTR %s +// RUN: %clang --target=x86_64 -mno-uintr %s -### 2>&1 | FileCheck -check-prefix=NO-UINTR %s // UINTR: "-target-feature" "+uintr" // NO-UINTR: "-target-feature" "-uintr" @@ -409,6 +409,15 @@ // NONX86-NEXT: warning: argument unused during compilation: '-msse4.2' [-Wunused-command-line-argument] // NONX86-NEXT: error: unsupported option '-mno-sgx' for target 'aarch64' +// RUN: not %clang -### --target=i386 -muintr %s 2>&1 | FileCheck --check-prefix=NON-UINTR %s +// RUN: %clang -### --target=i386 -mno-uintr %s 2>&1 > /dev/null +// RUN: not %clang -### --target=i386 -mapx-features=ndd %s 2>&1 | FileCheck --check-prefix=NON-APX %s +// RUN: not %clang -### --target=i386 -mapxf %s 2>&1 | FileCheck --check-prefix=NON-APX %s +// RUN: %clang -### --target=i386 -mno-apxf %s 2>&1 > /dev/null +// NON-UINTR: error: unsupported option '-muintr' for target 'i386' +// NON-APX: error: unsupported option '-mapx-features=|-mapxf' for target 'i386' +// NON-APX-NOT: error: {{.*}} -mapx-features= + // RUN: %clang --target=i386 -march=i386 -mharden-sls=return %s -### -o %t.o 2>&1 | FileCheck -check-prefixes=SLS-RET,NO-SLS %s // RUN: %clang --target=i386 -march=i386 -mharden-sls=indirect-jmp %s -### -o %t.o 2>&1 | FileCheck -check-prefixes=SLS-IJMP,NO-SLS %s // RUN: %clang --target=i386 -march=i386 -mharden-sls=none -mharden-sls=all %s -### -o %t.o 2>&1 | FileCheck -check-prefixes=SLS-IJMP,SLS-RET %s @@ -428,8 +437,8 @@ // RUN: %clang -target x86_64-unknown-linux-gnu -mno-apxf -mapxf %s -### -o %t.o 2>&1 | FileCheck -check-prefix=APXF %s // RUN: %clang -target x86_64-unknown-linux-gnu -mapxf -mno-apxf %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-APXF %s // -// APXF: "-target-feature" "+egpr" "-target-feature" "+push2pop2" "-target-feature" "+ppx" "-target-feature" "+ndd" "-target-feature" "+ccmp" "-target-feature" "+nf" "-target-feature" "+cf" -// NO-APXF: "-target-feature" "-egpr" "-target-feature" "-push2pop2" "-target-feature" "-ppx" "-target-feature" "-ndd" "-target-feature" "-ccmp" "-target-feature" "-nf" "-target-feature" "-cf" +// APXF: "-target-feature" "+egpr" "-target-feature" "+push2pop2" "-target-feature" "+ppx" "-target-feature" "+ndd" "-target-feature" "+ccmp" "-target-feature" "+nf" "-target-feature" "+cf" "-target-feature" "+zu" +// NO-APXF: "-target-feature" "-egpr" "-target-feature" "-push2pop2" "-target-feature" "-ppx" "-target-feature" "-ndd" "-target-feature" "-ccmp" "-target-feature" "-nf" "-target-feature" "-cf" "-target-feature" "-zu" // RUN: %clang -target x86_64-unknown-linux-gnu -mapx-features=egpr %s -### -o %t.o 2>&1 | FileCheck -check-prefix=EGPR %s // RUN: %clang -target x86_64-unknown-linux-gnu -mapx-features=push2pop2 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=PUSH2POP2 %s diff --git a/clang/test/Frontend/skip-function-bodies.cpp b/clang/test/Frontend/skip-function-bodies.cpp new file mode 100644 index 0000000000000..d0593b474bda2 --- /dev/null +++ b/clang/test/Frontend/skip-function-bodies.cpp @@ -0,0 +1,13 @@ +// Trivial check to ensure skip-function-bodies flag is propagated. +// +// RUN: %clang_cc1 -verify -skip-function-bodies -pedantic-errors %s +// expected-no-diagnostics + +int f() { + // normally this should emit some diags, but we're skipping it! + this is garbage; +} + +// Make sure we only accept it as a cc1 arg. +// RUN: not %clang -skip-function-bodies %s 2>&1 | FileCheck %s +// CHECK: clang: error: unknown argument '-skip-function-bodies'; did you mean '-Xclang -skip-function-bodies'? diff --git a/clang/test/Headers/__clang_hip_cmath.hip b/clang/test/Headers/__clang_hip_cmath.hip index cd085fdb5039a..ed1030b820627 100644 --- a/clang/test/Headers/__clang_hip_cmath.hip +++ b/clang/test/Headers/__clang_hip_cmath.hip @@ -13,7 +13,8 @@ // RUN: -internal-isystem %S/../../lib/Headers/cuda_wrappers \ // RUN: -internal-isystem %S/Inputs/include \ // RUN: -triple amdgcn-amd-amdhsa -aux-triple x86_64-unknown-unknown \ -// RUN: -target-cpu gfx906 -emit-llvm %s -fcuda-is-device -O1 -ffinite-math-only -o - \ +// RUN: -target-cpu gfx906 -emit-llvm %s -fcuda-is-device -O1 -menable-no-infs \ +// RUN: -menable-no-nans -o - \ // RUN: -D__HIPCC_RTC__ | FileCheck -check-prefix=FINITEONLY %s // DEFAULT-LABEL: @test_fma_f16( diff --git a/clang/test/Headers/__clang_hip_math.hip b/clang/test/Headers/__clang_hip_math.hip index 26da82843c512..6ee10976f1207 100644 --- a/clang/test/Headers/__clang_hip_math.hip +++ b/clang/test/Headers/__clang_hip_math.hip @@ -14,7 +14,8 @@ // RUN: -internal-isystem %S/../../lib/Headers/cuda_wrappers \ // RUN: -internal-isystem %S/Inputs/include \ // RUN: -triple amdgcn-amd-amdhsa -aux-triple x86_64-unknown-unknown \ -// RUN: -target-cpu gfx906 -emit-llvm %s -fcuda-is-device -O1 -ffinite-math-only -o - \ +// RUN: -target-cpu gfx906 -emit-llvm %s -fcuda-is-device -O1 -menable-no-infs \ +// RUN: -menable-no-nans -o - \ // RUN: -D__HIPCC_RTC__ | FileCheck -check-prefixes=CHECK,FINITEONLY %s // Check that we end up with -fapprox-func set on intrinsic calls diff --git a/clang/test/Headers/float.c b/clang/test/Headers/float.c index d524d0e53f3fd..a3dd9c90f785c 100644 --- a/clang/test/Headers/float.c +++ b/clang/test/Headers/float.c @@ -2,7 +2,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c99 -ffreestanding %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -ffreestanding %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c23 -ffreestanding %s -// RUN: %clang_cc1 -fsyntax-only -verify=finite -std=c23 -ffreestanding -ffinite-math-only %s +// RUN: %clang_cc1 -fsyntax-only -verify=finite -std=c23 -ffreestanding -menable-no-nans -menable-no-infs %s // RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++11 -ffreestanding %s // RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++14 -ffreestanding %s // RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++17 -ffreestanding %s @@ -223,8 +223,9 @@ #ifndef NAN #error "Mandatory macro NAN is missing." #endif - // FIXME: the NAN diagnostic should only be issued once, not twice. - _Static_assert(_Generic(INFINITY, float : 1, default : 0), ""); // finite-warning {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// FIXME: the NAN and INF diagnostics should only be issued once, not twice. + _Static_assert(_Generic(INFINITY, float : 1, default : 0), ""); // finite-warning {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} \ + finite-warning {{use of infinity is undefined behavior due to the currently enabled floating-point options}} _Static_assert(_Generic(NAN, float : 1, default : 0), ""); // finite-warning {{use of NaN is undefined behavior due to the currently enabled floating-point options}} \ finite-warning {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} diff --git a/clang/test/Headers/stdarg-cxx-modules.cpp b/clang/test/Headers/stdarg-cxx-modules.cpp new file mode 100644 index 0000000000000..113ece4fb64b3 --- /dev/null +++ b/clang/test/Headers/stdarg-cxx-modules.cpp @@ -0,0 +1,25 @@ +// RUN: rm -fR %t +// RUN: split-file %s %t +// RUN: cd %t +// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header h1.h +// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header h2.h -fmodule-file=h1.pcm +// RUN: %clang_cc1 -std=c++20 -fsyntax-only main.cpp -fmodule-file=h1.pcm -fmodule-file=h2.pcm + +//--- h1.h +#include +// expected-no-diagnostics + +//--- h2.h +import "h1.h"; +// expected-no-diagnostics + +//--- main.cpp +import "h1.h"; +import "h2.h"; + +void foo(int x, ...) { + va_list v; + va_start(v, x); + va_end(v); +} +// expected-no-diagnostics diff --git a/clang/test/Headers/stdatomic.c b/clang/test/Headers/stdatomic.c index 3643fd4245b31..9afd531a9ed9b 100644 --- a/clang/test/Headers/stdatomic.c +++ b/clang/test/Headers/stdatomic.c @@ -1,5 +1,8 @@ // RUN: %clang_cc1 -std=c11 -E %s | FileCheck %s // RUN: %clang_cc1 -std=c11 -fms-compatibility -E %s | FileCheck %s +// RUN: %clang_cc1 -std=c11 %s -verify +// RUN: %clang_cc1 -x c++ -std=c++11 %s -verify +// expected-no-diagnostics #include int bool_lock_free = ATOMIC_BOOL_LOCK_FREE; @@ -31,3 +34,5 @@ int llong_lock_free = ATOMIC_LLONG_LOCK_FREE; int pointer_lock_free = ATOMIC_POINTER_LOCK_FREE; // CHECK: pointer_lock_free = {{ *[012] *;}} + +atomic_flag f = ATOMIC_FLAG_INIT; diff --git a/clang/test/Headers/stddefneeds.cpp b/clang/test/Headers/stddefneeds.cpp index 0763bbdee13ae..0282e8afa600d 100644 --- a/clang/test/Headers/stddefneeds.cpp +++ b/clang/test/Headers/stddefneeds.cpp @@ -56,14 +56,21 @@ max_align_t m5; #undef NULL #define NULL 0 -// glibc (and other) headers then define __need_NULL and rely on stddef.h -// to redefine NULL to the correct value again. -#define __need_NULL +// Including stddef.h again shouldn't redefine NULL #include // gtk headers then use __attribute__((sentinel)), which doesn't work if NULL // is 0. -void f(const char* c, ...) __attribute__((sentinel)); +void f(const char* c, ...) __attribute__((sentinel)); // expected-note{{function has been explicitly marked sentinel here}} void g() { + f("", NULL); // expected-warning{{missing sentinel in function call}} +} + +// glibc (and other) headers then define __need_NULL and rely on stddef.h +// to redefine NULL to the correct value again. +#define __need_NULL +#include + +void h() { f("", NULL); // Shouldn't warn. } diff --git a/clang/test/Headers/xmmintrin.c b/clang/test/Headers/xmmintrin.c index a75b3380368c0..15e4a431df65b 100644 --- a/clang/test/Headers/xmmintrin.c +++ b/clang/test/Headers/xmmintrin.c @@ -14,7 +14,7 @@ _MM_ALIGN16 char c; // checking that clang emits PACKSSDW instead of PACKSSWB. // CHECK: define{{.*}} i64 @test_mm_cvtps_pi16 -// CHECK: call x86_mmx @llvm.x86.mmx.packssdw +// CHECK: call <8 x i16> @llvm.x86.sse2.packssdw.128 __m64 test_mm_cvtps_pi16(__m128 a) { return _mm_cvtps_pi16(a); diff --git a/clang/test/Index/pch-with-errors.c b/clang/test/Index/pch-with-errors.c index e8711c8e26a9b..cfe58c155cd6d 100644 --- a/clang/test/Index/pch-with-errors.c +++ b/clang/test/Index/pch-with-errors.c @@ -38,7 +38,7 @@ void foo(void) { // CHECK-INDEX: [indexEntityReference]: kind: function | name: erroneous // RUN: not %clang -fsyntax-only %s -include %t.h 2>&1 | FileCheck -check-prefix=PCH-ERR %s -// PCH-ERR: error: PCH file contains compiler errors +// PCH-ERR: error: PCH file '{{.*}}' contains compiler errors // RUN: not c-index-test -write-pch %t.pch foobar.c 2>&1 | FileCheck -check-prefix=NONEXISTENT %s // NONEXISTENT: Unable to load translation unit diff --git a/clang/test/InstallAPI/diagnostics-dsym.test b/clang/test/InstallAPI/diagnostics-dsym.test index 42fa67a1f9b1e..b8433653c3f76 100644 --- a/clang/test/InstallAPI/diagnostics-dsym.test +++ b/clang/test/InstallAPI/diagnostics-dsym.test @@ -19,8 +19,8 @@ ; RUN: --verify-mode=Pedantic 2>&1 | FileCheck %s ; CHECK: violations found for arm64 -; CHECK: foo.c:5:0: error: no declaration found for exported symbol 'bar' in dynamic library -; CHECK: foo.c:1:0: error: no declaration found for exported symbol 'foo' in dynamic library +; CHECK-DAG: foo.c:5:0: error: no declaration found for exported symbol 'bar' in dynamic library +; CHECK-DAG: foo.c:1:0: error: no declaration found for exported symbol 'foo' in dynamic library ;--- foo.c int foo(void) { diff --git a/clang/test/InstallAPI/directory-scanning-subdirectories.test b/clang/test/InstallAPI/directory-scanning-subdirectories.test new file mode 100644 index 0000000000000..3eac90440fa1e --- /dev/null +++ b/clang/test/InstallAPI/directory-scanning-subdirectories.test @@ -0,0 +1,61 @@ +; RUN: rm -rf %t +; RUN: split-file %s %t +; RUN: mkdir -p %t/DstRoot/ +; RUN: cp -r %S/Inputs/LibFoo/* %t/DstRoot/ + +; RUN: clang-installapi \ +; RUN: -target arm64-apple-macos12 -install_name @rpath/libfoo.dylib \ +; RUN: -current_version 1 -compatibility_version 1 \ +; RUN: -I%t/DstRoot/usr/include -dynamiclib \ +; RUN: -exclude-public-header %t/DstRoot/usr/include/public.h \ +; RUN: %t/DstRoot -o %t/output.tbd 2>&1 | FileCheck %s --allow-empty \ +; RUN: --implicit-check-not=error --implicit-check-not=warning +; RUN: llvm-readtapi --compare %t/output.tbd %t/expected.tbd + + +;--- DstRoot/usr/include/extra/extra.h +int extra(void); + +;--- DstRoot/usr/include/extra/additional/additional.h +int additional(void); + +;--- DstRoot/usr/include/more/more.h +int more(void); + +;--- DstRoot/usr/include/another/another.h +int another(void); + +;--- expected.tbd +{ + "main_library": { + "exported_symbols": [ + { + "text": { + "global": [ + "_foo", "_additional", "_more", + "_another", "_extra" + ] + } + } + ], + "flags": [ + { + "attributes": [ + "not_app_extension_safe" + ] + } + ], + "install_names": [ + { + "name": "@rpath/libfoo.dylib" + } + ], + "target_info": [ + { + "min_deployment": "12", + "target": "arm64-macos" + } + ] + }, + "tapi_tbd_version": 5 +} diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index 7809c826755f8..d191067b93d78 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -83,6 +83,7 @@ // CHECK-NEXT: HIPManaged (SubjectMatchRule_variable) // CHECK-NEXT: HLSLResourceClass (SubjectMatchRule_record_not_is_union) // CHECK-NEXT: Hot (SubjectMatchRule_function) +// CHECK-NEXT: HybridPatchable (SubjectMatchRule_function) // CHECK-NEXT: IBAction (SubjectMatchRule_objc_method_is_instance) // CHECK-NEXT: IFunc (SubjectMatchRule_function) // CHECK-NEXT: InitPriority (SubjectMatchRule_variable) @@ -110,6 +111,7 @@ // CHECK-NEXT: Naked (SubjectMatchRule_function) // CHECK-NEXT: NoBuiltin (SubjectMatchRule_function) // CHECK-NEXT: NoCommon (SubjectMatchRule_variable) +// CHECK-NEXT: NoConvergent (SubjectMatchRule_function) // CHECK-NEXT: NoDebug (SubjectMatchRule_type_alias, SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter) // CHECK-NEXT: NoDestroy (SubjectMatchRule_variable) // CHECK-NEXT: NoDuplicate (SubjectMatchRule_function) diff --git a/clang/test/Misc/target-invalid-cpu-note.c b/clang/test/Misc/target-invalid-cpu-note.c index a5f9ffa21220a..e0757b69242a8 100644 --- a/clang/test/Misc/target-invalid-cpu-note.c +++ b/clang/test/Misc/target-invalid-cpu-note.c @@ -57,7 +57,7 @@ // RUN: not %clang_cc1 -triple powerpc--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix PPC // PPC: error: unknown target CPU 'not-a-cpu' -// PPC-NEXT: note: valid target CPU values are: generic, 440, 450, 601, 602, 603, 603e, 603ev, 604, 604e, 620, 630, g3, 7400, g4, 7450, g4+, 750, 8548, 970, g5, a2, e500, e500mc, e5500, power3, pwr3, power4, pwr4, power5, pwr5, power5x, pwr5x, power6, pwr6, power6x, pwr6x, power7, pwr7, power8, pwr8, power9, pwr9, power10, pwr10, powerpc, ppc, ppc32, powerpc64, ppc64, powerpc64le, ppc64le, future{{$}} +// PPC-NEXT: note: valid target CPU values are: generic, 440, 440fp, ppc440, 450, 601, 602, 603, 603e, 603ev, 604, 604e, 620, 630, g3, 7400, g4, 7450, g4+, 750, 8548, ppc405, ppc464, ppc476, 970, ppc970, g5, a2, ppca2, ppc-cell-be, e500, e500mc, e5500, power3, pwr3, pwr4, power4, pwr5, power5, pwr5+, power5+, pwr5x, power5x, pwr6, power6, pwr6x, power6x, pwr7, power7, pwr8, power8, pwr9, power9, pwr10, power10, pwr11, power11, powerpc, ppc, ppc32, powerpc64, ppc64, powerpc64le, ppc64le, future{{$}} // RUN: not %clang_cc1 -triple mips--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix MIPS // MIPS: error: unknown target CPU 'not-a-cpu' diff --git a/clang/test/Modules/inline-builtins.cppm b/clang/test/Modules/inline-builtins.cppm new file mode 100644 index 0000000000000..8a0fffbfc25bc --- /dev/null +++ b/clang/test/Modules/inline-builtins.cppm @@ -0,0 +1,36 @@ +// REQUIRES: !system-windows +// +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: cd %t +// +// RUN: %clang_cc1 -std=c++20 -O3 %t/a.cppm -emit-module-interface -o %t/a.pcm +// RUN: %clang_cc1 -std=c++20 -O3 %t/test.cc -fmodule-file=a=%t/a.pcm \ +// RUN: -emit-llvm -o - | FileCheck %t/test.cc + +//--- memmove.h +typedef long unsigned int size_t; +extern "C" void *memmove (void *__dest, const void *__src, size_t __n) + throw () __attribute__ ((__nonnull__ (1, 2))); +extern "C" __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) void * + memmove (void *__dest, const void *__src, size_t __len) throw () +{ + return __builtin_memmove(__dest, __src, __len); +} + +//--- a.cppm +module; +#include "memmove.h" +export module a; +export using ::memmove; + +//--- test.cc +import a; + +void test() { + int a, b; + unsigned c = 0; + memmove(&a, &b, c); +} + +// CHECK-NOT: memmove diff --git a/clang/test/Modules/load-module-with-errors.m b/clang/test/Modules/load-module-with-errors.m index 1f8e483a19e92..6e10cb3381be8 100644 --- a/clang/test/Modules/load-module-with-errors.m +++ b/clang/test/Modules/load-module-with-errors.m @@ -1,7 +1,7 @@ // Note: the run lines follow their respective tests, since line/column // matter in this test. -// pcherror-error@* {{PCH file contains compiler errors}} +// pcherror-error-re@* {{module file '{{.*}}use_error_a.pcm' contains compiler errors}} @import use_error_a; // notallowerror-error {{could not build module 'use_error_a'}} @import use_error_b; // expected-no-diagnostics @@ -61,7 +61,7 @@ void test(Error *x) { // RUN: -fmodule-file=%t/prebuilt/use_error_a.pcm \ // RUN: -fmodule-file=%t/prebuilt/use_error_b.pcm \ // RUN: -fmodules-cache-path=%t 2>&1 | \ -// RUN: grep "PCH file contains compiler errors" +// RUN: grep "module file .* contains compiler errors" // Shouldn't build the cached modules (that have errors) when not allowing // errors diff --git a/clang/test/Modules/modulemap-allow-subdirectory-search.m b/clang/test/Modules/modulemap-allow-subdirectory-search.m new file mode 100644 index 0000000000000..ef6f9b1009bab --- /dev/null +++ b/clang/test/Modules/modulemap-allow-subdirectory-search.m @@ -0,0 +1,18 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t + +// RUN: %clang_cc1 -fsyntax-only -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache -I %t/include %t/test.m +// RUN: %clang_cc1 -fsyntax-only -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache -I %t/include %t/test.m -fmodulemap-allow-subdirectory-search +// RUN: not %clang_cc1 -fsyntax-only -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache -I %t/include %t/test.m -fno-modulemap-allow-subdirectory-search + +//--- include/UnrelatedName/Header.h +// empty + +//--- include/UnrelatedName/module.modulemap +module UsefulCode { + header "Header.h" + export * +} + +//--- test.m +@import UsefulCode; diff --git a/clang/test/Modules/pch-in-module-units.cppm b/clang/test/Modules/pch-in-module-units.cppm new file mode 100644 index 0000000000000..790a3af09a0ca --- /dev/null +++ b/clang/test/Modules/pch-in-module-units.cppm @@ -0,0 +1,51 @@ +// Test that we will skip ODR checks for declarations from PCH if they +// were from GMF. +// +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface %t/A.cppm \ +// RUN: -o %t/A.pcm -fskip-odr-check-in-gmf +// RUN: %clang_cc1 -std=c++20 -DDIFF -x c++-header %t/foo.h \ +// RUN: -emit-pch -o %t/foo.pch -fskip-odr-check-in-gmf +// RUN: %clang_cc1 -std=c++20 %t/B.cppm -fmodule-file=A=%t/A.pcm -include-pch \ +// RUN: %t/foo.pch -verify -fsyntax-only -fskip-odr-check-in-gmf + +//--- foo.h +#ifndef FOO_H +#define FOO_H +inline int foo() { +#ifndef DIFF + return 43; +#else + return 45; +#endif +} + +class f { +public: + int mem() { +#ifndef DIFF + return 47; +#else + return 45; +#endif + } +}; +#endif + +//--- A.cppm +module; +#include "foo.h" +export module A; +export using ::foo; +export using ::f; + +//--- B.cppm +// expected-no-diagnostics +module; +#include "foo.h" +export module B; +import A; +export int b = foo() + f().mem(); diff --git a/clang/test/Modules/stddef.cpp b/clang/test/Modules/stddef.cpp new file mode 100644 index 0000000000000..c53bfa3485194 --- /dev/null +++ b/clang/test/Modules/stddef.cpp @@ -0,0 +1,73 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/no-lsv -I%t %t/stddef.cpp -verify +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-local-submodule-visibility -fmodules-cache-path=%t/lsv -I%t %t/stddef.cpp -verify + +//--- stddef.cpp +#include + +void *pointer = NULL; +size_t size = 0; + +// When building with modules, a pcm is never re-imported, so re-including +// stddef.h will not re-import _Builtin_stddef.null to restore the definition of +// NULL, even though stddef.h will unconditionally include __stddef_null.h when +// building with modules. +#undef NULL +#include + +void *anotherPointer = NULL; // expected-error{{use of undeclared identifier 'NULL'}} + +// stddef.h needs to be a `textual` header to support clients doing things like +// this. +// +// #define __need_NULL +// #include +// +// As a textual header designed to be included multiple times, it can't directly +// declare anything, or those declarations would go into every module that +// included it. e.g. if stddef.h contained all of its declarations, and modules +// A and B included stddef.h, they would both have the declaration for size_t. +// That breaks Swift, which uses the module name as part of the type name, i.e. +// A.size_t and B.size_t are treated as completely different types in Swift and +// cannot be interchanged. To fix that, stddef.h (and stdarg.h) are split out +// into a separate file per __need macro that can be normal headers in explicit +// submodules. That runs into yet another wrinkle though. When modules build, +// declarations from previous submodules leak into subsequent ones when not +// using local submodule visibility. Consider if stddef.h did the normal thing. +// +// #ifndef __STDDEF_H +// #define __STDDEF_H +// // include all of the sub-headers +// #endif +// +// When SM builds without local submodule visibility, it will precompile a.h +// first. When it gets to b.h, the __STDDEF_H declaration from precompiling a.h +// will leak, and so when b.h includes stddef.h, it won't include any of its +// sub-headers, and SM.B will thus not import _Builtin_stddef or make any of its +// submodules visible. Precompiling b.h will be fine since it sees all of the +// declarations from a.h including stddef.h, but clients that only include b.h +// will not see any of the stddef.h types. stddef.h thus has to make sure to +// always include the necessary sub-headers, even if they've been included +// already. They all have their own header guards to allow this. +// __stddef_null.h is extra special, so this test makes sure to cover NULL plus +// one of the normal stddef.h types. + +//--- module.modulemap +module SM { + module A { + header "a.h" + export * + } + + module B { + header "b.h" + export * + } +} + +//--- a.h +#include + +//--- b.h +#include diff --git a/clang/test/Modules/subdirectory-module-maps-working-dir.m b/clang/test/Modules/subdirectory-module-maps-working-dir.m index 4fb19ff05ef38..43488e8d13601 100644 --- a/clang/test/Modules/subdirectory-module-maps-working-dir.m +++ b/clang/test/Modules/subdirectory-module-maps-working-dir.m @@ -1,8 +1,8 @@ // RUN: rm -rf %t -// RUN: %clang -fsyntax-only -fmodules -fmodules-cache-path=%t \ +// RUN: %clang_cc1 -fsyntax-only -fmodules -fimplicit-module-maps -fmodules-cache-path=%t \ // RUN: -working-directory %S/Inputs \ // RUN: -I subdirectory-module-maps-working-dir \ -// RUN: %s -Werror=implicit-function-declaration -Xclang -verify +// RUN: %s -Werror=implicit-function-declaration -verify @import ModuleInSubdir; diff --git a/clang/test/OpenMP/amdgpu-unsafe-fp-atomics.cpp b/clang/test/OpenMP/amdgpu-unsafe-fp-atomics.cpp new file mode 100644 index 0000000000000..7a34113cec8fa --- /dev/null +++ b/clang/test/OpenMP/amdgpu-unsafe-fp-atomics.cpp @@ -0,0 +1,59 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple amdgcn-amd-amdhsa -fopenmp-targets=amdgcn-amd-amdhsa -emit-llvm %s -fopenmp-is-target-device -o - | FileCheck -check-prefix=DEFAULT %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple amdgcn-amd-amdhsa -fopenmp-targets=amdgcn-amd-amdhsa -munsafe-fp-atomics -emit-llvm %s -fopenmp-is-target-device -o - | FileCheck -check-prefix=UNSAFE-FP-ATOMICS %s + +#pragma omp declare target + +float fv, fx; +double dv, dx; + +// DEFAULT-LABEL: define hidden void @_Z15atomic_fadd_f32v( +// DEFAULT-SAME: ) #[[ATTR0:[0-9]+]] { +// DEFAULT-NEXT: [[ENTRY:.*:]] +// DEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr addrspacecast (ptr addrspace(1) @fv to ptr), align 4 +// DEFAULT-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @fx to ptr), float [[TMP0]] monotonic, align 4 +// DEFAULT-NEXT: [[ADD:%.*]] = fadd float [[TMP1]], [[TMP0]] +// DEFAULT-NEXT: store float [[ADD]], ptr addrspacecast (ptr addrspace(1) @fv to ptr), align 4 +// DEFAULT-NEXT: ret void +// +// UNSAFE-FP-ATOMICS-LABEL: define hidden void @_Z15atomic_fadd_f32v( +// UNSAFE-FP-ATOMICS-SAME: ) #[[ATTR0:[0-9]+]] { +// UNSAFE-FP-ATOMICS-NEXT: [[ENTRY:.*:]] +// UNSAFE-FP-ATOMICS-NEXT: [[TMP0:%.*]] = load float, ptr addrspacecast (ptr addrspace(1) @fv to ptr), align 4 +// UNSAFE-FP-ATOMICS-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @fx to ptr), float [[TMP0]] monotonic, align 4, !amdgpu.no.fine.grained.memory [[META5:![0-9]+]], !amdgpu.ignore.denormal.mode [[META5]] +// UNSAFE-FP-ATOMICS-NEXT: [[ADD:%.*]] = fadd float [[TMP1]], [[TMP0]] +// UNSAFE-FP-ATOMICS-NEXT: store float [[ADD]], ptr addrspacecast (ptr addrspace(1) @fv to ptr), align 4 +// UNSAFE-FP-ATOMICS-NEXT: ret void +// +void atomic_fadd_f32() { +#pragma omp atomic capture + fv = fx = fx + fv; +} + +// DEFAULT-LABEL: define hidden void @_Z15atomic_fadd_f64v( +// DEFAULT-SAME: ) #[[ATTR0]] { +// DEFAULT-NEXT: [[ENTRY:.*:]] +// DEFAULT-NEXT: [[TMP0:%.*]] = load double, ptr addrspacecast (ptr addrspace(1) @dv to ptr), align 8 +// DEFAULT-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @dx to ptr), double [[TMP0]] monotonic, align 8 +// DEFAULT-NEXT: [[ADD:%.*]] = fadd double [[TMP1]], [[TMP0]] +// DEFAULT-NEXT: store double [[ADD]], ptr addrspacecast (ptr addrspace(1) @dv to ptr), align 8 +// DEFAULT-NEXT: ret void +// +// UNSAFE-FP-ATOMICS-LABEL: define hidden void @_Z15atomic_fadd_f64v( +// UNSAFE-FP-ATOMICS-SAME: ) #[[ATTR0]] { +// UNSAFE-FP-ATOMICS-NEXT: [[ENTRY:.*:]] +// UNSAFE-FP-ATOMICS-NEXT: [[TMP0:%.*]] = load double, ptr addrspacecast (ptr addrspace(1) @dv to ptr), align 8 +// UNSAFE-FP-ATOMICS-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @dx to ptr), double [[TMP0]] monotonic, align 8, !amdgpu.no.fine.grained.memory [[META5]] +// UNSAFE-FP-ATOMICS-NEXT: [[ADD:%.*]] = fadd double [[TMP1]], [[TMP0]] +// UNSAFE-FP-ATOMICS-NEXT: store double [[ADD]], ptr addrspacecast (ptr addrspace(1) @dv to ptr), align 8 +// UNSAFE-FP-ATOMICS-NEXT: ret void +// +void atomic_fadd_f64() { +#pragma omp atomic capture + dv = dx = dx + dv; +} + +#pragma omp end declare target +//. +// UNSAFE-FP-ATOMICS: [[META5]] = !{} +//. diff --git a/clang/test/OpenMP/generic_loop_ast_print.cpp b/clang/test/OpenMP/generic_loop_ast_print.cpp index b61ee79615d04..b361724c12a0d 100644 --- a/clang/test/OpenMP/generic_loop_ast_print.cpp +++ b/clang/test/OpenMP/generic_loop_ast_print.cpp @@ -23,7 +23,7 @@ //PRINT: template void templ_foo(T t) { //PRINT: T j, z; -//PRINT: #pragma omp simd collapse(C) reduction(+: z) lastprivate(j) +//PRINT: #pragma omp loop collapse(C) reduction(+: z) lastprivate(j) bind(thread) //PRINT: for (T i = 0; i < t; ++i) //PRINT: for (j = 0; j < t; ++j) //PRINT: z += i + j; @@ -31,19 +31,20 @@ //DUMP: FunctionTemplateDecl{{.*}}templ_foo //DUMP: TemplateTypeParmDecl{{.*}}T //DUMP: NonTypeTemplateParmDecl{{.*}}C -//DUMP: OMPSimdDirective +//DUMP: OMPGenericLoopDirective //DUMP: OMPCollapseClause //DUMP: DeclRefExpr{{.*}}'C' 'int' //DUMP: OMPReductionClause //DUMP: DeclRefExpr{{.*}}'z' 'T' //DUMP: OMPLastprivateClause //DUMP: DeclRefExpr{{.*}}'j' 'T' +//DUMP: OMPBindClause //DUMP: ForStmt //DUMP: ForStmt //PRINT: template<> void templ_foo(int t) { //PRINT: int j, z; -//PRINT: #pragma omp simd collapse(2) reduction(+: z) lastprivate(j) +//PRINT: #pragma omp loop collapse(2) reduction(+: z) lastprivate(j) bind(thread) //PRINT: for (int i = 0; i < t; ++i) //PRINT: for (j = 0; j < t; ++j) //PRINT: z += i + j; @@ -52,7 +53,7 @@ //DUMP: TemplateArgument type 'int' //DUMP: TemplateArgument integral '2' //DUMP: ParmVarDecl{{.*}}'int' -//DUMP: OMPSimdDirective +//DUMP: OMPGenericLoopDirective //DUMP: OMPCollapseClause //DUMP: ConstantExpr{{.*}}'int' //DUMP: value: Int 2 @@ -60,6 +61,7 @@ //DUMP: DeclRefExpr{{.*}}'z' 'int' //DUMP: OMPLastprivateClause //DUMP: DeclRefExpr{{.*}}'j' 'int' +//DUMP: OMPBindClause //DUMP: ForStmt template void templ_foo(T t) { @@ -80,12 +82,12 @@ void test() { int aaa[1000]; //PRINT: #pragma omp target teams distribute parallel for map(tofrom: MTX) - //PRINT: #pragma omp simd + //PRINT: #pragma omp loop //DUMP: OMPTargetTeamsDistributeParallelForDirective //DUMP: CapturedStmt //DUMP: ForStmt //DUMP: CompoundStmt - //DUMP: OMPSimdDirective + //DUMP: OMPGenericLoopDirective #pragma omp target teams distribute parallel for map(MTX) for (auto i = 0; i < N; ++i) { #pragma omp loop @@ -95,11 +97,11 @@ void test() { } //PRINT: #pragma omp target teams - //PRINT: #pragma omp distribute + //PRINT: #pragma omp loop //DUMP: OMPTargetTeamsDirective //DUMP: CapturedStmt //DUMP: ForStmt - //DUMP: OMPDistributeDirective + //DUMP: OMPGenericLoopDirective #pragma omp target teams for (int i=0; i<1000; ++i) { #pragma omp loop @@ -109,8 +111,8 @@ void test() { } int j, z, z1; - //PRINT: #pragma omp for collapse(2) private(z) lastprivate(j) order(concurrent) reduction(+: z1) - //DUMP: OMPForDirective + //PRINT: #pragma omp loop collapse(2) private(z) lastprivate(j) order(concurrent) reduction(+: z1) bind(parallel) + //DUMP: OMPGenericLoopDirective //DUMP: OMPCollapseClause //DUMP: IntegerLiteral{{.*}}2 //DUMP: OMPPrivateClause @@ -120,6 +122,7 @@ void test() { //DUMP: OMPOrderClause //DUMP: OMPReductionClause //DUMP-NEXT: DeclRefExpr{{.*}}'z1' + //DUMP: OMPBindClause //DUMP: ForStmt //DUMP: ForStmt #pragma omp loop collapse(2) private(z) lastprivate(j) order(concurrent) \ @@ -133,9 +136,10 @@ void test() { } //PRINT: #pragma omp target teams - //PRINT: #pragma omp distribute + //PRINT: #pragma omp loop bind(teams) //DUMP: OMPTargetTeamsDirective - //DUMP: OMPDistributeDirective + //DUMP: OMPGenericLoopDirective + //DUMP: OMPBindClause //DUMP: ForStmt #pragma omp target teams #pragma omp loop bind(teams) @@ -143,10 +147,11 @@ void test() { //PRINT: #pragma omp target //PRINT: #pragma omp teams - //PRINT: #pragma omp distribute + //PRINT: #pragma omp loop bind(teams) //DUMP: OMPTargetDirective //DUMP: OMPTeamsDirective - //DUMP: OMPDistributeDirective + //DUMP: OMPGenericLoopDirective + //DUMP: OMPBindClause //DUMP: ForStmt #pragma omp target #pragma omp teams diff --git a/clang/test/OpenMP/generic_loop_codegen.cpp b/clang/test/OpenMP/generic_loop_codegen.cpp index c3ad43bebccaf..d062695fee281 100644 --- a/clang/test/OpenMP/generic_loop_codegen.cpp +++ b/clang/test/OpenMP/generic_loop_codegen.cpp @@ -32,6 +32,8 @@ void foo(int t) { // IR-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4 // IR-NEXT: [[DOTCAPTURE_EXPR_2:%.*]] = alloca i32, align 4 // IR-NEXT: [[DOTCAPTURE_EXPR_3:%.*]] = alloca i64, align 8 +// IR-NEXT: [[DOTOMP_LB:%.*]] = alloca i64, align 8 +// IR-NEXT: [[DOTOMP_UB:%.*]] = alloca i64, align 8 // IR-NEXT: [[I8:%.*]] = alloca i32, align 4 // IR-NEXT: [[J9:%.*]] = alloca i32, align 4 // IR-NEXT: [[DOTOMP_IV:%.*]] = alloca i64, align 8 @@ -54,86 +56,89 @@ void foo(int t) { // IR-NEXT: [[MUL:%.*]] = mul nsw i64 [[CONV]], [[CONV6]] // IR-NEXT: [[SUB7:%.*]] = sub nsw i64 [[MUL]], 1 // IR-NEXT: store i64 [[SUB7]], ptr [[DOTCAPTURE_EXPR_3]], align 8 +// IR-NEXT: store i64 0, ptr [[DOTOMP_LB]], align 8 +// IR-NEXT: [[TMP4:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 +// IR-NEXT: store i64 [[TMP4]], ptr [[DOTOMP_UB]], align 8 // IR-NEXT: store i32 0, ptr [[I8]], align 4 // IR-NEXT: store i32 0, ptr [[J9]], align 4 -// IR-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 -// IR-NEXT: [[CMP:%.*]] = icmp slt i32 0, [[TMP4]] +// IR-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// IR-NEXT: [[CMP:%.*]] = icmp slt i32 0, [[TMP5]] // IR-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[SIMD_IF_END:%.*]] // IR: land.lhs.true: -// IR-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 -// IR-NEXT: [[CMP10:%.*]] = icmp slt i32 0, [[TMP5]] +// IR-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// IR-NEXT: [[CMP10:%.*]] = icmp slt i32 0, [[TMP6]] // IR-NEXT: br i1 [[CMP10]], label [[SIMD_IF_THEN:%.*]], label [[SIMD_IF_END]] // IR: simd.if.then: -// IR-NEXT: store i64 0, ptr [[DOTOMP_IV]], align 8 +// IR-NEXT: [[TMP7:%.*]] = load i64, ptr [[DOTOMP_LB]], align 8 +// IR-NEXT: store i64 [[TMP7]], ptr [[DOTOMP_IV]], align 8 // IR-NEXT: store i32 0, ptr [[Z13]], align 4 // IR-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // IR: omp.inner.for.cond: -// IR-NEXT: [[TMP6:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3:![0-9]+]] -// IR-NEXT: [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8, !llvm.access.group [[ACC_GRP3]] -// IR-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP7]], 1 -// IR-NEXT: [[CMP14:%.*]] = icmp slt i64 [[TMP6]], [[ADD]] +// IR-NEXT: [[TMP8:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3:![0-9]+]] +// IR-NEXT: [[TMP9:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8, !llvm.access.group [[ACC_GRP3]] +// IR-NEXT: [[CMP14:%.*]] = icmp sle i64 [[TMP8]], [[TMP9]] // IR-NEXT: br i1 [[CMP14]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // IR: omp.inner.for.body: -// IR-NEXT: [[TMP8:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] -// IR-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !llvm.access.group [[ACC_GRP3]] -// IR-NEXT: [[SUB15:%.*]] = sub nsw i32 [[TMP9]], 0 +// IR-NEXT: [[TMP10:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] +// IR-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !llvm.access.group [[ACC_GRP3]] +// IR-NEXT: [[SUB15:%.*]] = sub nsw i32 [[TMP11]], 0 // IR-NEXT: [[DIV16:%.*]] = sdiv i32 [[SUB15]], 1 // IR-NEXT: [[MUL17:%.*]] = mul nsw i32 1, [[DIV16]] // IR-NEXT: [[CONV18:%.*]] = sext i32 [[MUL17]] to i64 -// IR-NEXT: [[DIV19:%.*]] = sdiv i64 [[TMP8]], [[CONV18]] +// IR-NEXT: [[DIV19:%.*]] = sdiv i64 [[TMP10]], [[CONV18]] // IR-NEXT: [[MUL20:%.*]] = mul nsw i64 [[DIV19]], 1 // IR-NEXT: [[ADD21:%.*]] = add nsw i64 0, [[MUL20]] // IR-NEXT: [[CONV22:%.*]] = trunc i64 [[ADD21]] to i32 // IR-NEXT: store i32 [[CONV22]], ptr [[I11]], align 4, !llvm.access.group [[ACC_GRP3]] -// IR-NEXT: [[TMP10:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] -// IR-NEXT: [[TMP11:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] -// IR-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !llvm.access.group [[ACC_GRP3]] -// IR-NEXT: [[SUB23:%.*]] = sub nsw i32 [[TMP12]], 0 +// IR-NEXT: [[TMP12:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] +// IR-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] +// IR-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !llvm.access.group [[ACC_GRP3]] +// IR-NEXT: [[SUB23:%.*]] = sub nsw i32 [[TMP14]], 0 // IR-NEXT: [[DIV24:%.*]] = sdiv i32 [[SUB23]], 1 // IR-NEXT: [[MUL25:%.*]] = mul nsw i32 1, [[DIV24]] // IR-NEXT: [[CONV26:%.*]] = sext i32 [[MUL25]] to i64 -// IR-NEXT: [[DIV27:%.*]] = sdiv i64 [[TMP11]], [[CONV26]] -// IR-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !llvm.access.group [[ACC_GRP3]] -// IR-NEXT: [[SUB28:%.*]] = sub nsw i32 [[TMP13]], 0 +// IR-NEXT: [[DIV27:%.*]] = sdiv i64 [[TMP13]], [[CONV26]] +// IR-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !llvm.access.group [[ACC_GRP3]] +// IR-NEXT: [[SUB28:%.*]] = sub nsw i32 [[TMP15]], 0 // IR-NEXT: [[DIV29:%.*]] = sdiv i32 [[SUB28]], 1 // IR-NEXT: [[MUL30:%.*]] = mul nsw i32 1, [[DIV29]] // IR-NEXT: [[CONV31:%.*]] = sext i32 [[MUL30]] to i64 // IR-NEXT: [[MUL32:%.*]] = mul nsw i64 [[DIV27]], [[CONV31]] -// IR-NEXT: [[SUB33:%.*]] = sub nsw i64 [[TMP10]], [[MUL32]] +// IR-NEXT: [[SUB33:%.*]] = sub nsw i64 [[TMP12]], [[MUL32]] // IR-NEXT: [[MUL34:%.*]] = mul nsw i64 [[SUB33]], 1 // IR-NEXT: [[ADD35:%.*]] = add nsw i64 0, [[MUL34]] // IR-NEXT: [[CONV36:%.*]] = trunc i64 [[ADD35]] to i32 // IR-NEXT: store i32 [[CONV36]], ptr [[J12]], align 4, !llvm.access.group [[ACC_GRP3]] -// IR-NEXT: [[TMP14:%.*]] = load i32, ptr [[I11]], align 4, !llvm.access.group [[ACC_GRP3]] -// IR-NEXT: [[TMP15:%.*]] = load i32, ptr [[J12]], align 4, !llvm.access.group [[ACC_GRP3]] -// IR-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP14]], [[TMP15]] -// IR-NEXT: [[TMP16:%.*]] = load i32, ptr [[Z13]], align 4, !llvm.access.group [[ACC_GRP3]] -// IR-NEXT: [[ADD38:%.*]] = add nsw i32 [[TMP16]], [[ADD37]] +// IR-NEXT: [[TMP16:%.*]] = load i32, ptr [[I11]], align 4, !llvm.access.group [[ACC_GRP3]] +// IR-NEXT: [[TMP17:%.*]] = load i32, ptr [[J12]], align 4, !llvm.access.group [[ACC_GRP3]] +// IR-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// IR-NEXT: [[TMP18:%.*]] = load i32, ptr [[Z13]], align 4, !llvm.access.group [[ACC_GRP3]] +// IR-NEXT: [[ADD38:%.*]] = add nsw i32 [[TMP18]], [[ADD37]] // IR-NEXT: store i32 [[ADD38]], ptr [[Z13]], align 4, !llvm.access.group [[ACC_GRP3]] // IR-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // IR: omp.body.continue: // IR-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // IR: omp.inner.for.inc: -// IR-NEXT: [[TMP17:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] -// IR-NEXT: [[ADD39:%.*]] = add nsw i64 [[TMP17]], 1 +// IR-NEXT: [[TMP19:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] +// IR-NEXT: [[ADD39:%.*]] = add nsw i64 [[TMP19]], 1 // IR-NEXT: store i64 [[ADD39]], ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] // IR-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]] // IR: omp.inner.for.end: -// IR-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 -// IR-NEXT: [[SUB40:%.*]] = sub nsw i32 [[TMP18]], 0 +// IR-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// IR-NEXT: [[SUB40:%.*]] = sub nsw i32 [[TMP20]], 0 // IR-NEXT: [[DIV41:%.*]] = sdiv i32 [[SUB40]], 1 // IR-NEXT: [[MUL42:%.*]] = mul nsw i32 [[DIV41]], 1 // IR-NEXT: [[ADD43:%.*]] = add nsw i32 0, [[MUL42]] // IR-NEXT: store i32 [[ADD43]], ptr [[I11]], align 4 -// IR-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 -// IR-NEXT: [[SUB44:%.*]] = sub nsw i32 [[TMP19]], 0 +// IR-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// IR-NEXT: [[SUB44:%.*]] = sub nsw i32 [[TMP21]], 0 // IR-NEXT: [[DIV45:%.*]] = sdiv i32 [[SUB44]], 1 // IR-NEXT: [[MUL46:%.*]] = mul nsw i32 [[DIV45]], 1 // IR-NEXT: [[ADD47:%.*]] = add nsw i32 0, [[MUL46]] // IR-NEXT: store i32 [[ADD47]], ptr [[J]], align 4 -// IR-NEXT: [[TMP20:%.*]] = load i32, ptr [[Z]], align 4 -// IR-NEXT: [[TMP21:%.*]] = load i32, ptr [[Z13]], align 4 -// IR-NEXT: [[ADD48:%.*]] = add nsw i32 [[TMP20]], [[TMP21]] +// IR-NEXT: [[TMP22:%.*]] = load i32, ptr [[Z]], align 4 +// IR-NEXT: [[TMP23:%.*]] = load i32, ptr [[Z13]], align 4 +// IR-NEXT: [[ADD48:%.*]] = add nsw i32 [[TMP22]], [[TMP23]] // IR-NEXT: store i32 [[ADD48]], ptr [[Z]], align 4 // IR-NEXT: br label [[SIMD_IF_END]] // IR: simd.if.end: @@ -152,6 +157,8 @@ void foo(int t) { // IR-PCH-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4 // IR-PCH-NEXT: [[DOTCAPTURE_EXPR_2:%.*]] = alloca i32, align 4 // IR-PCH-NEXT: [[DOTCAPTURE_EXPR_3:%.*]] = alloca i64, align 8 +// IR-PCH-NEXT: [[DOTOMP_LB:%.*]] = alloca i64, align 8 +// IR-PCH-NEXT: [[DOTOMP_UB:%.*]] = alloca i64, align 8 // IR-PCH-NEXT: [[I8:%.*]] = alloca i32, align 4 // IR-PCH-NEXT: [[J9:%.*]] = alloca i32, align 4 // IR-PCH-NEXT: [[DOTOMP_IV:%.*]] = alloca i64, align 8 @@ -174,86 +181,89 @@ void foo(int t) { // IR-PCH-NEXT: [[MUL:%.*]] = mul nsw i64 [[CONV]], [[CONV6]] // IR-PCH-NEXT: [[SUB7:%.*]] = sub nsw i64 [[MUL]], 1 // IR-PCH-NEXT: store i64 [[SUB7]], ptr [[DOTCAPTURE_EXPR_3]], align 8 +// IR-PCH-NEXT: store i64 0, ptr [[DOTOMP_LB]], align 8 +// IR-PCH-NEXT: [[TMP4:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 +// IR-PCH-NEXT: store i64 [[TMP4]], ptr [[DOTOMP_UB]], align 8 // IR-PCH-NEXT: store i32 0, ptr [[I8]], align 4 // IR-PCH-NEXT: store i32 0, ptr [[J9]], align 4 -// IR-PCH-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 -// IR-PCH-NEXT: [[CMP:%.*]] = icmp slt i32 0, [[TMP4]] +// IR-PCH-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// IR-PCH-NEXT: [[CMP:%.*]] = icmp slt i32 0, [[TMP5]] // IR-PCH-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[SIMD_IF_END:%.*]] // IR-PCH: land.lhs.true: -// IR-PCH-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 -// IR-PCH-NEXT: [[CMP10:%.*]] = icmp slt i32 0, [[TMP5]] +// IR-PCH-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// IR-PCH-NEXT: [[CMP10:%.*]] = icmp slt i32 0, [[TMP6]] // IR-PCH-NEXT: br i1 [[CMP10]], label [[SIMD_IF_THEN:%.*]], label [[SIMD_IF_END]] // IR-PCH: simd.if.then: -// IR-PCH-NEXT: store i64 0, ptr [[DOTOMP_IV]], align 8 +// IR-PCH-NEXT: [[TMP7:%.*]] = load i64, ptr [[DOTOMP_LB]], align 8 +// IR-PCH-NEXT: store i64 [[TMP7]], ptr [[DOTOMP_IV]], align 8 // IR-PCH-NEXT: store i32 0, ptr [[Z13]], align 4 // IR-PCH-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // IR-PCH: omp.inner.for.cond: -// IR-PCH-NEXT: [[TMP6:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3:![0-9]+]] -// IR-PCH-NEXT: [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8, !llvm.access.group [[ACC_GRP3]] -// IR-PCH-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP7]], 1 -// IR-PCH-NEXT: [[CMP14:%.*]] = icmp slt i64 [[TMP6]], [[ADD]] +// IR-PCH-NEXT: [[TMP8:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3:![0-9]+]] +// IR-PCH-NEXT: [[TMP9:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8, !llvm.access.group [[ACC_GRP3]] +// IR-PCH-NEXT: [[CMP14:%.*]] = icmp sle i64 [[TMP8]], [[TMP9]] // IR-PCH-NEXT: br i1 [[CMP14]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // IR-PCH: omp.inner.for.body: -// IR-PCH-NEXT: [[TMP8:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] -// IR-PCH-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !llvm.access.group [[ACC_GRP3]] -// IR-PCH-NEXT: [[SUB15:%.*]] = sub nsw i32 [[TMP9]], 0 +// IR-PCH-NEXT: [[TMP10:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] +// IR-PCH-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !llvm.access.group [[ACC_GRP3]] +// IR-PCH-NEXT: [[SUB15:%.*]] = sub nsw i32 [[TMP11]], 0 // IR-PCH-NEXT: [[DIV16:%.*]] = sdiv i32 [[SUB15]], 1 // IR-PCH-NEXT: [[MUL17:%.*]] = mul nsw i32 1, [[DIV16]] // IR-PCH-NEXT: [[CONV18:%.*]] = sext i32 [[MUL17]] to i64 -// IR-PCH-NEXT: [[DIV19:%.*]] = sdiv i64 [[TMP8]], [[CONV18]] +// IR-PCH-NEXT: [[DIV19:%.*]] = sdiv i64 [[TMP10]], [[CONV18]] // IR-PCH-NEXT: [[MUL20:%.*]] = mul nsw i64 [[DIV19]], 1 // IR-PCH-NEXT: [[ADD21:%.*]] = add nsw i64 0, [[MUL20]] // IR-PCH-NEXT: [[CONV22:%.*]] = trunc i64 [[ADD21]] to i32 // IR-PCH-NEXT: store i32 [[CONV22]], ptr [[I11]], align 4, !llvm.access.group [[ACC_GRP3]] -// IR-PCH-NEXT: [[TMP10:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] -// IR-PCH-NEXT: [[TMP11:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] -// IR-PCH-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !llvm.access.group [[ACC_GRP3]] -// IR-PCH-NEXT: [[SUB23:%.*]] = sub nsw i32 [[TMP12]], 0 +// IR-PCH-NEXT: [[TMP12:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] +// IR-PCH-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] +// IR-PCH-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !llvm.access.group [[ACC_GRP3]] +// IR-PCH-NEXT: [[SUB23:%.*]] = sub nsw i32 [[TMP14]], 0 // IR-PCH-NEXT: [[DIV24:%.*]] = sdiv i32 [[SUB23]], 1 // IR-PCH-NEXT: [[MUL25:%.*]] = mul nsw i32 1, [[DIV24]] // IR-PCH-NEXT: [[CONV26:%.*]] = sext i32 [[MUL25]] to i64 -// IR-PCH-NEXT: [[DIV27:%.*]] = sdiv i64 [[TMP11]], [[CONV26]] -// IR-PCH-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !llvm.access.group [[ACC_GRP3]] -// IR-PCH-NEXT: [[SUB28:%.*]] = sub nsw i32 [[TMP13]], 0 +// IR-PCH-NEXT: [[DIV27:%.*]] = sdiv i64 [[TMP13]], [[CONV26]] +// IR-PCH-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !llvm.access.group [[ACC_GRP3]] +// IR-PCH-NEXT: [[SUB28:%.*]] = sub nsw i32 [[TMP15]], 0 // IR-PCH-NEXT: [[DIV29:%.*]] = sdiv i32 [[SUB28]], 1 // IR-PCH-NEXT: [[MUL30:%.*]] = mul nsw i32 1, [[DIV29]] // IR-PCH-NEXT: [[CONV31:%.*]] = sext i32 [[MUL30]] to i64 // IR-PCH-NEXT: [[MUL32:%.*]] = mul nsw i64 [[DIV27]], [[CONV31]] -// IR-PCH-NEXT: [[SUB33:%.*]] = sub nsw i64 [[TMP10]], [[MUL32]] +// IR-PCH-NEXT: [[SUB33:%.*]] = sub nsw i64 [[TMP12]], [[MUL32]] // IR-PCH-NEXT: [[MUL34:%.*]] = mul nsw i64 [[SUB33]], 1 // IR-PCH-NEXT: [[ADD35:%.*]] = add nsw i64 0, [[MUL34]] // IR-PCH-NEXT: [[CONV36:%.*]] = trunc i64 [[ADD35]] to i32 // IR-PCH-NEXT: store i32 [[CONV36]], ptr [[J12]], align 4, !llvm.access.group [[ACC_GRP3]] -// IR-PCH-NEXT: [[TMP14:%.*]] = load i32, ptr [[I11]], align 4, !llvm.access.group [[ACC_GRP3]] -// IR-PCH-NEXT: [[TMP15:%.*]] = load i32, ptr [[J12]], align 4, !llvm.access.group [[ACC_GRP3]] -// IR-PCH-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP14]], [[TMP15]] -// IR-PCH-NEXT: [[TMP16:%.*]] = load i32, ptr [[Z13]], align 4, !llvm.access.group [[ACC_GRP3]] -// IR-PCH-NEXT: [[ADD38:%.*]] = add nsw i32 [[TMP16]], [[ADD37]] +// IR-PCH-NEXT: [[TMP16:%.*]] = load i32, ptr [[I11]], align 4, !llvm.access.group [[ACC_GRP3]] +// IR-PCH-NEXT: [[TMP17:%.*]] = load i32, ptr [[J12]], align 4, !llvm.access.group [[ACC_GRP3]] +// IR-PCH-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// IR-PCH-NEXT: [[TMP18:%.*]] = load i32, ptr [[Z13]], align 4, !llvm.access.group [[ACC_GRP3]] +// IR-PCH-NEXT: [[ADD38:%.*]] = add nsw i32 [[TMP18]], [[ADD37]] // IR-PCH-NEXT: store i32 [[ADD38]], ptr [[Z13]], align 4, !llvm.access.group [[ACC_GRP3]] // IR-PCH-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // IR-PCH: omp.body.continue: // IR-PCH-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // IR-PCH: omp.inner.for.inc: -// IR-PCH-NEXT: [[TMP17:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] -// IR-PCH-NEXT: [[ADD39:%.*]] = add nsw i64 [[TMP17]], 1 +// IR-PCH-NEXT: [[TMP19:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] +// IR-PCH-NEXT: [[ADD39:%.*]] = add nsw i64 [[TMP19]], 1 // IR-PCH-NEXT: store i64 [[ADD39]], ptr [[DOTOMP_IV]], align 8, !llvm.access.group [[ACC_GRP3]] // IR-PCH-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]] // IR-PCH: omp.inner.for.end: -// IR-PCH-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 -// IR-PCH-NEXT: [[SUB40:%.*]] = sub nsw i32 [[TMP18]], 0 +// IR-PCH-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// IR-PCH-NEXT: [[SUB40:%.*]] = sub nsw i32 [[TMP20]], 0 // IR-PCH-NEXT: [[DIV41:%.*]] = sdiv i32 [[SUB40]], 1 // IR-PCH-NEXT: [[MUL42:%.*]] = mul nsw i32 [[DIV41]], 1 // IR-PCH-NEXT: [[ADD43:%.*]] = add nsw i32 0, [[MUL42]] // IR-PCH-NEXT: store i32 [[ADD43]], ptr [[I11]], align 4 -// IR-PCH-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 -// IR-PCH-NEXT: [[SUB44:%.*]] = sub nsw i32 [[TMP19]], 0 +// IR-PCH-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// IR-PCH-NEXT: [[SUB44:%.*]] = sub nsw i32 [[TMP21]], 0 // IR-PCH-NEXT: [[DIV45:%.*]] = sdiv i32 [[SUB44]], 1 // IR-PCH-NEXT: [[MUL46:%.*]] = mul nsw i32 [[DIV45]], 1 // IR-PCH-NEXT: [[ADD47:%.*]] = add nsw i32 0, [[MUL46]] // IR-PCH-NEXT: store i32 [[ADD47]], ptr [[J]], align 4 -// IR-PCH-NEXT: [[TMP20:%.*]] = load i32, ptr [[Z]], align 4 -// IR-PCH-NEXT: [[TMP21:%.*]] = load i32, ptr [[Z13]], align 4 -// IR-PCH-NEXT: [[ADD48:%.*]] = add nsw i32 [[TMP20]], [[TMP21]] +// IR-PCH-NEXT: [[TMP22:%.*]] = load i32, ptr [[Z]], align 4 +// IR-PCH-NEXT: [[TMP23:%.*]] = load i32, ptr [[Z13]], align 4 +// IR-PCH-NEXT: [[ADD48:%.*]] = add nsw i32 [[TMP22]], [[TMP23]] // IR-PCH-NEXT: store i32 [[ADD48]], ptr [[Z]], align 4 // IR-PCH-NEXT: br label [[SIMD_IF_END]] // IR-PCH: simd.if.end: diff --git a/clang/test/OpenMP/interchange_ast_print.cpp b/clang/test/OpenMP/interchange_ast_print.cpp new file mode 100644 index 0000000000000..f8bf075cd300f --- /dev/null +++ b/clang/test/OpenMP/interchange_ast_print.cpp @@ -0,0 +1,135 @@ +// Check no warnings/errors +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -std=c++20 -fopenmp -fopenmp-version=60 -fsyntax-only -verify %s +// expected-no-diagnostics + +// Check AST and unparsing +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -std=c++20 -fopenmp -fopenmp-version=60 -ast-dump %s | FileCheck %s --check-prefix=DUMP +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -std=c++20 -fopenmp -fopenmp-version=60 -ast-print %s | FileCheck %s --check-prefix=PRINT + +// Check same results after serialization round-trip +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -std=c++20 -fopenmp -fopenmp-version=60 -emit-pch -o %t %s +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -std=c++20 -fopenmp -fopenmp-version=60 -include-pch %t -ast-dump-all %s | FileCheck %s --check-prefix=DUMP +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -std=c++20 -fopenmp -fopenmp-version=60 -include-pch %t -ast-print %s | FileCheck %s --check-prefix=PRINT + +#ifndef HEADER +#define HEADER + +// placeholder for loop body code. +extern "C" void body(...); + +// PRINT-LABEL: void foo1( +// DUMP-LABEL: FunctionDecl {{.*}} foo1 +void foo1() { + // PRINT: #pragma omp interchange + // DUMP: OMPInterchangeDirective + #pragma omp interchange + // PRINT: for (int i = 7; i < 17; i += 3) + // DUMP-NEXT: ForStmt + for (int i = 7; i < 17; i += 3) + // PRINT: for (int j = 7; j < 17; j += 3) + // DUMP: ForStmt + for (int j = 7; j < 17; j += 3) + // PRINT: body(i, j); + // DUMP: CallExpr + body(i, j); +} + + + + +// PRINT-LABEL: void foo3( +// DUMP-LABEL: FunctionDecl {{.*}} foo3 +void foo3() { + // PRINT: #pragma omp for collapse(3) + // DUMP: OMPForDirective + // DUMP-NEXT: OMPCollapseClause + // DUMP-NEXT: ConstantExpr + // DUMP-NEXT: value: Int 3 + // DUMP-NEXT: IntegerLiteral {{.*}} 3 + // DUMP-NEXT: CapturedStmt + // DUMP-NEXT: CapturedDecl + #pragma omp for collapse(3) + // PRINT: #pragma omp interchange + // DUMP: OMPInterchangeDirective + #pragma omp interchange + // PRINT: for (int i = 7; i < 17; i += 1) + // DUMP-NEXT: ForStmt + for (int i = 7; i < 17; i += 1) + // PRINT: for (int j = 7; j < 17; j += 1) + // DUMP: ForStmt + for (int j = 7; j < 17; j += 1) + // PRINT: for (int k = 7; k < 17; k += 1) + // DUMP: ForStmt + for (int k = 7; k < 17; k += 1) + // PRINT: body(i, j, k); + // DUMP: CallExpr + body(i, j, k); +} + + +// PRINT-LABEL: void foo6( +// DUMP-LABEL: FunctionTemplateDecl {{.*}} foo6 +template +void foo6() { + // PRINT: #pragma omp interchange + // DUMP: OMPInterchangeDirective + #pragma omp interchange + // PRINT-NEXT: for (int i = 0; i < 11; i += 2) + // DUMP-NEXT: ForStmt + for (int i = 0; i < 11; i += 2) + // PRINT-NEXT: #pragma omp tile sizes(Tile) + // DUMP: OMPTileDirective + #pragma omp tile sizes(Tile) + // PRINT-NEXT: for (int j = 0; j < 13; j += 2) + // DUMP: ForStmt + for (int j = 0; j < 13; j += 2) + // PRINT-NEXT: body(i, j); + // DUMP: CallExpr + body(i, j); +} + +// Also test instantiating the template. +void tfoo6() { + foo6<32>(); +} + + +// PRINT-LABEL: void foo7( +// DUMP-LABEL: FunctionDecl {{.*}} foo7 +void foo7() { + double arr[128]; + // PRINT: #pragma omp interchange + // DUMP: OMPInterchangeDirective + #pragma omp interchange + // PRINT-NEXT: for (double c = 42; auto &&v : arr) + // DUMP-NEXT: CXXForRangeStmt + for (double c = 42; auto &&v : arr) + // PRINT-NEXT: for (int i = 0; i < 42; i += 2) + // DUMP: ForStmt + for (int i = 0; i < 42; i += 2) + // PRINT-NEXT: body(c, v, i); + // DUMP: CallExpr + body(c, v, i); +} + + +// PRINT-LABEL: void foo8( +// DUMP-LABEL: FunctionDecl {{.*}} foo8 +void foo8() { + double arr[128]; + // PRINT: #pragma omp interchange + // DUMP: OMPInterchangeDirective + #pragma omp interchange + // PRINT-NEXT: for (int i = 0; i < 42; i += 2) + // DUMP-NEXT: ForStmt + for (int i = 0; i < 42; i += 2) + // PRINT-NEXT: for (double c = 42; auto &&v : arr) + // DUMP: CXXForRangeStmt + for (double c = 42; auto &&v : arr) + // PRINT-NEXT: body(i, c, v); + // DUMP: CallExpr + body(i, c, v); +} + +#endif + diff --git a/clang/test/OpenMP/interchange_codegen.cpp b/clang/test/OpenMP/interchange_codegen.cpp new file mode 100644 index 0000000000000..9c1782183cf98 --- /dev/null +++ b/clang/test/OpenMP/interchange_codegen.cpp @@ -0,0 +1,1990 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ + +// expected-no-diagnostics + +// Check code generation +// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -std=c++20 -fclang-abi-compat=latest -fopenmp -fopenmp-version=60 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1 + +// Check same results after serialization round-trip +// FIXME: They should be exactly the same but currently differ in function order +// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -std=c++20 -fclang-abi-compat=latest -fopenmp -fopenmp-version=60 -emit-pch -o %t %s +// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -std=c++20 -fclang-abi-compat=latest -fopenmp -fopenmp-version=60 -include-pch %t -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK2 + +#ifndef HEADER +#define HEADER + +// placeholder for loop body code. +extern "C" void body(...) {} + + + + +extern "C" void foo2(int start1, int start2, int end1, int end2, int step1, int step2) { +#pragma omp interchange + for (int i = start1; i < end1; i += step1) + for (int j = start2; j < end2; j += step2) + body(i, j); +} + + +extern "C" void foo3() { +#pragma omp for +#pragma omp interchange + for (int i = 7; i < 17; i += 3) + for (int j = 7; j < 17; j += 3) + body(i, j); +} + + +extern "C" void foo4() { +#pragma omp for collapse(2) + for (int k = 7; k < 17; k += 3) +#pragma omp interchange + for (int i = 7; i < 17; i += 3) + for (int j = 7; j < 17; j += 3) + body(i, j); +} + + +extern "C" void foo6() { +#pragma omp for collapse(4) + for (int i = 7; i < 17; i += 3) +#pragma omp interchange + for (int j = 7; j < 17; j += 3) + for (int k = 7; k < 17; k += 3) + for (int l = 7; l < 17; l += 3) + body(i, j, k, l); +} + + +extern "C" void foo9() { + double arr[128]; + #pragma omp interchange + for (double c = 42; auto && v : arr) + for (int i = 0; i < 42; i += 2) + body(c, v, i); +} + + +extern "C" void foo10() { + double A[128], B[16]; + #pragma omp for collapse(4) + for (int i = 0; i < 128; ++i) + #pragma omp interchange + for (double c = 42; auto aa : A) + for (double d = 42; auto &bb : B) + for (int j = 0; j < 128; ++j) + body(i, c, aa, d, bb, j); +} + +#endif /* HEADER */ + +// CHECK1-LABEL: define {{[^@]+}}@body +// CHECK1-SAME: (...) #[[ATTR0:[0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@foo2 +// CHECK1-SAME: (i32 noundef [[START1:%.*]], i32 noundef [[START2:%.*]], i32 noundef [[END1:%.*]], i32 noundef [[END2:%.*]], i32 noundef [[STEP1:%.*]], i32 noundef [[STEP2:%.*]]) #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[START1_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[START2_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[END1_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[END2_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[STEP1_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[STEP2_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTNEW_STEP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_2:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[J:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_5:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_6:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTNEW_STEP7:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_8:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTPERMUTED_0_IV_J:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTPERMUTED_1_IV_I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store i32 [[START1]], ptr [[START1_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[START2]], ptr [[START2_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[END1]], ptr [[END1_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[END2]], ptr [[END2_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[STEP1]], ptr [[STEP1_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[STEP2]], ptr [[STEP2_ADDR]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr [[START1_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP0]], ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[START1_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[END1_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP2]], ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[STEP1_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP3]], ptr [[DOTNEW_STEP]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK1-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], [[TMP5]] +// CHECK1-NEXT: [[SUB3:%.*]] = sub i32 [[SUB]], 1 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 +// CHECK1-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], [[TMP6]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 +// CHECK1-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], [[TMP7]] +// CHECK1-NEXT: [[SUB4:%.*]] = sub i32 [[DIV]], 1 +// CHECK1-NEXT: store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[START2_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP8]], ptr [[J]], align 4 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[START2_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP9]], ptr [[DOTCAPTURE_EXPR_5]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[END2_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP10]], ptr [[DOTCAPTURE_EXPR_6]], align 4 +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[STEP2_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP11]], ptr [[DOTNEW_STEP7]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_5]], align 4 +// CHECK1-NEXT: [[SUB9:%.*]] = sub i32 [[TMP12]], [[TMP13]] +// CHECK1-NEXT: [[SUB10:%.*]] = sub i32 [[SUB9]], 1 +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTNEW_STEP7]], align 4 +// CHECK1-NEXT: [[ADD11:%.*]] = add i32 [[SUB10]], [[TMP14]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTNEW_STEP7]], align 4 +// CHECK1-NEXT: [[DIV12:%.*]] = udiv i32 [[ADD11]], [[TMP15]] +// CHECK1-NEXT: [[SUB13:%.*]] = sub i32 [[DIV12]], 1 +// CHECK1-NEXT: store i32 [[SUB13]], ptr [[DOTCAPTURE_EXPR_8]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK1-NEXT: br label [[FOR_COND:%.*]] +// CHECK1: for.cond: +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_8]], align 4 +// CHECK1-NEXT: [[ADD14:%.*]] = add i32 [[TMP17]], 1 +// CHECK1-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP16]], [[ADD14]] +// CHECK1-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END24:%.*]] +// CHECK1: for.body: +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_5]], align 4 +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTNEW_STEP7]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul i32 [[TMP19]], [[TMP20]] +// CHECK1-NEXT: [[ADD15:%.*]] = add i32 [[TMP18]], [[MUL]] +// CHECK1-NEXT: store i32 [[ADD15]], ptr [[J]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK1-NEXT: br label [[FOR_COND16:%.*]] +// CHECK1: for.cond16: +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: [[ADD17:%.*]] = add i32 [[TMP22]], 1 +// CHECK1-NEXT: [[CMP18:%.*]] = icmp ult i32 [[TMP21]], [[ADD17]] +// CHECK1-NEXT: br i1 [[CMP18]], label [[FOR_BODY19:%.*]], label [[FOR_END:%.*]] +// CHECK1: for.body19: +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 +// CHECK1-NEXT: [[MUL20:%.*]] = mul i32 [[TMP24]], [[TMP25]] +// CHECK1-NEXT: [[ADD21:%.*]] = add i32 [[TMP23]], [[MUL20]] +// CHECK1-NEXT: store i32 [[ADD21]], ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[J]], align 4 +// CHECK1-NEXT: call void (...) @body(i32 noundef [[TMP26]], i32 noundef [[TMP27]]) +// CHECK1-NEXT: br label [[FOR_INC:%.*]] +// CHECK1: for.inc: +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK1-NEXT: [[INC:%.*]] = add i32 [[TMP28]], 1 +// CHECK1-NEXT: store i32 [[INC]], ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK1-NEXT: br label [[FOR_COND16]], !llvm.loop [[LOOP3:![0-9]+]] +// CHECK1: for.end: +// CHECK1-NEXT: br label [[FOR_INC22:%.*]] +// CHECK1: for.inc22: +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK1-NEXT: [[INC23:%.*]] = add i32 [[TMP29]], 1 +// CHECK1-NEXT: store i32 [[INC23]], ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK1-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP5:![0-9]+]] +// CHECK1: for.end24: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@foo3 +// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[J:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTPERMUTED_0_IV_J:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTPERMUTED_1_IV_I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2:[0-9]+]]) +// CHECK1-NEXT: store i32 7, ptr [[I]], align 4 +// CHECK1-NEXT: store i32 7, ptr [[J]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 3 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 3, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP6]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK1-NEXT: [[MUL2:%.*]] = mul nsw i32 [[TMP7]], 3 +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 7, [[MUL2]] +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[J]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK1-NEXT: br label [[FOR_COND:%.*]] +// CHECK1: for.cond: +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK1-NEXT: [[CMP4:%.*]] = icmp slt i32 [[TMP8]], 4 +// CHECK1-NEXT: br i1 [[CMP4]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +// CHECK1: for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK1-NEXT: [[MUL5:%.*]] = mul nsw i32 [[TMP9]], 3 +// CHECK1-NEXT: [[ADD6:%.*]] = add nsw i32 7, [[MUL5]] +// CHECK1-NEXT: store i32 [[ADD6]], ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[J]], align 4 +// CHECK1-NEXT: call void (...) @body(i32 noundef [[TMP10]], i32 noundef [[TMP11]]) +// CHECK1-NEXT: br label [[FOR_INC:%.*]] +// CHECK1: for.inc: +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK1-NEXT: [[INC:%.*]] = add nsw i32 [[TMP12]], 1 +// CHECK1-NEXT: store i32 [[INC]], ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK1-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]] +// CHECK1: for.end: +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP13]], 1 +// CHECK1-NEXT: store i32 [[ADD7]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]]) +// CHECK1-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3:[0-9]+]], i32 [[TMP0]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@foo4 +// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[J:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[K:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTPERMUTED_0_IV_J:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTPERMUTED_1_IV_I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]]) +// CHECK1-NEXT: store i32 7, ptr [[I]], align 4 +// CHECK1-NEXT: store i32 7, ptr [[J]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 15, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 15 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 15, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP6]], 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[DIV]], 3 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 7, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[K]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[DIV3:%.*]] = sdiv i32 [[TMP8]], 4 +// CHECK1-NEXT: [[MUL4:%.*]] = mul nsw i32 [[DIV3]], 4 +// CHECK1-NEXT: [[SUB:%.*]] = sub nsw i32 [[TMP7]], [[MUL4]] +// CHECK1-NEXT: [[MUL5:%.*]] = mul nsw i32 [[SUB]], 1 +// CHECK1-NEXT: [[ADD6:%.*]] = add nsw i32 0, [[MUL5]] +// CHECK1-NEXT: store i32 [[ADD6]], ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK1-NEXT: [[MUL7:%.*]] = mul nsw i32 [[TMP9]], 3 +// CHECK1-NEXT: [[ADD8:%.*]] = add nsw i32 7, [[MUL7]] +// CHECK1-NEXT: store i32 [[ADD8]], ptr [[J]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK1-NEXT: br label [[FOR_COND:%.*]] +// CHECK1: for.cond: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK1-NEXT: [[CMP9:%.*]] = icmp slt i32 [[TMP10]], 4 +// CHECK1-NEXT: br i1 [[CMP9]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +// CHECK1: for.body: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK1-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP11]], 3 +// CHECK1-NEXT: [[ADD11:%.*]] = add nsw i32 7, [[MUL10]] +// CHECK1-NEXT: store i32 [[ADD11]], ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[J]], align 4 +// CHECK1-NEXT: call void (...) @body(i32 noundef [[TMP12]], i32 noundef [[TMP13]]) +// CHECK1-NEXT: br label [[FOR_INC:%.*]] +// CHECK1: for.inc: +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK1-NEXT: [[INC:%.*]] = add nsw i32 [[TMP14]], 1 +// CHECK1-NEXT: store i32 [[INC]], ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK1-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP7:![0-9]+]] +// CHECK1: for.end: +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD12:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK1-NEXT: store i32 [[ADD12]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]]) +// CHECK1-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@foo6 +// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[_TMP3:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[J:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[K:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTPERMUTED_0_IV_K:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTPERMUTED_1_IV_J:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[L:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]]) +// CHECK1-NEXT: store i32 7, ptr [[J]], align 4 +// CHECK1-NEXT: store i32 7, ptr [[K]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 255, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 255 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 255, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP4:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]] +// CHECK1-NEXT: br i1 [[CMP4]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP6]], 64 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[DIV]], 3 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 7, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[DIV5:%.*]] = sdiv i32 [[TMP8]], 64 +// CHECK1-NEXT: [[MUL6:%.*]] = mul nsw i32 [[DIV5]], 64 +// CHECK1-NEXT: [[SUB:%.*]] = sub nsw i32 [[TMP7]], [[MUL6]] +// CHECK1-NEXT: [[DIV7:%.*]] = sdiv i32 [[SUB]], 16 +// CHECK1-NEXT: [[MUL8:%.*]] = mul nsw i32 [[DIV7]], 1 +// CHECK1-NEXT: [[ADD9:%.*]] = add nsw i32 0, [[MUL8]] +// CHECK1-NEXT: store i32 [[ADD9]], ptr [[DOTPERMUTED_0_IV_K]], align 4 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[DIV10:%.*]] = sdiv i32 [[TMP10]], 64 +// CHECK1-NEXT: [[MUL11:%.*]] = mul nsw i32 [[DIV10]], 64 +// CHECK1-NEXT: [[SUB12:%.*]] = sub nsw i32 [[TMP9]], [[MUL11]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[DIV13:%.*]] = sdiv i32 [[TMP12]], 64 +// CHECK1-NEXT: [[MUL14:%.*]] = mul nsw i32 [[DIV13]], 64 +// CHECK1-NEXT: [[SUB15:%.*]] = sub nsw i32 [[TMP11]], [[MUL14]] +// CHECK1-NEXT: [[DIV16:%.*]] = sdiv i32 [[SUB15]], 16 +// CHECK1-NEXT: [[MUL17:%.*]] = mul nsw i32 [[DIV16]], 16 +// CHECK1-NEXT: [[SUB18:%.*]] = sub nsw i32 [[SUB12]], [[MUL17]] +// CHECK1-NEXT: [[DIV19:%.*]] = sdiv i32 [[SUB18]], 4 +// CHECK1-NEXT: [[MUL20:%.*]] = mul nsw i32 [[DIV19]], 1 +// CHECK1-NEXT: [[ADD21:%.*]] = add nsw i32 0, [[MUL20]] +// CHECK1-NEXT: store i32 [[ADD21]], ptr [[DOTPERMUTED_1_IV_J]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[DIV22:%.*]] = sdiv i32 [[TMP14]], 64 +// CHECK1-NEXT: [[MUL23:%.*]] = mul nsw i32 [[DIV22]], 64 +// CHECK1-NEXT: [[SUB24:%.*]] = sub nsw i32 [[TMP13]], [[MUL23]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[DIV25:%.*]] = sdiv i32 [[TMP16]], 64 +// CHECK1-NEXT: [[MUL26:%.*]] = mul nsw i32 [[DIV25]], 64 +// CHECK1-NEXT: [[SUB27:%.*]] = sub nsw i32 [[TMP15]], [[MUL26]] +// CHECK1-NEXT: [[DIV28:%.*]] = sdiv i32 [[SUB27]], 16 +// CHECK1-NEXT: [[MUL29:%.*]] = mul nsw i32 [[DIV28]], 16 +// CHECK1-NEXT: [[SUB30:%.*]] = sub nsw i32 [[SUB24]], [[MUL29]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[DIV31:%.*]] = sdiv i32 [[TMP18]], 64 +// CHECK1-NEXT: [[MUL32:%.*]] = mul nsw i32 [[DIV31]], 64 +// CHECK1-NEXT: [[SUB33:%.*]] = sub nsw i32 [[TMP17]], [[MUL32]] +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[DIV34:%.*]] = sdiv i32 [[TMP20]], 64 +// CHECK1-NEXT: [[MUL35:%.*]] = mul nsw i32 [[DIV34]], 64 +// CHECK1-NEXT: [[SUB36:%.*]] = sub nsw i32 [[TMP19]], [[MUL35]] +// CHECK1-NEXT: [[DIV37:%.*]] = sdiv i32 [[SUB36]], 16 +// CHECK1-NEXT: [[MUL38:%.*]] = mul nsw i32 [[DIV37]], 16 +// CHECK1-NEXT: [[SUB39:%.*]] = sub nsw i32 [[SUB33]], [[MUL38]] +// CHECK1-NEXT: [[DIV40:%.*]] = sdiv i32 [[SUB39]], 4 +// CHECK1-NEXT: [[MUL41:%.*]] = mul nsw i32 [[DIV40]], 4 +// CHECK1-NEXT: [[SUB42:%.*]] = sub nsw i32 [[SUB30]], [[MUL41]] +// CHECK1-NEXT: [[MUL43:%.*]] = mul nsw i32 [[SUB42]], 3 +// CHECK1-NEXT: [[ADD44:%.*]] = add nsw i32 7, [[MUL43]] +// CHECK1-NEXT: store i32 [[ADD44]], ptr [[L]], align 4 +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_K]], align 4 +// CHECK1-NEXT: [[MUL45:%.*]] = mul nsw i32 [[TMP21]], 3 +// CHECK1-NEXT: [[ADD46:%.*]] = add nsw i32 7, [[MUL45]] +// CHECK1-NEXT: store i32 [[ADD46]], ptr [[K]], align 4 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_J]], align 4 +// CHECK1-NEXT: [[MUL47:%.*]] = mul nsw i32 [[TMP22]], 3 +// CHECK1-NEXT: [[ADD48:%.*]] = add nsw i32 7, [[MUL47]] +// CHECK1-NEXT: store i32 [[ADD48]], ptr [[J]], align 4 +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[J]], align 4 +// CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[K]], align 4 +// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[L]], align 4 +// CHECK1-NEXT: call void (...) @body(i32 noundef [[TMP23]], i32 noundef [[TMP24]], i32 noundef [[TMP25]], i32 noundef [[TMP26]]) +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD49:%.*]] = add nsw i32 [[TMP27]], 1 +// CHECK1-NEXT: store i32 [[ADD49]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]]) +// CHECK1-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@foo9 +// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARR:%.*]] = alloca [128 x double], align 16 +// CHECK1-NEXT: [[C:%.*]] = alloca double, align 8 +// CHECK1-NEXT: [[__RANGE2:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[__END2:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[__BEGIN2:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_3:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTPERMUTED_0_IV_I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTPERMUTED_1_IV___BEGIN2:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[V:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store double 4.200000e+01, ptr [[C]], align 8 +// CHECK1-NEXT: store ptr [[ARR]], ptr [[__RANGE2]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP0]], i64 0, i64 0 +// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 128 +// CHECK1-NEXT: store ptr [[ADD_PTR]], ptr [[__END2]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP1]], i64 0, i64 0 +// CHECK1-NEXT: store ptr [[ARRAYDECAY1]], ptr [[__BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY2:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP2]], i64 0, i64 0 +// CHECK1-NEXT: store ptr [[ARRAYDECAY2]], ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__END2]], align 8 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[DOTCAPTURE_EXPR_3]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_3]], align 8 +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[TMP4]] to i64 +// CHECK1-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[TMP5]] to i64 +// CHECK1-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]] +// CHECK1-NEXT: [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8 +// CHECK1-NEXT: [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i64 [[SUB]], 1 +// CHECK1-NEXT: [[DIV:%.*]] = sdiv i64 [[ADD]], 1 +// CHECK1-NEXT: [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1 +// CHECK1-NEXT: store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[I]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTPERMUTED_0_IV_I]], align 4 +// CHECK1-NEXT: br label [[FOR_COND:%.*]] +// CHECK1: for.cond: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_I]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP6]], 21 +// CHECK1-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END15:%.*]] +// CHECK1: for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_I]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 2 +// CHECK1-NEXT: [[ADD6:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD6]], ptr [[I]], align 4 +// CHECK1-NEXT: store i64 0, ptr [[DOTPERMUTED_1_IV___BEGIN2]], align 8 +// CHECK1-NEXT: br label [[FOR_COND7:%.*]] +// CHECK1: for.cond7: +// CHECK1-NEXT: [[TMP8:%.*]] = load i64, ptr [[DOTPERMUTED_1_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK1-NEXT: [[ADD8:%.*]] = add nsw i64 [[TMP9]], 1 +// CHECK1-NEXT: [[CMP9:%.*]] = icmp slt i64 [[TMP8]], [[ADD8]] +// CHECK1-NEXT: br i1 [[CMP9]], label [[FOR_BODY10:%.*]], label [[FOR_END:%.*]] +// CHECK1: for.body10: +// CHECK1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = load i64, ptr [[DOTPERMUTED_1_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[MUL11:%.*]] = mul nsw i64 [[TMP11]], 1 +// CHECK1-NEXT: [[ADD_PTR12:%.*]] = getelementptr inbounds double, ptr [[TMP10]], i64 [[MUL11]] +// CHECK1-NEXT: store ptr [[ADD_PTR12]], ptr [[__BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[__BEGIN2]], align 8 +// CHECK1-NEXT: store ptr [[TMP12]], ptr [[V]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = load double, ptr [[C]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = load ptr, ptr [[V]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = load double, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[I]], align 4 +// CHECK1-NEXT: call void (...) @body(double noundef [[TMP13]], double noundef [[TMP15]], i32 noundef [[TMP16]]) +// CHECK1-NEXT: br label [[FOR_INC:%.*]] +// CHECK1: for.inc: +// CHECK1-NEXT: [[TMP17:%.*]] = load i64, ptr [[DOTPERMUTED_1_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[INC:%.*]] = add nsw i64 [[TMP17]], 1 +// CHECK1-NEXT: store i64 [[INC]], ptr [[DOTPERMUTED_1_IV___BEGIN2]], align 8 +// CHECK1-NEXT: br label [[FOR_COND7]], !llvm.loop [[LOOP8:![0-9]+]] +// CHECK1: for.end: +// CHECK1-NEXT: br label [[FOR_INC13:%.*]] +// CHECK1: for.inc13: +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_I]], align 4 +// CHECK1-NEXT: [[INC14:%.*]] = add nsw i32 [[TMP18]], 1 +// CHECK1-NEXT: store i32 [[INC14]], ptr [[DOTPERMUTED_0_IV_I]], align 4 +// CHECK1-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK1: for.end15: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@foo10 +// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[A:%.*]] = alloca [128 x double], align 16 +// CHECK1-NEXT: [[B:%.*]] = alloca [16 x double], align 16 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[_TMP1:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[_TMP2:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[_TMP3:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[C:%.*]] = alloca double, align 8 +// CHECK1-NEXT: [[__RANGE3:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[__END3:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[__BEGIN3:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_6:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_7:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[D:%.*]] = alloca double, align 8 +// CHECK1-NEXT: [[__RANGE4:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[__END4:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[__BEGIN4:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_12:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_14:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_15:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_24:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_26:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_28:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTPERMUTED_0_IV___BEGIN4:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPERMUTED_1_IV___BEGIN3:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[J:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I37:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTPERMUTED_0_IV___BEGIN438:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPERMUTED_1_IV___BEGIN339:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[J40:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[BB:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[AA:%.*]] = alloca double, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]]) +// CHECK1-NEXT: store double 4.200000e+01, ptr [[C]], align 8 +// CHECK1-NEXT: store ptr [[A]], ptr [[__RANGE3]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE3]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP1]], i64 0, i64 0 +// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 128 +// CHECK1-NEXT: store ptr [[ADD_PTR]], ptr [[__END3]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__RANGE3]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY4:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP2]], i64 0, i64 0 +// CHECK1-NEXT: store ptr [[ARRAYDECAY4]], ptr [[__BEGIN3]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__RANGE3]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY5:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP3]], i64 0, i64 0 +// CHECK1-NEXT: store ptr [[ARRAYDECAY5]], ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[__END3]], align 8 +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[DOTCAPTURE_EXPR_6]], align 8 +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_6]], align 8 +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[TMP5]] to i64 +// CHECK1-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[TMP6]] to i64 +// CHECK1-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]] +// CHECK1-NEXT: [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8 +// CHECK1-NEXT: [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i64 [[SUB]], 1 +// CHECK1-NEXT: [[DIV:%.*]] = sdiv i64 [[ADD]], 1 +// CHECK1-NEXT: [[SUB8:%.*]] = sub nsw i64 [[DIV]], 1 +// CHECK1-NEXT: store i64 [[SUB8]], ptr [[DOTCAPTURE_EXPR_7]], align 8 +// CHECK1-NEXT: store double 4.200000e+01, ptr [[D]], align 8 +// CHECK1-NEXT: store ptr [[B]], ptr [[__RANGE4]], align 8 +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[__RANGE4]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY9:%.*]] = getelementptr inbounds [16 x double], ptr [[TMP7]], i64 0, i64 0 +// CHECK1-NEXT: [[ADD_PTR10:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY9]], i64 16 +// CHECK1-NEXT: store ptr [[ADD_PTR10]], ptr [[__END4]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[__RANGE4]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY11:%.*]] = getelementptr inbounds [16 x double], ptr [[TMP8]], i64 0, i64 0 +// CHECK1-NEXT: store ptr [[ARRAYDECAY11]], ptr [[__BEGIN4]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[__RANGE4]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY13:%.*]] = getelementptr inbounds [16 x double], ptr [[TMP9]], i64 0, i64 0 +// CHECK1-NEXT: store ptr [[ARRAYDECAY13]], ptr [[DOTCAPTURE_EXPR_12]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[__END4]], align 8 +// CHECK1-NEXT: store ptr [[TMP10]], ptr [[DOTCAPTURE_EXPR_14]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_14]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_12]], align 8 +// CHECK1-NEXT: [[SUB_PTR_LHS_CAST16:%.*]] = ptrtoint ptr [[TMP11]] to i64 +// CHECK1-NEXT: [[SUB_PTR_RHS_CAST17:%.*]] = ptrtoint ptr [[TMP12]] to i64 +// CHECK1-NEXT: [[SUB_PTR_SUB18:%.*]] = sub i64 [[SUB_PTR_LHS_CAST16]], [[SUB_PTR_RHS_CAST17]] +// CHECK1-NEXT: [[SUB_PTR_DIV19:%.*]] = sdiv exact i64 [[SUB_PTR_SUB18]], 8 +// CHECK1-NEXT: [[SUB20:%.*]] = sub nsw i64 [[SUB_PTR_DIV19]], 1 +// CHECK1-NEXT: [[ADD21:%.*]] = add nsw i64 [[SUB20]], 1 +// CHECK1-NEXT: [[DIV22:%.*]] = sdiv i64 [[ADD21]], 1 +// CHECK1-NEXT: [[SUB23:%.*]] = sub nsw i64 [[DIV22]], 1 +// CHECK1-NEXT: store i64 [[SUB23]], ptr [[DOTCAPTURE_EXPR_15]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_15]], align 8 +// CHECK1-NEXT: [[ADD25:%.*]] = add nsw i64 [[TMP13]], 1 +// CHECK1-NEXT: store i64 [[ADD25]], ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_7]], align 8 +// CHECK1-NEXT: [[ADD27:%.*]] = add nsw i64 [[TMP14]], 1 +// CHECK1-NEXT: store i64 [[ADD27]], ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[SUB29:%.*]] = sub nsw i64 [[TMP15]], 0 +// CHECK1-NEXT: [[DIV30:%.*]] = sdiv i64 [[SUB29]], 1 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i64 128, [[DIV30]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB31:%.*]] = sub nsw i64 [[TMP16]], 0 +// CHECK1-NEXT: [[DIV32:%.*]] = sdiv i64 [[SUB31]], 1 +// CHECK1-NEXT: [[MUL33:%.*]] = mul nsw i64 [[MUL]], [[DIV32]] +// CHECK1-NEXT: [[MUL34:%.*]] = mul nsw i64 [[MUL33]], 128 +// CHECK1-NEXT: [[SUB35:%.*]] = sub nsw i64 [[MUL34]], 1 +// CHECK1-NEXT: store i64 [[SUB35]], ptr [[DOTCAPTURE_EXPR_28]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[I]], align 4 +// CHECK1-NEXT: store i64 0, ptr [[DOTPERMUTED_0_IV___BEGIN4]], align 8 +// CHECK1-NEXT: store i64 0, ptr [[DOTPERMUTED_1_IV___BEGIN3]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[J]], align 4 +// CHECK1-NEXT: [[TMP17:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[CMP:%.*]] = icmp slt i64 0, [[TMP17]] +// CHECK1-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[OMP_PRECOND_END:%.*]] +// CHECK1: land.lhs.true: +// CHECK1-NEXT: [[TMP18:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[CMP36:%.*]] = icmp slt i64 0, [[TMP18]] +// CHECK1-NEXT: br i1 [[CMP36]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END]] +// CHECK1: omp.precond.then: +// CHECK1-NEXT: store i64 0, ptr [[DOTOMP_LB]], align 8 +// CHECK1-NEXT: [[TMP19:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_28]], align 8 +// CHECK1-NEXT: store i64 [[TMP19]], ptr [[DOTOMP_UB]], align 8 +// CHECK1-NEXT: store i64 1, ptr [[DOTOMP_STRIDE]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_8(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i64 1, i64 1) +// CHECK1-NEXT: [[TMP20:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8 +// CHECK1-NEXT: [[TMP21:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_28]], align 8 +// CHECK1-NEXT: [[CMP41:%.*]] = icmp sgt i64 [[TMP20]], [[TMP21]] +// CHECK1-NEXT: br i1 [[CMP41]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_28]], align 8 +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP23:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i64 [ [[TMP22]], [[COND_TRUE]] ], [ [[TMP23]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i64 [[COND]], ptr [[DOTOMP_UB]], align 8 +// CHECK1-NEXT: [[TMP24:%.*]] = load i64, ptr [[DOTOMP_LB]], align 8 +// CHECK1-NEXT: store i64 [[TMP24]], ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP26:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8 +// CHECK1-NEXT: [[CMP42:%.*]] = icmp sle i64 [[TMP25]], [[TMP26]] +// CHECK1-NEXT: br i1 [[CMP42]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP27:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[SUB43:%.*]] = sub nsw i64 [[TMP28]], 0 +// CHECK1-NEXT: [[DIV44:%.*]] = sdiv i64 [[SUB43]], 1 +// CHECK1-NEXT: [[MUL45:%.*]] = mul nsw i64 1, [[DIV44]] +// CHECK1-NEXT: [[TMP29:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB46:%.*]] = sub nsw i64 [[TMP29]], 0 +// CHECK1-NEXT: [[DIV47:%.*]] = sdiv i64 [[SUB46]], 1 +// CHECK1-NEXT: [[MUL48:%.*]] = mul nsw i64 [[MUL45]], [[DIV47]] +// CHECK1-NEXT: [[MUL49:%.*]] = mul nsw i64 [[MUL48]], 128 +// CHECK1-NEXT: [[DIV50:%.*]] = sdiv i64 [[TMP27]], [[MUL49]] +// CHECK1-NEXT: [[MUL51:%.*]] = mul nsw i64 [[DIV50]], 1 +// CHECK1-NEXT: [[ADD52:%.*]] = add nsw i64 0, [[MUL51]] +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[ADD52]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[I37]], align 4 +// CHECK1-NEXT: [[TMP30:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP31:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP32:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[SUB53:%.*]] = sub nsw i64 [[TMP32]], 0 +// CHECK1-NEXT: [[DIV54:%.*]] = sdiv i64 [[SUB53]], 1 +// CHECK1-NEXT: [[MUL55:%.*]] = mul nsw i64 1, [[DIV54]] +// CHECK1-NEXT: [[TMP33:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB56:%.*]] = sub nsw i64 [[TMP33]], 0 +// CHECK1-NEXT: [[DIV57:%.*]] = sdiv i64 [[SUB56]], 1 +// CHECK1-NEXT: [[MUL58:%.*]] = mul nsw i64 [[MUL55]], [[DIV57]] +// CHECK1-NEXT: [[MUL59:%.*]] = mul nsw i64 [[MUL58]], 128 +// CHECK1-NEXT: [[DIV60:%.*]] = sdiv i64 [[TMP31]], [[MUL59]] +// CHECK1-NEXT: [[TMP34:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[SUB61:%.*]] = sub nsw i64 [[TMP34]], 0 +// CHECK1-NEXT: [[DIV62:%.*]] = sdiv i64 [[SUB61]], 1 +// CHECK1-NEXT: [[MUL63:%.*]] = mul nsw i64 1, [[DIV62]] +// CHECK1-NEXT: [[TMP35:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB64:%.*]] = sub nsw i64 [[TMP35]], 0 +// CHECK1-NEXT: [[DIV65:%.*]] = sdiv i64 [[SUB64]], 1 +// CHECK1-NEXT: [[MUL66:%.*]] = mul nsw i64 [[MUL63]], [[DIV65]] +// CHECK1-NEXT: [[MUL67:%.*]] = mul nsw i64 [[MUL66]], 128 +// CHECK1-NEXT: [[MUL68:%.*]] = mul nsw i64 [[DIV60]], [[MUL67]] +// CHECK1-NEXT: [[SUB69:%.*]] = sub nsw i64 [[TMP30]], [[MUL68]] +// CHECK1-NEXT: [[TMP36:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB70:%.*]] = sub nsw i64 [[TMP36]], 0 +// CHECK1-NEXT: [[DIV71:%.*]] = sdiv i64 [[SUB70]], 1 +// CHECK1-NEXT: [[MUL72:%.*]] = mul nsw i64 1, [[DIV71]] +// CHECK1-NEXT: [[MUL73:%.*]] = mul nsw i64 [[MUL72]], 128 +// CHECK1-NEXT: [[DIV74:%.*]] = sdiv i64 [[SUB69]], [[MUL73]] +// CHECK1-NEXT: [[MUL75:%.*]] = mul nsw i64 [[DIV74]], 1 +// CHECK1-NEXT: [[ADD76:%.*]] = add nsw i64 0, [[MUL75]] +// CHECK1-NEXT: store i64 [[ADD76]], ptr [[DOTPERMUTED_0_IV___BEGIN438]], align 8 +// CHECK1-NEXT: [[TMP37:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP38:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP39:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[SUB77:%.*]] = sub nsw i64 [[TMP39]], 0 +// CHECK1-NEXT: [[DIV78:%.*]] = sdiv i64 [[SUB77]], 1 +// CHECK1-NEXT: [[MUL79:%.*]] = mul nsw i64 1, [[DIV78]] +// CHECK1-NEXT: [[TMP40:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB80:%.*]] = sub nsw i64 [[TMP40]], 0 +// CHECK1-NEXT: [[DIV81:%.*]] = sdiv i64 [[SUB80]], 1 +// CHECK1-NEXT: [[MUL82:%.*]] = mul nsw i64 [[MUL79]], [[DIV81]] +// CHECK1-NEXT: [[MUL83:%.*]] = mul nsw i64 [[MUL82]], 128 +// CHECK1-NEXT: [[DIV84:%.*]] = sdiv i64 [[TMP38]], [[MUL83]] +// CHECK1-NEXT: [[TMP41:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[SUB85:%.*]] = sub nsw i64 [[TMP41]], 0 +// CHECK1-NEXT: [[DIV86:%.*]] = sdiv i64 [[SUB85]], 1 +// CHECK1-NEXT: [[MUL87:%.*]] = mul nsw i64 1, [[DIV86]] +// CHECK1-NEXT: [[TMP42:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB88:%.*]] = sub nsw i64 [[TMP42]], 0 +// CHECK1-NEXT: [[DIV89:%.*]] = sdiv i64 [[SUB88]], 1 +// CHECK1-NEXT: [[MUL90:%.*]] = mul nsw i64 [[MUL87]], [[DIV89]] +// CHECK1-NEXT: [[MUL91:%.*]] = mul nsw i64 [[MUL90]], 128 +// CHECK1-NEXT: [[MUL92:%.*]] = mul nsw i64 [[DIV84]], [[MUL91]] +// CHECK1-NEXT: [[SUB93:%.*]] = sub nsw i64 [[TMP37]], [[MUL92]] +// CHECK1-NEXT: [[TMP43:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP44:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP45:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[SUB94:%.*]] = sub nsw i64 [[TMP45]], 0 +// CHECK1-NEXT: [[DIV95:%.*]] = sdiv i64 [[SUB94]], 1 +// CHECK1-NEXT: [[MUL96:%.*]] = mul nsw i64 1, [[DIV95]] +// CHECK1-NEXT: [[TMP46:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB97:%.*]] = sub nsw i64 [[TMP46]], 0 +// CHECK1-NEXT: [[DIV98:%.*]] = sdiv i64 [[SUB97]], 1 +// CHECK1-NEXT: [[MUL99:%.*]] = mul nsw i64 [[MUL96]], [[DIV98]] +// CHECK1-NEXT: [[MUL100:%.*]] = mul nsw i64 [[MUL99]], 128 +// CHECK1-NEXT: [[DIV101:%.*]] = sdiv i64 [[TMP44]], [[MUL100]] +// CHECK1-NEXT: [[TMP47:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[SUB102:%.*]] = sub nsw i64 [[TMP47]], 0 +// CHECK1-NEXT: [[DIV103:%.*]] = sdiv i64 [[SUB102]], 1 +// CHECK1-NEXT: [[MUL104:%.*]] = mul nsw i64 1, [[DIV103]] +// CHECK1-NEXT: [[TMP48:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB105:%.*]] = sub nsw i64 [[TMP48]], 0 +// CHECK1-NEXT: [[DIV106:%.*]] = sdiv i64 [[SUB105]], 1 +// CHECK1-NEXT: [[MUL107:%.*]] = mul nsw i64 [[MUL104]], [[DIV106]] +// CHECK1-NEXT: [[MUL108:%.*]] = mul nsw i64 [[MUL107]], 128 +// CHECK1-NEXT: [[MUL109:%.*]] = mul nsw i64 [[DIV101]], [[MUL108]] +// CHECK1-NEXT: [[SUB110:%.*]] = sub nsw i64 [[TMP43]], [[MUL109]] +// CHECK1-NEXT: [[TMP49:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB111:%.*]] = sub nsw i64 [[TMP49]], 0 +// CHECK1-NEXT: [[DIV112:%.*]] = sdiv i64 [[SUB111]], 1 +// CHECK1-NEXT: [[MUL113:%.*]] = mul nsw i64 1, [[DIV112]] +// CHECK1-NEXT: [[MUL114:%.*]] = mul nsw i64 [[MUL113]], 128 +// CHECK1-NEXT: [[DIV115:%.*]] = sdiv i64 [[SUB110]], [[MUL114]] +// CHECK1-NEXT: [[TMP50:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB116:%.*]] = sub nsw i64 [[TMP50]], 0 +// CHECK1-NEXT: [[DIV117:%.*]] = sdiv i64 [[SUB116]], 1 +// CHECK1-NEXT: [[MUL118:%.*]] = mul nsw i64 1, [[DIV117]] +// CHECK1-NEXT: [[MUL119:%.*]] = mul nsw i64 [[MUL118]], 128 +// CHECK1-NEXT: [[MUL120:%.*]] = mul nsw i64 [[DIV115]], [[MUL119]] +// CHECK1-NEXT: [[SUB121:%.*]] = sub nsw i64 [[SUB93]], [[MUL120]] +// CHECK1-NEXT: [[DIV122:%.*]] = sdiv i64 [[SUB121]], 128 +// CHECK1-NEXT: [[MUL123:%.*]] = mul nsw i64 [[DIV122]], 1 +// CHECK1-NEXT: [[ADD124:%.*]] = add nsw i64 0, [[MUL123]] +// CHECK1-NEXT: store i64 [[ADD124]], ptr [[DOTPERMUTED_1_IV___BEGIN339]], align 8 +// CHECK1-NEXT: [[TMP51:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP52:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP53:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[SUB125:%.*]] = sub nsw i64 [[TMP53]], 0 +// CHECK1-NEXT: [[DIV126:%.*]] = sdiv i64 [[SUB125]], 1 +// CHECK1-NEXT: [[MUL127:%.*]] = mul nsw i64 1, [[DIV126]] +// CHECK1-NEXT: [[TMP54:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB128:%.*]] = sub nsw i64 [[TMP54]], 0 +// CHECK1-NEXT: [[DIV129:%.*]] = sdiv i64 [[SUB128]], 1 +// CHECK1-NEXT: [[MUL130:%.*]] = mul nsw i64 [[MUL127]], [[DIV129]] +// CHECK1-NEXT: [[MUL131:%.*]] = mul nsw i64 [[MUL130]], 128 +// CHECK1-NEXT: [[DIV132:%.*]] = sdiv i64 [[TMP52]], [[MUL131]] +// CHECK1-NEXT: [[TMP55:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[SUB133:%.*]] = sub nsw i64 [[TMP55]], 0 +// CHECK1-NEXT: [[DIV134:%.*]] = sdiv i64 [[SUB133]], 1 +// CHECK1-NEXT: [[MUL135:%.*]] = mul nsw i64 1, [[DIV134]] +// CHECK1-NEXT: [[TMP56:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB136:%.*]] = sub nsw i64 [[TMP56]], 0 +// CHECK1-NEXT: [[DIV137:%.*]] = sdiv i64 [[SUB136]], 1 +// CHECK1-NEXT: [[MUL138:%.*]] = mul nsw i64 [[MUL135]], [[DIV137]] +// CHECK1-NEXT: [[MUL139:%.*]] = mul nsw i64 [[MUL138]], 128 +// CHECK1-NEXT: [[MUL140:%.*]] = mul nsw i64 [[DIV132]], [[MUL139]] +// CHECK1-NEXT: [[SUB141:%.*]] = sub nsw i64 [[TMP51]], [[MUL140]] +// CHECK1-NEXT: [[TMP57:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP58:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP59:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[SUB142:%.*]] = sub nsw i64 [[TMP59]], 0 +// CHECK1-NEXT: [[DIV143:%.*]] = sdiv i64 [[SUB142]], 1 +// CHECK1-NEXT: [[MUL144:%.*]] = mul nsw i64 1, [[DIV143]] +// CHECK1-NEXT: [[TMP60:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB145:%.*]] = sub nsw i64 [[TMP60]], 0 +// CHECK1-NEXT: [[DIV146:%.*]] = sdiv i64 [[SUB145]], 1 +// CHECK1-NEXT: [[MUL147:%.*]] = mul nsw i64 [[MUL144]], [[DIV146]] +// CHECK1-NEXT: [[MUL148:%.*]] = mul nsw i64 [[MUL147]], 128 +// CHECK1-NEXT: [[DIV149:%.*]] = sdiv i64 [[TMP58]], [[MUL148]] +// CHECK1-NEXT: [[TMP61:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[SUB150:%.*]] = sub nsw i64 [[TMP61]], 0 +// CHECK1-NEXT: [[DIV151:%.*]] = sdiv i64 [[SUB150]], 1 +// CHECK1-NEXT: [[MUL152:%.*]] = mul nsw i64 1, [[DIV151]] +// CHECK1-NEXT: [[TMP62:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB153:%.*]] = sub nsw i64 [[TMP62]], 0 +// CHECK1-NEXT: [[DIV154:%.*]] = sdiv i64 [[SUB153]], 1 +// CHECK1-NEXT: [[MUL155:%.*]] = mul nsw i64 [[MUL152]], [[DIV154]] +// CHECK1-NEXT: [[MUL156:%.*]] = mul nsw i64 [[MUL155]], 128 +// CHECK1-NEXT: [[MUL157:%.*]] = mul nsw i64 [[DIV149]], [[MUL156]] +// CHECK1-NEXT: [[SUB158:%.*]] = sub nsw i64 [[TMP57]], [[MUL157]] +// CHECK1-NEXT: [[TMP63:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB159:%.*]] = sub nsw i64 [[TMP63]], 0 +// CHECK1-NEXT: [[DIV160:%.*]] = sdiv i64 [[SUB159]], 1 +// CHECK1-NEXT: [[MUL161:%.*]] = mul nsw i64 1, [[DIV160]] +// CHECK1-NEXT: [[MUL162:%.*]] = mul nsw i64 [[MUL161]], 128 +// CHECK1-NEXT: [[DIV163:%.*]] = sdiv i64 [[SUB158]], [[MUL162]] +// CHECK1-NEXT: [[TMP64:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB164:%.*]] = sub nsw i64 [[TMP64]], 0 +// CHECK1-NEXT: [[DIV165:%.*]] = sdiv i64 [[SUB164]], 1 +// CHECK1-NEXT: [[MUL166:%.*]] = mul nsw i64 1, [[DIV165]] +// CHECK1-NEXT: [[MUL167:%.*]] = mul nsw i64 [[MUL166]], 128 +// CHECK1-NEXT: [[MUL168:%.*]] = mul nsw i64 [[DIV163]], [[MUL167]] +// CHECK1-NEXT: [[SUB169:%.*]] = sub nsw i64 [[SUB141]], [[MUL168]] +// CHECK1-NEXT: [[TMP65:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP66:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP67:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[SUB170:%.*]] = sub nsw i64 [[TMP67]], 0 +// CHECK1-NEXT: [[DIV171:%.*]] = sdiv i64 [[SUB170]], 1 +// CHECK1-NEXT: [[MUL172:%.*]] = mul nsw i64 1, [[DIV171]] +// CHECK1-NEXT: [[TMP68:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB173:%.*]] = sub nsw i64 [[TMP68]], 0 +// CHECK1-NEXT: [[DIV174:%.*]] = sdiv i64 [[SUB173]], 1 +// CHECK1-NEXT: [[MUL175:%.*]] = mul nsw i64 [[MUL172]], [[DIV174]] +// CHECK1-NEXT: [[MUL176:%.*]] = mul nsw i64 [[MUL175]], 128 +// CHECK1-NEXT: [[DIV177:%.*]] = sdiv i64 [[TMP66]], [[MUL176]] +// CHECK1-NEXT: [[TMP69:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[SUB178:%.*]] = sub nsw i64 [[TMP69]], 0 +// CHECK1-NEXT: [[DIV179:%.*]] = sdiv i64 [[SUB178]], 1 +// CHECK1-NEXT: [[MUL180:%.*]] = mul nsw i64 1, [[DIV179]] +// CHECK1-NEXT: [[TMP70:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB181:%.*]] = sub nsw i64 [[TMP70]], 0 +// CHECK1-NEXT: [[DIV182:%.*]] = sdiv i64 [[SUB181]], 1 +// CHECK1-NEXT: [[MUL183:%.*]] = mul nsw i64 [[MUL180]], [[DIV182]] +// CHECK1-NEXT: [[MUL184:%.*]] = mul nsw i64 [[MUL183]], 128 +// CHECK1-NEXT: [[MUL185:%.*]] = mul nsw i64 [[DIV177]], [[MUL184]] +// CHECK1-NEXT: [[SUB186:%.*]] = sub nsw i64 [[TMP65]], [[MUL185]] +// CHECK1-NEXT: [[TMP71:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP72:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP73:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[SUB187:%.*]] = sub nsw i64 [[TMP73]], 0 +// CHECK1-NEXT: [[DIV188:%.*]] = sdiv i64 [[SUB187]], 1 +// CHECK1-NEXT: [[MUL189:%.*]] = mul nsw i64 1, [[DIV188]] +// CHECK1-NEXT: [[TMP74:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB190:%.*]] = sub nsw i64 [[TMP74]], 0 +// CHECK1-NEXT: [[DIV191:%.*]] = sdiv i64 [[SUB190]], 1 +// CHECK1-NEXT: [[MUL192:%.*]] = mul nsw i64 [[MUL189]], [[DIV191]] +// CHECK1-NEXT: [[MUL193:%.*]] = mul nsw i64 [[MUL192]], 128 +// CHECK1-NEXT: [[DIV194:%.*]] = sdiv i64 [[TMP72]], [[MUL193]] +// CHECK1-NEXT: [[TMP75:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK1-NEXT: [[SUB195:%.*]] = sub nsw i64 [[TMP75]], 0 +// CHECK1-NEXT: [[DIV196:%.*]] = sdiv i64 [[SUB195]], 1 +// CHECK1-NEXT: [[MUL197:%.*]] = mul nsw i64 1, [[DIV196]] +// CHECK1-NEXT: [[TMP76:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB198:%.*]] = sub nsw i64 [[TMP76]], 0 +// CHECK1-NEXT: [[DIV199:%.*]] = sdiv i64 [[SUB198]], 1 +// CHECK1-NEXT: [[MUL200:%.*]] = mul nsw i64 [[MUL197]], [[DIV199]] +// CHECK1-NEXT: [[MUL201:%.*]] = mul nsw i64 [[MUL200]], 128 +// CHECK1-NEXT: [[MUL202:%.*]] = mul nsw i64 [[DIV194]], [[MUL201]] +// CHECK1-NEXT: [[SUB203:%.*]] = sub nsw i64 [[TMP71]], [[MUL202]] +// CHECK1-NEXT: [[TMP77:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB204:%.*]] = sub nsw i64 [[TMP77]], 0 +// CHECK1-NEXT: [[DIV205:%.*]] = sdiv i64 [[SUB204]], 1 +// CHECK1-NEXT: [[MUL206:%.*]] = mul nsw i64 1, [[DIV205]] +// CHECK1-NEXT: [[MUL207:%.*]] = mul nsw i64 [[MUL206]], 128 +// CHECK1-NEXT: [[DIV208:%.*]] = sdiv i64 [[SUB203]], [[MUL207]] +// CHECK1-NEXT: [[TMP78:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK1-NEXT: [[SUB209:%.*]] = sub nsw i64 [[TMP78]], 0 +// CHECK1-NEXT: [[DIV210:%.*]] = sdiv i64 [[SUB209]], 1 +// CHECK1-NEXT: [[MUL211:%.*]] = mul nsw i64 1, [[DIV210]] +// CHECK1-NEXT: [[MUL212:%.*]] = mul nsw i64 [[MUL211]], 128 +// CHECK1-NEXT: [[MUL213:%.*]] = mul nsw i64 [[DIV208]], [[MUL212]] +// CHECK1-NEXT: [[SUB214:%.*]] = sub nsw i64 [[SUB186]], [[MUL213]] +// CHECK1-NEXT: [[DIV215:%.*]] = sdiv i64 [[SUB214]], 128 +// CHECK1-NEXT: [[MUL216:%.*]] = mul nsw i64 [[DIV215]], 128 +// CHECK1-NEXT: [[SUB217:%.*]] = sub nsw i64 [[SUB169]], [[MUL216]] +// CHECK1-NEXT: [[MUL218:%.*]] = mul nsw i64 [[SUB217]], 1 +// CHECK1-NEXT: [[ADD219:%.*]] = add nsw i64 0, [[MUL218]] +// CHECK1-NEXT: [[CONV220:%.*]] = trunc i64 [[ADD219]] to i32 +// CHECK1-NEXT: store i32 [[CONV220]], ptr [[J40]], align 4 +// CHECK1-NEXT: [[TMP79:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_12]], align 8 +// CHECK1-NEXT: [[TMP80:%.*]] = load i64, ptr [[DOTPERMUTED_0_IV___BEGIN438]], align 8 +// CHECK1-NEXT: [[MUL221:%.*]] = mul nsw i64 [[TMP80]], 1 +// CHECK1-NEXT: [[ADD_PTR222:%.*]] = getelementptr inbounds double, ptr [[TMP79]], i64 [[MUL221]] +// CHECK1-NEXT: store ptr [[ADD_PTR222]], ptr [[__BEGIN4]], align 8 +// CHECK1-NEXT: [[TMP81:%.*]] = load ptr, ptr [[__BEGIN4]], align 8 +// CHECK1-NEXT: store ptr [[TMP81]], ptr [[BB]], align 8 +// CHECK1-NEXT: [[TMP82:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[TMP83:%.*]] = load i64, ptr [[DOTPERMUTED_1_IV___BEGIN339]], align 8 +// CHECK1-NEXT: [[MUL223:%.*]] = mul nsw i64 [[TMP83]], 1 +// CHECK1-NEXT: [[ADD_PTR224:%.*]] = getelementptr inbounds double, ptr [[TMP82]], i64 [[MUL223]] +// CHECK1-NEXT: store ptr [[ADD_PTR224]], ptr [[__BEGIN3]], align 8 +// CHECK1-NEXT: [[TMP84:%.*]] = load ptr, ptr [[__BEGIN3]], align 8 +// CHECK1-NEXT: [[TMP85:%.*]] = load double, ptr [[TMP84]], align 8 +// CHECK1-NEXT: store double [[TMP85]], ptr [[AA]], align 8 +// CHECK1-NEXT: [[TMP86:%.*]] = load i32, ptr [[I37]], align 4 +// CHECK1-NEXT: [[TMP87:%.*]] = load double, ptr [[C]], align 8 +// CHECK1-NEXT: [[TMP88:%.*]] = load double, ptr [[AA]], align 8 +// CHECK1-NEXT: [[TMP89:%.*]] = load double, ptr [[D]], align 8 +// CHECK1-NEXT: [[TMP90:%.*]] = load ptr, ptr [[BB]], align 8 +// CHECK1-NEXT: [[TMP91:%.*]] = load double, ptr [[TMP90]], align 8 +// CHECK1-NEXT: [[TMP92:%.*]] = load i32, ptr [[J40]], align 4 +// CHECK1-NEXT: call void (...) @body(i32 noundef [[TMP86]], double noundef [[TMP87]], double noundef [[TMP88]], double noundef [[TMP89]], double noundef [[TMP91]], i32 noundef [[TMP92]]) +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP93:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[ADD225:%.*]] = add nsw i64 [[TMP93]], 1 +// CHECK1-NEXT: store i64 [[ADD225]], ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]]) +// CHECK1-NEXT: br label [[OMP_PRECOND_END]] +// CHECK1: omp.precond.end: +// CHECK1-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]]) +// CHECK1-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@body +// CHECK2-SAME: (...) #[[ATTR0:[0-9]+]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@foo10 +// CHECK2-SAME: () #[[ATTR0]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[A:%.*]] = alloca [128 x double], align 16 +// CHECK2-NEXT: [[B:%.*]] = alloca [16 x double], align 16 +// CHECK2-NEXT: [[DOTOMP_IV:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[_TMP1:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[_TMP2:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[_TMP3:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[C:%.*]] = alloca double, align 8 +// CHECK2-NEXT: [[__RANGE3:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[__END3:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[__BEGIN3:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_6:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_7:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[D:%.*]] = alloca double, align 8 +// CHECK2-NEXT: [[__RANGE4:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[__END4:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[__BEGIN4:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_12:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_14:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_15:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_24:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_26:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_28:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTPERMUTED_0_IV___BEGIN4:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTPERMUTED_1_IV___BEGIN3:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[J:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_LB:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTOMP_UB:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[I37:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTPERMUTED_0_IV___BEGIN438:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTPERMUTED_1_IV___BEGIN339:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[J40:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[BB:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[AA:%.*]] = alloca double, align 8 +// CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2:[0-9]+]]) +// CHECK2-NEXT: store double 4.200000e+01, ptr [[C]], align 8 +// CHECK2-NEXT: store ptr [[A]], ptr [[__RANGE3]], align 8 +// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE3]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP1]], i64 0, i64 0 +// CHECK2-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 128 +// CHECK2-NEXT: store ptr [[ADD_PTR]], ptr [[__END3]], align 8 +// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__RANGE3]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY4:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP2]], i64 0, i64 0 +// CHECK2-NEXT: store ptr [[ARRAYDECAY4]], ptr [[__BEGIN3]], align 8 +// CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__RANGE3]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY5:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP3]], i64 0, i64 0 +// CHECK2-NEXT: store ptr [[ARRAYDECAY5]], ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[__END3]], align 8 +// CHECK2-NEXT: store ptr [[TMP4]], ptr [[DOTCAPTURE_EXPR_6]], align 8 +// CHECK2-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_6]], align 8 +// CHECK2-NEXT: [[TMP6:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[TMP5]] to i64 +// CHECK2-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[TMP6]] to i64 +// CHECK2-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]] +// CHECK2-NEXT: [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8 +// CHECK2-NEXT: [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1 +// CHECK2-NEXT: [[ADD:%.*]] = add nsw i64 [[SUB]], 1 +// CHECK2-NEXT: [[DIV:%.*]] = sdiv i64 [[ADD]], 1 +// CHECK2-NEXT: [[SUB8:%.*]] = sub nsw i64 [[DIV]], 1 +// CHECK2-NEXT: store i64 [[SUB8]], ptr [[DOTCAPTURE_EXPR_7]], align 8 +// CHECK2-NEXT: store double 4.200000e+01, ptr [[D]], align 8 +// CHECK2-NEXT: store ptr [[B]], ptr [[__RANGE4]], align 8 +// CHECK2-NEXT: [[TMP7:%.*]] = load ptr, ptr [[__RANGE4]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY9:%.*]] = getelementptr inbounds [16 x double], ptr [[TMP7]], i64 0, i64 0 +// CHECK2-NEXT: [[ADD_PTR10:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY9]], i64 16 +// CHECK2-NEXT: store ptr [[ADD_PTR10]], ptr [[__END4]], align 8 +// CHECK2-NEXT: [[TMP8:%.*]] = load ptr, ptr [[__RANGE4]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY11:%.*]] = getelementptr inbounds [16 x double], ptr [[TMP8]], i64 0, i64 0 +// CHECK2-NEXT: store ptr [[ARRAYDECAY11]], ptr [[__BEGIN4]], align 8 +// CHECK2-NEXT: [[TMP9:%.*]] = load ptr, ptr [[__RANGE4]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY13:%.*]] = getelementptr inbounds [16 x double], ptr [[TMP9]], i64 0, i64 0 +// CHECK2-NEXT: store ptr [[ARRAYDECAY13]], ptr [[DOTCAPTURE_EXPR_12]], align 8 +// CHECK2-NEXT: [[TMP10:%.*]] = load ptr, ptr [[__END4]], align 8 +// CHECK2-NEXT: store ptr [[TMP10]], ptr [[DOTCAPTURE_EXPR_14]], align 8 +// CHECK2-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_14]], align 8 +// CHECK2-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_12]], align 8 +// CHECK2-NEXT: [[SUB_PTR_LHS_CAST16:%.*]] = ptrtoint ptr [[TMP11]] to i64 +// CHECK2-NEXT: [[SUB_PTR_RHS_CAST17:%.*]] = ptrtoint ptr [[TMP12]] to i64 +// CHECK2-NEXT: [[SUB_PTR_SUB18:%.*]] = sub i64 [[SUB_PTR_LHS_CAST16]], [[SUB_PTR_RHS_CAST17]] +// CHECK2-NEXT: [[SUB_PTR_DIV19:%.*]] = sdiv exact i64 [[SUB_PTR_SUB18]], 8 +// CHECK2-NEXT: [[SUB20:%.*]] = sub nsw i64 [[SUB_PTR_DIV19]], 1 +// CHECK2-NEXT: [[ADD21:%.*]] = add nsw i64 [[SUB20]], 1 +// CHECK2-NEXT: [[DIV22:%.*]] = sdiv i64 [[ADD21]], 1 +// CHECK2-NEXT: [[SUB23:%.*]] = sub nsw i64 [[DIV22]], 1 +// CHECK2-NEXT: store i64 [[SUB23]], ptr [[DOTCAPTURE_EXPR_15]], align 8 +// CHECK2-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_15]], align 8 +// CHECK2-NEXT: [[ADD25:%.*]] = add nsw i64 [[TMP13]], 1 +// CHECK2-NEXT: store i64 [[ADD25]], ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[TMP14:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_7]], align 8 +// CHECK2-NEXT: [[ADD27:%.*]] = add nsw i64 [[TMP14]], 1 +// CHECK2-NEXT: store i64 [[ADD27]], ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[TMP15:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[SUB29:%.*]] = sub nsw i64 [[TMP15]], 0 +// CHECK2-NEXT: [[DIV30:%.*]] = sdiv i64 [[SUB29]], 1 +// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i64 128, [[DIV30]] +// CHECK2-NEXT: [[TMP16:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB31:%.*]] = sub nsw i64 [[TMP16]], 0 +// CHECK2-NEXT: [[DIV32:%.*]] = sdiv i64 [[SUB31]], 1 +// CHECK2-NEXT: [[MUL33:%.*]] = mul nsw i64 [[MUL]], [[DIV32]] +// CHECK2-NEXT: [[MUL34:%.*]] = mul nsw i64 [[MUL33]], 128 +// CHECK2-NEXT: [[SUB35:%.*]] = sub nsw i64 [[MUL34]], 1 +// CHECK2-NEXT: store i64 [[SUB35]], ptr [[DOTCAPTURE_EXPR_28]], align 8 +// CHECK2-NEXT: store i32 0, ptr [[I]], align 4 +// CHECK2-NEXT: store i64 0, ptr [[DOTPERMUTED_0_IV___BEGIN4]], align 8 +// CHECK2-NEXT: store i64 0, ptr [[DOTPERMUTED_1_IV___BEGIN3]], align 8 +// CHECK2-NEXT: store i32 0, ptr [[J]], align 4 +// CHECK2-NEXT: [[TMP17:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[CMP:%.*]] = icmp slt i64 0, [[TMP17]] +// CHECK2-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[OMP_PRECOND_END:%.*]] +// CHECK2: land.lhs.true: +// CHECK2-NEXT: [[TMP18:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[CMP36:%.*]] = icmp slt i64 0, [[TMP18]] +// CHECK2-NEXT: br i1 [[CMP36]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END]] +// CHECK2: omp.precond.then: +// CHECK2-NEXT: store i64 0, ptr [[DOTOMP_LB]], align 8 +// CHECK2-NEXT: [[TMP19:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_28]], align 8 +// CHECK2-NEXT: store i64 [[TMP19]], ptr [[DOTOMP_UB]], align 8 +// CHECK2-NEXT: store i64 1, ptr [[DOTOMP_STRIDE]], align 8 +// CHECK2-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK2-NEXT: call void @__kmpc_for_static_init_8(ptr @[[GLOB1:[0-9]+]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i64 1, i64 1) +// CHECK2-NEXT: [[TMP20:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8 +// CHECK2-NEXT: [[TMP21:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_28]], align 8 +// CHECK2-NEXT: [[CMP41:%.*]] = icmp sgt i64 [[TMP20]], [[TMP21]] +// CHECK2-NEXT: br i1 [[CMP41]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK2: cond.true: +// CHECK2-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_28]], align 8 +// CHECK2-NEXT: br label [[COND_END:%.*]] +// CHECK2: cond.false: +// CHECK2-NEXT: [[TMP23:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8 +// CHECK2-NEXT: br label [[COND_END]] +// CHECK2: cond.end: +// CHECK2-NEXT: [[COND:%.*]] = phi i64 [ [[TMP22]], [[COND_TRUE]] ], [ [[TMP23]], [[COND_FALSE]] ] +// CHECK2-NEXT: store i64 [[COND]], ptr [[DOTOMP_UB]], align 8 +// CHECK2-NEXT: [[TMP24:%.*]] = load i64, ptr [[DOTOMP_LB]], align 8 +// CHECK2-NEXT: store i64 [[TMP24]], ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK2: omp.inner.for.cond: +// CHECK2-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP26:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8 +// CHECK2-NEXT: [[CMP42:%.*]] = icmp sle i64 [[TMP25]], [[TMP26]] +// CHECK2-NEXT: br i1 [[CMP42]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK2: omp.inner.for.body: +// CHECK2-NEXT: [[TMP27:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP28:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[SUB43:%.*]] = sub nsw i64 [[TMP28]], 0 +// CHECK2-NEXT: [[DIV44:%.*]] = sdiv i64 [[SUB43]], 1 +// CHECK2-NEXT: [[MUL45:%.*]] = mul nsw i64 1, [[DIV44]] +// CHECK2-NEXT: [[TMP29:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB46:%.*]] = sub nsw i64 [[TMP29]], 0 +// CHECK2-NEXT: [[DIV47:%.*]] = sdiv i64 [[SUB46]], 1 +// CHECK2-NEXT: [[MUL48:%.*]] = mul nsw i64 [[MUL45]], [[DIV47]] +// CHECK2-NEXT: [[MUL49:%.*]] = mul nsw i64 [[MUL48]], 128 +// CHECK2-NEXT: [[DIV50:%.*]] = sdiv i64 [[TMP27]], [[MUL49]] +// CHECK2-NEXT: [[MUL51:%.*]] = mul nsw i64 [[DIV50]], 1 +// CHECK2-NEXT: [[ADD52:%.*]] = add nsw i64 0, [[MUL51]] +// CHECK2-NEXT: [[CONV:%.*]] = trunc i64 [[ADD52]] to i32 +// CHECK2-NEXT: store i32 [[CONV]], ptr [[I37]], align 4 +// CHECK2-NEXT: [[TMP30:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP31:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP32:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[SUB53:%.*]] = sub nsw i64 [[TMP32]], 0 +// CHECK2-NEXT: [[DIV54:%.*]] = sdiv i64 [[SUB53]], 1 +// CHECK2-NEXT: [[MUL55:%.*]] = mul nsw i64 1, [[DIV54]] +// CHECK2-NEXT: [[TMP33:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB56:%.*]] = sub nsw i64 [[TMP33]], 0 +// CHECK2-NEXT: [[DIV57:%.*]] = sdiv i64 [[SUB56]], 1 +// CHECK2-NEXT: [[MUL58:%.*]] = mul nsw i64 [[MUL55]], [[DIV57]] +// CHECK2-NEXT: [[MUL59:%.*]] = mul nsw i64 [[MUL58]], 128 +// CHECK2-NEXT: [[DIV60:%.*]] = sdiv i64 [[TMP31]], [[MUL59]] +// CHECK2-NEXT: [[TMP34:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[SUB61:%.*]] = sub nsw i64 [[TMP34]], 0 +// CHECK2-NEXT: [[DIV62:%.*]] = sdiv i64 [[SUB61]], 1 +// CHECK2-NEXT: [[MUL63:%.*]] = mul nsw i64 1, [[DIV62]] +// CHECK2-NEXT: [[TMP35:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB64:%.*]] = sub nsw i64 [[TMP35]], 0 +// CHECK2-NEXT: [[DIV65:%.*]] = sdiv i64 [[SUB64]], 1 +// CHECK2-NEXT: [[MUL66:%.*]] = mul nsw i64 [[MUL63]], [[DIV65]] +// CHECK2-NEXT: [[MUL67:%.*]] = mul nsw i64 [[MUL66]], 128 +// CHECK2-NEXT: [[MUL68:%.*]] = mul nsw i64 [[DIV60]], [[MUL67]] +// CHECK2-NEXT: [[SUB69:%.*]] = sub nsw i64 [[TMP30]], [[MUL68]] +// CHECK2-NEXT: [[TMP36:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB70:%.*]] = sub nsw i64 [[TMP36]], 0 +// CHECK2-NEXT: [[DIV71:%.*]] = sdiv i64 [[SUB70]], 1 +// CHECK2-NEXT: [[MUL72:%.*]] = mul nsw i64 1, [[DIV71]] +// CHECK2-NEXT: [[MUL73:%.*]] = mul nsw i64 [[MUL72]], 128 +// CHECK2-NEXT: [[DIV74:%.*]] = sdiv i64 [[SUB69]], [[MUL73]] +// CHECK2-NEXT: [[MUL75:%.*]] = mul nsw i64 [[DIV74]], 1 +// CHECK2-NEXT: [[ADD76:%.*]] = add nsw i64 0, [[MUL75]] +// CHECK2-NEXT: store i64 [[ADD76]], ptr [[DOTPERMUTED_0_IV___BEGIN438]], align 8 +// CHECK2-NEXT: [[TMP37:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP38:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP39:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[SUB77:%.*]] = sub nsw i64 [[TMP39]], 0 +// CHECK2-NEXT: [[DIV78:%.*]] = sdiv i64 [[SUB77]], 1 +// CHECK2-NEXT: [[MUL79:%.*]] = mul nsw i64 1, [[DIV78]] +// CHECK2-NEXT: [[TMP40:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB80:%.*]] = sub nsw i64 [[TMP40]], 0 +// CHECK2-NEXT: [[DIV81:%.*]] = sdiv i64 [[SUB80]], 1 +// CHECK2-NEXT: [[MUL82:%.*]] = mul nsw i64 [[MUL79]], [[DIV81]] +// CHECK2-NEXT: [[MUL83:%.*]] = mul nsw i64 [[MUL82]], 128 +// CHECK2-NEXT: [[DIV84:%.*]] = sdiv i64 [[TMP38]], [[MUL83]] +// CHECK2-NEXT: [[TMP41:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[SUB85:%.*]] = sub nsw i64 [[TMP41]], 0 +// CHECK2-NEXT: [[DIV86:%.*]] = sdiv i64 [[SUB85]], 1 +// CHECK2-NEXT: [[MUL87:%.*]] = mul nsw i64 1, [[DIV86]] +// CHECK2-NEXT: [[TMP42:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB88:%.*]] = sub nsw i64 [[TMP42]], 0 +// CHECK2-NEXT: [[DIV89:%.*]] = sdiv i64 [[SUB88]], 1 +// CHECK2-NEXT: [[MUL90:%.*]] = mul nsw i64 [[MUL87]], [[DIV89]] +// CHECK2-NEXT: [[MUL91:%.*]] = mul nsw i64 [[MUL90]], 128 +// CHECK2-NEXT: [[MUL92:%.*]] = mul nsw i64 [[DIV84]], [[MUL91]] +// CHECK2-NEXT: [[SUB93:%.*]] = sub nsw i64 [[TMP37]], [[MUL92]] +// CHECK2-NEXT: [[TMP43:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP44:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP45:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[SUB94:%.*]] = sub nsw i64 [[TMP45]], 0 +// CHECK2-NEXT: [[DIV95:%.*]] = sdiv i64 [[SUB94]], 1 +// CHECK2-NEXT: [[MUL96:%.*]] = mul nsw i64 1, [[DIV95]] +// CHECK2-NEXT: [[TMP46:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB97:%.*]] = sub nsw i64 [[TMP46]], 0 +// CHECK2-NEXT: [[DIV98:%.*]] = sdiv i64 [[SUB97]], 1 +// CHECK2-NEXT: [[MUL99:%.*]] = mul nsw i64 [[MUL96]], [[DIV98]] +// CHECK2-NEXT: [[MUL100:%.*]] = mul nsw i64 [[MUL99]], 128 +// CHECK2-NEXT: [[DIV101:%.*]] = sdiv i64 [[TMP44]], [[MUL100]] +// CHECK2-NEXT: [[TMP47:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[SUB102:%.*]] = sub nsw i64 [[TMP47]], 0 +// CHECK2-NEXT: [[DIV103:%.*]] = sdiv i64 [[SUB102]], 1 +// CHECK2-NEXT: [[MUL104:%.*]] = mul nsw i64 1, [[DIV103]] +// CHECK2-NEXT: [[TMP48:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB105:%.*]] = sub nsw i64 [[TMP48]], 0 +// CHECK2-NEXT: [[DIV106:%.*]] = sdiv i64 [[SUB105]], 1 +// CHECK2-NEXT: [[MUL107:%.*]] = mul nsw i64 [[MUL104]], [[DIV106]] +// CHECK2-NEXT: [[MUL108:%.*]] = mul nsw i64 [[MUL107]], 128 +// CHECK2-NEXT: [[MUL109:%.*]] = mul nsw i64 [[DIV101]], [[MUL108]] +// CHECK2-NEXT: [[SUB110:%.*]] = sub nsw i64 [[TMP43]], [[MUL109]] +// CHECK2-NEXT: [[TMP49:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB111:%.*]] = sub nsw i64 [[TMP49]], 0 +// CHECK2-NEXT: [[DIV112:%.*]] = sdiv i64 [[SUB111]], 1 +// CHECK2-NEXT: [[MUL113:%.*]] = mul nsw i64 1, [[DIV112]] +// CHECK2-NEXT: [[MUL114:%.*]] = mul nsw i64 [[MUL113]], 128 +// CHECK2-NEXT: [[DIV115:%.*]] = sdiv i64 [[SUB110]], [[MUL114]] +// CHECK2-NEXT: [[TMP50:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB116:%.*]] = sub nsw i64 [[TMP50]], 0 +// CHECK2-NEXT: [[DIV117:%.*]] = sdiv i64 [[SUB116]], 1 +// CHECK2-NEXT: [[MUL118:%.*]] = mul nsw i64 1, [[DIV117]] +// CHECK2-NEXT: [[MUL119:%.*]] = mul nsw i64 [[MUL118]], 128 +// CHECK2-NEXT: [[MUL120:%.*]] = mul nsw i64 [[DIV115]], [[MUL119]] +// CHECK2-NEXT: [[SUB121:%.*]] = sub nsw i64 [[SUB93]], [[MUL120]] +// CHECK2-NEXT: [[DIV122:%.*]] = sdiv i64 [[SUB121]], 128 +// CHECK2-NEXT: [[MUL123:%.*]] = mul nsw i64 [[DIV122]], 1 +// CHECK2-NEXT: [[ADD124:%.*]] = add nsw i64 0, [[MUL123]] +// CHECK2-NEXT: store i64 [[ADD124]], ptr [[DOTPERMUTED_1_IV___BEGIN339]], align 8 +// CHECK2-NEXT: [[TMP51:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP52:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP53:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[SUB125:%.*]] = sub nsw i64 [[TMP53]], 0 +// CHECK2-NEXT: [[DIV126:%.*]] = sdiv i64 [[SUB125]], 1 +// CHECK2-NEXT: [[MUL127:%.*]] = mul nsw i64 1, [[DIV126]] +// CHECK2-NEXT: [[TMP54:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB128:%.*]] = sub nsw i64 [[TMP54]], 0 +// CHECK2-NEXT: [[DIV129:%.*]] = sdiv i64 [[SUB128]], 1 +// CHECK2-NEXT: [[MUL130:%.*]] = mul nsw i64 [[MUL127]], [[DIV129]] +// CHECK2-NEXT: [[MUL131:%.*]] = mul nsw i64 [[MUL130]], 128 +// CHECK2-NEXT: [[DIV132:%.*]] = sdiv i64 [[TMP52]], [[MUL131]] +// CHECK2-NEXT: [[TMP55:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[SUB133:%.*]] = sub nsw i64 [[TMP55]], 0 +// CHECK2-NEXT: [[DIV134:%.*]] = sdiv i64 [[SUB133]], 1 +// CHECK2-NEXT: [[MUL135:%.*]] = mul nsw i64 1, [[DIV134]] +// CHECK2-NEXT: [[TMP56:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB136:%.*]] = sub nsw i64 [[TMP56]], 0 +// CHECK2-NEXT: [[DIV137:%.*]] = sdiv i64 [[SUB136]], 1 +// CHECK2-NEXT: [[MUL138:%.*]] = mul nsw i64 [[MUL135]], [[DIV137]] +// CHECK2-NEXT: [[MUL139:%.*]] = mul nsw i64 [[MUL138]], 128 +// CHECK2-NEXT: [[MUL140:%.*]] = mul nsw i64 [[DIV132]], [[MUL139]] +// CHECK2-NEXT: [[SUB141:%.*]] = sub nsw i64 [[TMP51]], [[MUL140]] +// CHECK2-NEXT: [[TMP57:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP58:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP59:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[SUB142:%.*]] = sub nsw i64 [[TMP59]], 0 +// CHECK2-NEXT: [[DIV143:%.*]] = sdiv i64 [[SUB142]], 1 +// CHECK2-NEXT: [[MUL144:%.*]] = mul nsw i64 1, [[DIV143]] +// CHECK2-NEXT: [[TMP60:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB145:%.*]] = sub nsw i64 [[TMP60]], 0 +// CHECK2-NEXT: [[DIV146:%.*]] = sdiv i64 [[SUB145]], 1 +// CHECK2-NEXT: [[MUL147:%.*]] = mul nsw i64 [[MUL144]], [[DIV146]] +// CHECK2-NEXT: [[MUL148:%.*]] = mul nsw i64 [[MUL147]], 128 +// CHECK2-NEXT: [[DIV149:%.*]] = sdiv i64 [[TMP58]], [[MUL148]] +// CHECK2-NEXT: [[TMP61:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[SUB150:%.*]] = sub nsw i64 [[TMP61]], 0 +// CHECK2-NEXT: [[DIV151:%.*]] = sdiv i64 [[SUB150]], 1 +// CHECK2-NEXT: [[MUL152:%.*]] = mul nsw i64 1, [[DIV151]] +// CHECK2-NEXT: [[TMP62:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB153:%.*]] = sub nsw i64 [[TMP62]], 0 +// CHECK2-NEXT: [[DIV154:%.*]] = sdiv i64 [[SUB153]], 1 +// CHECK2-NEXT: [[MUL155:%.*]] = mul nsw i64 [[MUL152]], [[DIV154]] +// CHECK2-NEXT: [[MUL156:%.*]] = mul nsw i64 [[MUL155]], 128 +// CHECK2-NEXT: [[MUL157:%.*]] = mul nsw i64 [[DIV149]], [[MUL156]] +// CHECK2-NEXT: [[SUB158:%.*]] = sub nsw i64 [[TMP57]], [[MUL157]] +// CHECK2-NEXT: [[TMP63:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB159:%.*]] = sub nsw i64 [[TMP63]], 0 +// CHECK2-NEXT: [[DIV160:%.*]] = sdiv i64 [[SUB159]], 1 +// CHECK2-NEXT: [[MUL161:%.*]] = mul nsw i64 1, [[DIV160]] +// CHECK2-NEXT: [[MUL162:%.*]] = mul nsw i64 [[MUL161]], 128 +// CHECK2-NEXT: [[DIV163:%.*]] = sdiv i64 [[SUB158]], [[MUL162]] +// CHECK2-NEXT: [[TMP64:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB164:%.*]] = sub nsw i64 [[TMP64]], 0 +// CHECK2-NEXT: [[DIV165:%.*]] = sdiv i64 [[SUB164]], 1 +// CHECK2-NEXT: [[MUL166:%.*]] = mul nsw i64 1, [[DIV165]] +// CHECK2-NEXT: [[MUL167:%.*]] = mul nsw i64 [[MUL166]], 128 +// CHECK2-NEXT: [[MUL168:%.*]] = mul nsw i64 [[DIV163]], [[MUL167]] +// CHECK2-NEXT: [[SUB169:%.*]] = sub nsw i64 [[SUB141]], [[MUL168]] +// CHECK2-NEXT: [[TMP65:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP66:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP67:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[SUB170:%.*]] = sub nsw i64 [[TMP67]], 0 +// CHECK2-NEXT: [[DIV171:%.*]] = sdiv i64 [[SUB170]], 1 +// CHECK2-NEXT: [[MUL172:%.*]] = mul nsw i64 1, [[DIV171]] +// CHECK2-NEXT: [[TMP68:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB173:%.*]] = sub nsw i64 [[TMP68]], 0 +// CHECK2-NEXT: [[DIV174:%.*]] = sdiv i64 [[SUB173]], 1 +// CHECK2-NEXT: [[MUL175:%.*]] = mul nsw i64 [[MUL172]], [[DIV174]] +// CHECK2-NEXT: [[MUL176:%.*]] = mul nsw i64 [[MUL175]], 128 +// CHECK2-NEXT: [[DIV177:%.*]] = sdiv i64 [[TMP66]], [[MUL176]] +// CHECK2-NEXT: [[TMP69:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[SUB178:%.*]] = sub nsw i64 [[TMP69]], 0 +// CHECK2-NEXT: [[DIV179:%.*]] = sdiv i64 [[SUB178]], 1 +// CHECK2-NEXT: [[MUL180:%.*]] = mul nsw i64 1, [[DIV179]] +// CHECK2-NEXT: [[TMP70:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB181:%.*]] = sub nsw i64 [[TMP70]], 0 +// CHECK2-NEXT: [[DIV182:%.*]] = sdiv i64 [[SUB181]], 1 +// CHECK2-NEXT: [[MUL183:%.*]] = mul nsw i64 [[MUL180]], [[DIV182]] +// CHECK2-NEXT: [[MUL184:%.*]] = mul nsw i64 [[MUL183]], 128 +// CHECK2-NEXT: [[MUL185:%.*]] = mul nsw i64 [[DIV177]], [[MUL184]] +// CHECK2-NEXT: [[SUB186:%.*]] = sub nsw i64 [[TMP65]], [[MUL185]] +// CHECK2-NEXT: [[TMP71:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP72:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP73:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[SUB187:%.*]] = sub nsw i64 [[TMP73]], 0 +// CHECK2-NEXT: [[DIV188:%.*]] = sdiv i64 [[SUB187]], 1 +// CHECK2-NEXT: [[MUL189:%.*]] = mul nsw i64 1, [[DIV188]] +// CHECK2-NEXT: [[TMP74:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB190:%.*]] = sub nsw i64 [[TMP74]], 0 +// CHECK2-NEXT: [[DIV191:%.*]] = sdiv i64 [[SUB190]], 1 +// CHECK2-NEXT: [[MUL192:%.*]] = mul nsw i64 [[MUL189]], [[DIV191]] +// CHECK2-NEXT: [[MUL193:%.*]] = mul nsw i64 [[MUL192]], 128 +// CHECK2-NEXT: [[DIV194:%.*]] = sdiv i64 [[TMP72]], [[MUL193]] +// CHECK2-NEXT: [[TMP75:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_24]], align 8 +// CHECK2-NEXT: [[SUB195:%.*]] = sub nsw i64 [[TMP75]], 0 +// CHECK2-NEXT: [[DIV196:%.*]] = sdiv i64 [[SUB195]], 1 +// CHECK2-NEXT: [[MUL197:%.*]] = mul nsw i64 1, [[DIV196]] +// CHECK2-NEXT: [[TMP76:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB198:%.*]] = sub nsw i64 [[TMP76]], 0 +// CHECK2-NEXT: [[DIV199:%.*]] = sdiv i64 [[SUB198]], 1 +// CHECK2-NEXT: [[MUL200:%.*]] = mul nsw i64 [[MUL197]], [[DIV199]] +// CHECK2-NEXT: [[MUL201:%.*]] = mul nsw i64 [[MUL200]], 128 +// CHECK2-NEXT: [[MUL202:%.*]] = mul nsw i64 [[DIV194]], [[MUL201]] +// CHECK2-NEXT: [[SUB203:%.*]] = sub nsw i64 [[TMP71]], [[MUL202]] +// CHECK2-NEXT: [[TMP77:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB204:%.*]] = sub nsw i64 [[TMP77]], 0 +// CHECK2-NEXT: [[DIV205:%.*]] = sdiv i64 [[SUB204]], 1 +// CHECK2-NEXT: [[MUL206:%.*]] = mul nsw i64 1, [[DIV205]] +// CHECK2-NEXT: [[MUL207:%.*]] = mul nsw i64 [[MUL206]], 128 +// CHECK2-NEXT: [[DIV208:%.*]] = sdiv i64 [[SUB203]], [[MUL207]] +// CHECK2-NEXT: [[TMP78:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_26]], align 8 +// CHECK2-NEXT: [[SUB209:%.*]] = sub nsw i64 [[TMP78]], 0 +// CHECK2-NEXT: [[DIV210:%.*]] = sdiv i64 [[SUB209]], 1 +// CHECK2-NEXT: [[MUL211:%.*]] = mul nsw i64 1, [[DIV210]] +// CHECK2-NEXT: [[MUL212:%.*]] = mul nsw i64 [[MUL211]], 128 +// CHECK2-NEXT: [[MUL213:%.*]] = mul nsw i64 [[DIV208]], [[MUL212]] +// CHECK2-NEXT: [[SUB214:%.*]] = sub nsw i64 [[SUB186]], [[MUL213]] +// CHECK2-NEXT: [[DIV215:%.*]] = sdiv i64 [[SUB214]], 128 +// CHECK2-NEXT: [[MUL216:%.*]] = mul nsw i64 [[DIV215]], 128 +// CHECK2-NEXT: [[SUB217:%.*]] = sub nsw i64 [[SUB169]], [[MUL216]] +// CHECK2-NEXT: [[MUL218:%.*]] = mul nsw i64 [[SUB217]], 1 +// CHECK2-NEXT: [[ADD219:%.*]] = add nsw i64 0, [[MUL218]] +// CHECK2-NEXT: [[CONV220:%.*]] = trunc i64 [[ADD219]] to i32 +// CHECK2-NEXT: store i32 [[CONV220]], ptr [[J40]], align 4 +// CHECK2-NEXT: [[TMP79:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_12]], align 8 +// CHECK2-NEXT: [[TMP80:%.*]] = load i64, ptr [[DOTPERMUTED_0_IV___BEGIN438]], align 8 +// CHECK2-NEXT: [[MUL221:%.*]] = mul nsw i64 [[TMP80]], 1 +// CHECK2-NEXT: [[ADD_PTR222:%.*]] = getelementptr inbounds double, ptr [[TMP79]], i64 [[MUL221]] +// CHECK2-NEXT: store ptr [[ADD_PTR222]], ptr [[__BEGIN4]], align 8 +// CHECK2-NEXT: [[TMP81:%.*]] = load ptr, ptr [[__BEGIN4]], align 8 +// CHECK2-NEXT: store ptr [[TMP81]], ptr [[BB]], align 8 +// CHECK2-NEXT: [[TMP82:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[TMP83:%.*]] = load i64, ptr [[DOTPERMUTED_1_IV___BEGIN339]], align 8 +// CHECK2-NEXT: [[MUL223:%.*]] = mul nsw i64 [[TMP83]], 1 +// CHECK2-NEXT: [[ADD_PTR224:%.*]] = getelementptr inbounds double, ptr [[TMP82]], i64 [[MUL223]] +// CHECK2-NEXT: store ptr [[ADD_PTR224]], ptr [[__BEGIN3]], align 8 +// CHECK2-NEXT: [[TMP84:%.*]] = load ptr, ptr [[__BEGIN3]], align 8 +// CHECK2-NEXT: [[TMP85:%.*]] = load double, ptr [[TMP84]], align 8 +// CHECK2-NEXT: store double [[TMP85]], ptr [[AA]], align 8 +// CHECK2-NEXT: [[TMP86:%.*]] = load i32, ptr [[I37]], align 4 +// CHECK2-NEXT: [[TMP87:%.*]] = load double, ptr [[C]], align 8 +// CHECK2-NEXT: [[TMP88:%.*]] = load double, ptr [[AA]], align 8 +// CHECK2-NEXT: [[TMP89:%.*]] = load double, ptr [[D]], align 8 +// CHECK2-NEXT: [[TMP90:%.*]] = load ptr, ptr [[BB]], align 8 +// CHECK2-NEXT: [[TMP91:%.*]] = load double, ptr [[TMP90]], align 8 +// CHECK2-NEXT: [[TMP92:%.*]] = load i32, ptr [[J40]], align 4 +// CHECK2-NEXT: call void (...) @body(i32 noundef [[TMP86]], double noundef [[TMP87]], double noundef [[TMP88]], double noundef [[TMP89]], double noundef [[TMP91]], i32 noundef [[TMP92]]) +// CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK2: omp.body.continue: +// CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK2: omp.inner.for.inc: +// CHECK2-NEXT: [[TMP93:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[ADD225:%.*]] = add nsw i64 [[TMP93]], 1 +// CHECK2-NEXT: store i64 [[ADD225]], ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK2: omp.inner.for.end: +// CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK2: omp.loop.exit: +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]]) +// CHECK2-NEXT: br label [[OMP_PRECOND_END]] +// CHECK2: omp.precond.end: +// CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3:[0-9]+]], i32 [[TMP0]]) +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@foo2 +// CHECK2-SAME: (i32 noundef [[START1:%.*]], i32 noundef [[START2:%.*]], i32 noundef [[END1:%.*]], i32 noundef [[END2:%.*]], i32 noundef [[STEP1:%.*]], i32 noundef [[STEP2:%.*]]) #[[ATTR0]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[START1_ADDR:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[START2_ADDR:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[END1_ADDR:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[END2_ADDR:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[STEP1_ADDR:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[STEP2_ADDR:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTNEW_STEP:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_2:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[J:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_5:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_6:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTNEW_STEP7:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_8:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTPERMUTED_0_IV_J:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTPERMUTED_1_IV_I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: store i32 [[START1]], ptr [[START1_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[START2]], ptr [[START2_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[END1]], ptr [[END1_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[END2]], ptr [[END2_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[STEP1]], ptr [[STEP1_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[STEP2]], ptr [[STEP2_ADDR]], align 4 +// CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[START1_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP0]], ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[START1_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[END1_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP2]], ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr [[STEP1_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP3]], ptr [[DOTNEW_STEP]], align 4 +// CHECK2-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK2-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK2-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], [[TMP5]] +// CHECK2-NEXT: [[SUB3:%.*]] = sub i32 [[SUB]], 1 +// CHECK2-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 +// CHECK2-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], [[TMP6]] +// CHECK2-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 +// CHECK2-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], [[TMP7]] +// CHECK2-NEXT: [[SUB4:%.*]] = sub i32 [[DIV]], 1 +// CHECK2-NEXT: store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK2-NEXT: [[TMP8:%.*]] = load i32, ptr [[START2_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP8]], ptr [[J]], align 4 +// CHECK2-NEXT: [[TMP9:%.*]] = load i32, ptr [[START2_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP9]], ptr [[DOTCAPTURE_EXPR_5]], align 4 +// CHECK2-NEXT: [[TMP10:%.*]] = load i32, ptr [[END2_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP10]], ptr [[DOTCAPTURE_EXPR_6]], align 4 +// CHECK2-NEXT: [[TMP11:%.*]] = load i32, ptr [[STEP2_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP11]], ptr [[DOTNEW_STEP7]], align 4 +// CHECK2-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4 +// CHECK2-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_5]], align 4 +// CHECK2-NEXT: [[SUB9:%.*]] = sub i32 [[TMP12]], [[TMP13]] +// CHECK2-NEXT: [[SUB10:%.*]] = sub i32 [[SUB9]], 1 +// CHECK2-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTNEW_STEP7]], align 4 +// CHECK2-NEXT: [[ADD11:%.*]] = add i32 [[SUB10]], [[TMP14]] +// CHECK2-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTNEW_STEP7]], align 4 +// CHECK2-NEXT: [[DIV12:%.*]] = udiv i32 [[ADD11]], [[TMP15]] +// CHECK2-NEXT: [[SUB13:%.*]] = sub i32 [[DIV12]], 1 +// CHECK2-NEXT: store i32 [[SUB13]], ptr [[DOTCAPTURE_EXPR_8]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK2-NEXT: br label [[FOR_COND:%.*]] +// CHECK2: for.cond: +// CHECK2-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK2-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_8]], align 4 +// CHECK2-NEXT: [[ADD14:%.*]] = add i32 [[TMP17]], 1 +// CHECK2-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP16]], [[ADD14]] +// CHECK2-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END24:%.*]] +// CHECK2: for.body: +// CHECK2-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_5]], align 4 +// CHECK2-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK2-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTNEW_STEP7]], align 4 +// CHECK2-NEXT: [[MUL:%.*]] = mul i32 [[TMP19]], [[TMP20]] +// CHECK2-NEXT: [[ADD15:%.*]] = add i32 [[TMP18]], [[MUL]] +// CHECK2-NEXT: store i32 [[ADD15]], ptr [[J]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK2-NEXT: br label [[FOR_COND16:%.*]] +// CHECK2: for.cond16: +// CHECK2-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK2-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK2-NEXT: [[ADD17:%.*]] = add i32 [[TMP22]], 1 +// CHECK2-NEXT: [[CMP18:%.*]] = icmp ult i32 [[TMP21]], [[ADD17]] +// CHECK2-NEXT: br i1 [[CMP18]], label [[FOR_BODY19:%.*]], label [[FOR_END:%.*]] +// CHECK2: for.body19: +// CHECK2-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK2-NEXT: [[TMP24:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK2-NEXT: [[TMP25:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 +// CHECK2-NEXT: [[MUL20:%.*]] = mul i32 [[TMP24]], [[TMP25]] +// CHECK2-NEXT: [[ADD21:%.*]] = add i32 [[TMP23]], [[MUL20]] +// CHECK2-NEXT: store i32 [[ADD21]], ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP26:%.*]] = load i32, ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP27:%.*]] = load i32, ptr [[J]], align 4 +// CHECK2-NEXT: call void (...) @body(i32 noundef [[TMP26]], i32 noundef [[TMP27]]) +// CHECK2-NEXT: br label [[FOR_INC:%.*]] +// CHECK2: for.inc: +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK2-NEXT: [[INC:%.*]] = add i32 [[TMP28]], 1 +// CHECK2-NEXT: store i32 [[INC]], ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK2-NEXT: br label [[FOR_COND16]], !llvm.loop [[LOOP3:![0-9]+]] +// CHECK2: for.end: +// CHECK2-NEXT: br label [[FOR_INC22:%.*]] +// CHECK2: for.inc22: +// CHECK2-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK2-NEXT: [[INC23:%.*]] = add i32 [[TMP29]], 1 +// CHECK2-NEXT: store i32 [[INC23]], ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP5:![0-9]+]] +// CHECK2: for.end24: +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@foo3 +// CHECK2-SAME: () #[[ATTR0]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[J:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTPERMUTED_0_IV_J:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTPERMUTED_1_IV_I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]]) +// CHECK2-NEXT: store i32 7, ptr [[I]], align 4 +// CHECK2-NEXT: store i32 7, ptr [[J]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK2-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 3 +// CHECK2-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK2: cond.true: +// CHECK2-NEXT: br label [[COND_END:%.*]] +// CHECK2: cond.false: +// CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: br label [[COND_END]] +// CHECK2: cond.end: +// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ 3, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ] +// CHECK2-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK2-NEXT: store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK2: omp.inner.for.cond: +// CHECK2-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]] +// CHECK2-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK2: omp.inner.for.body: +// CHECK2-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP6]], 1 +// CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK2-NEXT: store i32 [[ADD]], ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK2-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK2-NEXT: [[MUL2:%.*]] = mul nsw i32 [[TMP7]], 3 +// CHECK2-NEXT: [[ADD3:%.*]] = add nsw i32 7, [[MUL2]] +// CHECK2-NEXT: store i32 [[ADD3]], ptr [[J]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK2-NEXT: br label [[FOR_COND:%.*]] +// CHECK2: for.cond: +// CHECK2-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK2-NEXT: [[CMP4:%.*]] = icmp slt i32 [[TMP8]], 4 +// CHECK2-NEXT: br i1 [[CMP4]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +// CHECK2: for.body: +// CHECK2-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK2-NEXT: [[MUL5:%.*]] = mul nsw i32 [[TMP9]], 3 +// CHECK2-NEXT: [[ADD6:%.*]] = add nsw i32 7, [[MUL5]] +// CHECK2-NEXT: store i32 [[ADD6]], ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP10:%.*]] = load i32, ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP11:%.*]] = load i32, ptr [[J]], align 4 +// CHECK2-NEXT: call void (...) @body(i32 noundef [[TMP10]], i32 noundef [[TMP11]]) +// CHECK2-NEXT: br label [[FOR_INC:%.*]] +// CHECK2: for.inc: +// CHECK2-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP12]], 1 +// CHECK2-NEXT: store i32 [[INC]], ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]] +// CHECK2: for.end: +// CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK2: omp.body.continue: +// CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK2: omp.inner.for.inc: +// CHECK2-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP13]], 1 +// CHECK2-NEXT: store i32 [[ADD7]], ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK2: omp.inner.for.end: +// CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK2: omp.loop.exit: +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]]) +// CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]]) +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@foo4 +// CHECK2-SAME: () #[[ATTR0]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[J:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[K:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTPERMUTED_0_IV_J:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTPERMUTED_1_IV_I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]]) +// CHECK2-NEXT: store i32 7, ptr [[I]], align 4 +// CHECK2-NEXT: store i32 7, ptr [[J]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK2-NEXT: store i32 15, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK2-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 15 +// CHECK2-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK2: cond.true: +// CHECK2-NEXT: br label [[COND_END:%.*]] +// CHECK2: cond.false: +// CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: br label [[COND_END]] +// CHECK2: cond.end: +// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ 15, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ] +// CHECK2-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK2-NEXT: store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK2: omp.inner.for.cond: +// CHECK2-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]] +// CHECK2-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK2: omp.inner.for.body: +// CHECK2-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP6]], 4 +// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[DIV]], 3 +// CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 7, [[MUL]] +// CHECK2-NEXT: store i32 [[ADD]], ptr [[K]], align 4 +// CHECK2-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[DIV3:%.*]] = sdiv i32 [[TMP8]], 4 +// CHECK2-NEXT: [[MUL4:%.*]] = mul nsw i32 [[DIV3]], 4 +// CHECK2-NEXT: [[SUB:%.*]] = sub nsw i32 [[TMP7]], [[MUL4]] +// CHECK2-NEXT: [[MUL5:%.*]] = mul nsw i32 [[SUB]], 1 +// CHECK2-NEXT: [[ADD6:%.*]] = add nsw i32 0, [[MUL5]] +// CHECK2-NEXT: store i32 [[ADD6]], ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK2-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], align 4 +// CHECK2-NEXT: [[MUL7:%.*]] = mul nsw i32 [[TMP9]], 3 +// CHECK2-NEXT: [[ADD8:%.*]] = add nsw i32 7, [[MUL7]] +// CHECK2-NEXT: store i32 [[ADD8]], ptr [[J]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK2-NEXT: br label [[FOR_COND:%.*]] +// CHECK2: for.cond: +// CHECK2-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK2-NEXT: [[CMP9:%.*]] = icmp slt i32 [[TMP10]], 4 +// CHECK2-NEXT: br i1 [[CMP9]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +// CHECK2: for.body: +// CHECK2-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK2-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP11]], 3 +// CHECK2-NEXT: [[ADD11:%.*]] = add nsw i32 7, [[MUL10]] +// CHECK2-NEXT: store i32 [[ADD11]], ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP12:%.*]] = load i32, ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP13:%.*]] = load i32, ptr [[J]], align 4 +// CHECK2-NEXT: call void (...) @body(i32 noundef [[TMP12]], i32 noundef [[TMP13]]) +// CHECK2-NEXT: br label [[FOR_INC:%.*]] +// CHECK2: for.inc: +// CHECK2-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP14]], 1 +// CHECK2-NEXT: store i32 [[INC]], ptr [[DOTPERMUTED_1_IV_I]], align 4 +// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP7:![0-9]+]] +// CHECK2: for.end: +// CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK2: omp.body.continue: +// CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK2: omp.inner.for.inc: +// CHECK2-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[ADD12:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK2-NEXT: store i32 [[ADD12]], ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK2: omp.inner.for.end: +// CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK2: omp.loop.exit: +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]]) +// CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]]) +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@foo6 +// CHECK2-SAME: () #[[ATTR0]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[_TMP3:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[J:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[K:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTPERMUTED_0_IV_K:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTPERMUTED_1_IV_J:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[L:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]]) +// CHECK2-NEXT: store i32 7, ptr [[J]], align 4 +// CHECK2-NEXT: store i32 7, ptr [[K]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK2-NEXT: store i32 255, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK2-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 255 +// CHECK2-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK2: cond.true: +// CHECK2-NEXT: br label [[COND_END:%.*]] +// CHECK2: cond.false: +// CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: br label [[COND_END]] +// CHECK2: cond.end: +// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ 255, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ] +// CHECK2-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK2-NEXT: store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK2: omp.inner.for.cond: +// CHECK2-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[CMP4:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]] +// CHECK2-NEXT: br i1 [[CMP4]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK2: omp.inner.for.body: +// CHECK2-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP6]], 64 +// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[DIV]], 3 +// CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 7, [[MUL]] +// CHECK2-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[DIV5:%.*]] = sdiv i32 [[TMP8]], 64 +// CHECK2-NEXT: [[MUL6:%.*]] = mul nsw i32 [[DIV5]], 64 +// CHECK2-NEXT: [[SUB:%.*]] = sub nsw i32 [[TMP7]], [[MUL6]] +// CHECK2-NEXT: [[DIV7:%.*]] = sdiv i32 [[SUB]], 16 +// CHECK2-NEXT: [[MUL8:%.*]] = mul nsw i32 [[DIV7]], 1 +// CHECK2-NEXT: [[ADD9:%.*]] = add nsw i32 0, [[MUL8]] +// CHECK2-NEXT: store i32 [[ADD9]], ptr [[DOTPERMUTED_0_IV_K]], align 4 +// CHECK2-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[DIV10:%.*]] = sdiv i32 [[TMP10]], 64 +// CHECK2-NEXT: [[MUL11:%.*]] = mul nsw i32 [[DIV10]], 64 +// CHECK2-NEXT: [[SUB12:%.*]] = sub nsw i32 [[TMP9]], [[MUL11]] +// CHECK2-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[DIV13:%.*]] = sdiv i32 [[TMP12]], 64 +// CHECK2-NEXT: [[MUL14:%.*]] = mul nsw i32 [[DIV13]], 64 +// CHECK2-NEXT: [[SUB15:%.*]] = sub nsw i32 [[TMP11]], [[MUL14]] +// CHECK2-NEXT: [[DIV16:%.*]] = sdiv i32 [[SUB15]], 16 +// CHECK2-NEXT: [[MUL17:%.*]] = mul nsw i32 [[DIV16]], 16 +// CHECK2-NEXT: [[SUB18:%.*]] = sub nsw i32 [[SUB12]], [[MUL17]] +// CHECK2-NEXT: [[DIV19:%.*]] = sdiv i32 [[SUB18]], 4 +// CHECK2-NEXT: [[MUL20:%.*]] = mul nsw i32 [[DIV19]], 1 +// CHECK2-NEXT: [[ADD21:%.*]] = add nsw i32 0, [[MUL20]] +// CHECK2-NEXT: store i32 [[ADD21]], ptr [[DOTPERMUTED_1_IV_J]], align 4 +// CHECK2-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[DIV22:%.*]] = sdiv i32 [[TMP14]], 64 +// CHECK2-NEXT: [[MUL23:%.*]] = mul nsw i32 [[DIV22]], 64 +// CHECK2-NEXT: [[SUB24:%.*]] = sub nsw i32 [[TMP13]], [[MUL23]] +// CHECK2-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[DIV25:%.*]] = sdiv i32 [[TMP16]], 64 +// CHECK2-NEXT: [[MUL26:%.*]] = mul nsw i32 [[DIV25]], 64 +// CHECK2-NEXT: [[SUB27:%.*]] = sub nsw i32 [[TMP15]], [[MUL26]] +// CHECK2-NEXT: [[DIV28:%.*]] = sdiv i32 [[SUB27]], 16 +// CHECK2-NEXT: [[MUL29:%.*]] = mul nsw i32 [[DIV28]], 16 +// CHECK2-NEXT: [[SUB30:%.*]] = sub nsw i32 [[SUB24]], [[MUL29]] +// CHECK2-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[DIV31:%.*]] = sdiv i32 [[TMP18]], 64 +// CHECK2-NEXT: [[MUL32:%.*]] = mul nsw i32 [[DIV31]], 64 +// CHECK2-NEXT: [[SUB33:%.*]] = sub nsw i32 [[TMP17]], [[MUL32]] +// CHECK2-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[DIV34:%.*]] = sdiv i32 [[TMP20]], 64 +// CHECK2-NEXT: [[MUL35:%.*]] = mul nsw i32 [[DIV34]], 64 +// CHECK2-NEXT: [[SUB36:%.*]] = sub nsw i32 [[TMP19]], [[MUL35]] +// CHECK2-NEXT: [[DIV37:%.*]] = sdiv i32 [[SUB36]], 16 +// CHECK2-NEXT: [[MUL38:%.*]] = mul nsw i32 [[DIV37]], 16 +// CHECK2-NEXT: [[SUB39:%.*]] = sub nsw i32 [[SUB33]], [[MUL38]] +// CHECK2-NEXT: [[DIV40:%.*]] = sdiv i32 [[SUB39]], 4 +// CHECK2-NEXT: [[MUL41:%.*]] = mul nsw i32 [[DIV40]], 4 +// CHECK2-NEXT: [[SUB42:%.*]] = sub nsw i32 [[SUB30]], [[MUL41]] +// CHECK2-NEXT: [[MUL43:%.*]] = mul nsw i32 [[SUB42]], 3 +// CHECK2-NEXT: [[ADD44:%.*]] = add nsw i32 7, [[MUL43]] +// CHECK2-NEXT: store i32 [[ADD44]], ptr [[L]], align 4 +// CHECK2-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_K]], align 4 +// CHECK2-NEXT: [[MUL45:%.*]] = mul nsw i32 [[TMP21]], 3 +// CHECK2-NEXT: [[ADD46:%.*]] = add nsw i32 7, [[MUL45]] +// CHECK2-NEXT: store i32 [[ADD46]], ptr [[K]], align 4 +// CHECK2-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_J]], align 4 +// CHECK2-NEXT: [[MUL47:%.*]] = mul nsw i32 [[TMP22]], 3 +// CHECK2-NEXT: [[ADD48:%.*]] = add nsw i32 7, [[MUL47]] +// CHECK2-NEXT: store i32 [[ADD48]], ptr [[J]], align 4 +// CHECK2-NEXT: [[TMP23:%.*]] = load i32, ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP24:%.*]] = load i32, ptr [[J]], align 4 +// CHECK2-NEXT: [[TMP25:%.*]] = load i32, ptr [[K]], align 4 +// CHECK2-NEXT: [[TMP26:%.*]] = load i32, ptr [[L]], align 4 +// CHECK2-NEXT: call void (...) @body(i32 noundef [[TMP23]], i32 noundef [[TMP24]], i32 noundef [[TMP25]], i32 noundef [[TMP26]]) +// CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK2: omp.body.continue: +// CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK2: omp.inner.for.inc: +// CHECK2-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[ADD49:%.*]] = add nsw i32 [[TMP27]], 1 +// CHECK2-NEXT: store i32 [[ADD49]], ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK2: omp.inner.for.end: +// CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK2: omp.loop.exit: +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]]) +// CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]]) +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@foo9 +// CHECK2-SAME: () #[[ATTR0]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[ARR:%.*]] = alloca [128 x double], align 16 +// CHECK2-NEXT: [[C:%.*]] = alloca double, align 8 +// CHECK2-NEXT: [[__RANGE2:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[__END2:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[__BEGIN2:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_3:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTPERMUTED_0_IV_I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTPERMUTED_1_IV___BEGIN2:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[V:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: store double 4.200000e+01, ptr [[C]], align 8 +// CHECK2-NEXT: store ptr [[ARR]], ptr [[__RANGE2]], align 8 +// CHECK2-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP0]], i64 0, i64 0 +// CHECK2-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 128 +// CHECK2-NEXT: store ptr [[ADD_PTR]], ptr [[__END2]], align 8 +// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP1]], i64 0, i64 0 +// CHECK2-NEXT: store ptr [[ARRAYDECAY1]], ptr [[__BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY2:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP2]], i64 0, i64 0 +// CHECK2-NEXT: store ptr [[ARRAYDECAY2]], ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__END2]], align 8 +// CHECK2-NEXT: store ptr [[TMP3]], ptr [[DOTCAPTURE_EXPR_3]], align 8 +// CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_3]], align 8 +// CHECK2-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[TMP4]] to i64 +// CHECK2-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[TMP5]] to i64 +// CHECK2-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]] +// CHECK2-NEXT: [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8 +// CHECK2-NEXT: [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1 +// CHECK2-NEXT: [[ADD:%.*]] = add nsw i64 [[SUB]], 1 +// CHECK2-NEXT: [[DIV:%.*]] = sdiv i64 [[ADD]], 1 +// CHECK2-NEXT: [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1 +// CHECK2-NEXT: store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK2-NEXT: store i32 0, ptr [[I]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTPERMUTED_0_IV_I]], align 4 +// CHECK2-NEXT: br label [[FOR_COND:%.*]] +// CHECK2: for.cond: +// CHECK2-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_I]], align 4 +// CHECK2-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP6]], 21 +// CHECK2-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END15:%.*]] +// CHECK2: for.body: +// CHECK2-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_I]], align 4 +// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 2 +// CHECK2-NEXT: [[ADD6:%.*]] = add nsw i32 0, [[MUL]] +// CHECK2-NEXT: store i32 [[ADD6]], ptr [[I]], align 4 +// CHECK2-NEXT: store i64 0, ptr [[DOTPERMUTED_1_IV___BEGIN2]], align 8 +// CHECK2-NEXT: br label [[FOR_COND7:%.*]] +// CHECK2: for.cond7: +// CHECK2-NEXT: [[TMP8:%.*]] = load i64, ptr [[DOTPERMUTED_1_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP9:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK2-NEXT: [[ADD8:%.*]] = add nsw i64 [[TMP9]], 1 +// CHECK2-NEXT: [[CMP9:%.*]] = icmp slt i64 [[TMP8]], [[ADD8]] +// CHECK2-NEXT: br i1 [[CMP9]], label [[FOR_BODY10:%.*]], label [[FOR_END:%.*]] +// CHECK2: for.body10: +// CHECK2-NEXT: [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[TMP11:%.*]] = load i64, ptr [[DOTPERMUTED_1_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[MUL11:%.*]] = mul nsw i64 [[TMP11]], 1 +// CHECK2-NEXT: [[ADD_PTR12:%.*]] = getelementptr inbounds double, ptr [[TMP10]], i64 [[MUL11]] +// CHECK2-NEXT: store ptr [[ADD_PTR12]], ptr [[__BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP12:%.*]] = load ptr, ptr [[__BEGIN2]], align 8 +// CHECK2-NEXT: store ptr [[TMP12]], ptr [[V]], align 8 +// CHECK2-NEXT: [[TMP13:%.*]] = load double, ptr [[C]], align 8 +// CHECK2-NEXT: [[TMP14:%.*]] = load ptr, ptr [[V]], align 8 +// CHECK2-NEXT: [[TMP15:%.*]] = load double, ptr [[TMP14]], align 8 +// CHECK2-NEXT: [[TMP16:%.*]] = load i32, ptr [[I]], align 4 +// CHECK2-NEXT: call void (...) @body(double noundef [[TMP13]], double noundef [[TMP15]], i32 noundef [[TMP16]]) +// CHECK2-NEXT: br label [[FOR_INC:%.*]] +// CHECK2: for.inc: +// CHECK2-NEXT: [[TMP17:%.*]] = load i64, ptr [[DOTPERMUTED_1_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[INC:%.*]] = add nsw i64 [[TMP17]], 1 +// CHECK2-NEXT: store i64 [[INC]], ptr [[DOTPERMUTED_1_IV___BEGIN2]], align 8 +// CHECK2-NEXT: br label [[FOR_COND7]], !llvm.loop [[LOOP8:![0-9]+]] +// CHECK2: for.end: +// CHECK2-NEXT: br label [[FOR_INC13:%.*]] +// CHECK2: for.inc13: +// CHECK2-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_I]], align 4 +// CHECK2-NEXT: [[INC14:%.*]] = add nsw i32 [[TMP18]], 1 +// CHECK2-NEXT: store i32 [[INC14]], ptr [[DOTPERMUTED_0_IV_I]], align 4 +// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK2: for.end15: +// CHECK2-NEXT: ret void +// diff --git a/clang/test/OpenMP/interchange_messages.cpp b/clang/test/OpenMP/interchange_messages.cpp new file mode 100644 index 0000000000000..175c2f1efa744 --- /dev/null +++ b/clang/test/OpenMP/interchange_messages.cpp @@ -0,0 +1,77 @@ +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -std=c++17 -fopenmp -fopenmp-version=60 -fsyntax-only -Wuninitialized -verify %s + +void func() { + + // expected-warning@+1 {{extra tokens at the end of '#pragma omp interchange' are ignored}} + #pragma omp interchange foo + for (int i = 0; i < 7; ++i) + for (int j = 0; j < 13; ++j) + ; + + // expected-error@+1 {{unexpected OpenMP clause 'collapse' in directive '#pragma omp interchange'}} + #pragma omp interchange collapse(2) + for (int i = 0; i < 7; ++i) + for (int j = 0; j < 13; ++j) + ; + + { + // expected-error@+2 {{expected statement}} + #pragma omp interchange + } + + // expected-error@+2 {{statement after '#pragma omp interchange' must be a for loop}} + #pragma omp interchange + int b = 0; + + // expected-error@+3 {{statement after '#pragma omp interchange' must be a for loop}} + #pragma omp interchange + for (int i = 0; i < 7; ++i) + ; + + // expected-error@+2 {{statement after '#pragma omp interchange' must be a for loop}} + #pragma omp interchange + for (int i = 0; i < 7; ++i) { + int k = 3; + for (int j = 0; j < 7; ++j) + ; + } + + // expected-error@+3 {{expected loop invariant expression}} + #pragma omp interchange + for (int i = 0; i < 7; ++i) + for (int j = i; j < 7; ++j) + ; + + // expected-error@+3 {{expected loop invariant expression}} + #pragma omp interchange + for (int i = 0; i < 7; ++i) + for (int j = 0; j < i; ++j) + ; + + // expected-error@+3 {{expected loop invariant expression}} + #pragma omp interchange + for (int i = 0; i < 7; ++i) + for (int j = 0; j < i; ++j) + ; + + // expected-error@+6 {{expected 3 for loops after '#pragma omp for', but found only 2}} + // expected-note@+1 {{as specified in 'collapse' clause}} + #pragma omp for collapse(3) + #pragma omp interchange + for (int i = 0; i < 7; ++i) + for (int j = 0; j < 13; ++j) + ; + + // expected-error@+2 {{statement after '#pragma omp interchange' must be a for loop}} + #pragma omp interchange + #pragma omp for + for (int i = 0; i < 7; ++i) + ; + + // expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', '>=', or '!=') of loop variable 'j'}} + #pragma omp interchange + for (int i = 0; i < 7; ++i) + for (int j = 0; j/3<7; ++j) + ; +} + diff --git a/clang/test/OpenMP/nvptx_target_parallel_reduction_codegen_tbaa_PR46146.cpp b/clang/test/OpenMP/nvptx_target_parallel_reduction_codegen_tbaa_PR46146.cpp index 7b37480856ca2..4c2d40e21bef0 100644 --- a/clang/test/OpenMP/nvptx_target_parallel_reduction_codegen_tbaa_PR46146.cpp +++ b/clang/test/OpenMP/nvptx_target_parallel_reduction_codegen_tbaa_PR46146.cpp @@ -36,14 +36,14 @@ void test() { // CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[DOTTHREADID_TEMP_:%.*]] = alloca i32, align 4 -// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8, !tbaa [[TBAA10:![0-9]+]] // CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_target_init(ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z17complex_reductionIfEvv_l16_kernel_environment, ptr [[DYN_PTR]]) // CHECK1-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP0]], -1 // CHECK1-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]] // CHECK1: user_code.entry: // CHECK1-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]]) // CHECK1-NEXT: store i32 0, ptr [[DOTZERO_ADDR]], align 4 -// CHECK1-NEXT: store i32 [[TMP1]], ptr [[DOTTHREADID_TEMP_]], align 4 +// CHECK1-NEXT: store i32 [[TMP1]], ptr [[DOTTHREADID_TEMP_]], align 4, !tbaa [[TBAA15:![0-9]+]] // CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z17complex_reductionIfEvv_l16_omp_outlined(ptr [[DOTTHREADID_TEMP_]], ptr [[DOTZERO_ADDR]]) #[[ATTR4:[0-9]+]] // CHECK1-NEXT: call void @__kmpc_target_deinit() // CHECK1-NEXT: ret void @@ -66,78 +66,78 @@ void test() { // CHECK1-NEXT: [[REF_TMP:%.*]] = alloca float, align 4 // CHECK1-NEXT: [[REF_TMP2:%.*]] = alloca float, align 4 // CHECK1-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [3 x ptr], align 8 -// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA17:![0-9]+]] +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA17]] // CHECK1-NEXT: [[ISTART:%.*]] = call align 16 ptr @__kmpc_alloc_shared(i64 4) // CHECK1-NEXT: [[IEND:%.*]] = call align 16 ptr @__kmpc_alloc_shared(i64 4) // CHECK1-NEXT: [[PARTIAL_SUM:%.*]] = call align 16 ptr @__kmpc_alloc_shared(i64 8) // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_IV]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_LB]]) #[[ATTR4]] -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_UB]]) #[[ATTR4]] -// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_STRIDE]]) #[[ATTR4]] -// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_IS_LAST]]) #[[ATTR4]] -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[IB]]) #[[ATTR4]] // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @__kmpc_distribute_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) -// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 // CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK1: cond.true: // CHECK1-NEXT: br label [[COND_END:%.*]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: br label [[COND_END]] // CHECK1: cond.end: // CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] -// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 -// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 -// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] // CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]] // CHECK1: omp.inner.for.cond.cleanup: // CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1 // CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] -// CHECK1-NEXT: store i32 [[ADD]], ptr [[IB]], align 4 +// CHECK1-NEXT: store i32 [[ADD]], ptr [[IB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[REF_TMP]]) #[[ATTR4]] -// CHECK1-NEXT: store float 0.000000e+00, ptr [[REF_TMP]], align 4 +// CHECK1-NEXT: store float 0.000000e+00, ptr [[REF_TMP]], align 4, !tbaa [[TBAA19:![0-9]+]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[REF_TMP2]]) #[[ATTR4]] -// CHECK1-NEXT: store float 0.000000e+00, ptr [[REF_TMP2]], align 4 -// CHECK1-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(ptr nonnull align 4 dereferenceable(8) [[PARTIAL_SUM]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP2]]) #[[ATTR12:[0-9]+]] +// CHECK1-NEXT: store float 0.000000e+00, ptr [[REF_TMP2]], align 4, !tbaa [[TBAA19]] +// CHECK1-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(ptr nonnull align 4 dereferenceable(8) [[PARTIAL_SUM]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP2]]) #[[ATTR11:[0-9]+]] // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[REF_TMP2]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[REF_TMP]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[IB]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[IB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[MUL3:%.*]] = mul nsw i32 [[TMP8]], 4 -// CHECK1-NEXT: store i32 [[MUL3]], ptr [[ISTART]], align 4 -// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[IB]], align 4 +// CHECK1-NEXT: store i32 [[MUL3]], ptr [[ISTART]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[IB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP9]], 1 // CHECK1-NEXT: [[MUL5:%.*]] = mul nsw i32 [[ADD4]], 4 -// CHECK1-NEXT: store i32 [[MUL5]], ptr [[IEND]], align 4 +// CHECK1-NEXT: store i32 [[MUL5]], ptr [[IEND]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [3 x ptr], ptr [[CAPTURED_VARS_ADDRS]], i64 0, i64 0 -// CHECK1-NEXT: store ptr [[ISTART]], ptr [[TMP10]], align 8 +// CHECK1-NEXT: store ptr [[ISTART]], ptr [[TMP10]], align 8, !tbaa [[TBAA21:![0-9]+]] // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [3 x ptr], ptr [[CAPTURED_VARS_ADDRS]], i64 0, i64 1 -// CHECK1-NEXT: store ptr [[IEND]], ptr [[TMP11]], align 8 +// CHECK1-NEXT: store ptr [[IEND]], ptr [[TMP11]], align 8, !tbaa [[TBAA21]] // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [3 x ptr], ptr [[CAPTURED_VARS_ADDRS]], i64 0, i64 2 -// CHECK1-NEXT: store ptr [[PARTIAL_SUM]], ptr [[TMP12]], align 8 +// CHECK1-NEXT: store ptr [[PARTIAL_SUM]], ptr [[TMP12]], align 8, !tbaa [[TBAA21]] // CHECK1-NEXT: call void @__kmpc_parallel_51(ptr @[[GLOB1]], i32 [[TMP1]], i32 1, i32 -1, i32 -1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z17complex_reductionIfEvv_l16_omp_outlined_omp_outlined, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z17complex_reductionIfEvv_l16_omp_outlined_omp_outlined_wrapper, ptr [[CAPTURED_VARS_ADDRS]], i64 3) // CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK1: omp.body.continue: // CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK1: omp.inner.for.inc: -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP13]], 1 -// CHECK1-NEXT: store i32 [[ADD6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: store i32 [[ADD6]], ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] @@ -161,13 +161,13 @@ void test() { // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[__RE_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[__IM_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK1-NEXT: store ptr [[__RE]], ptr [[__RE_ADDR]], align 8 -// CHECK1-NEXT: store ptr [[__IM]], ptr [[__IM_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8, !tbaa [[TBAA23:![0-9]+]] +// CHECK1-NEXT: store ptr [[__RE]], ptr [[__RE_ADDR]], align 8, !tbaa [[TBAA24:![0-9]+]] +// CHECK1-NEXT: store ptr [[__IM]], ptr [[__IM_ADDR]], align 8, !tbaa [[TBAA24]] // CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RE_ADDR]], align 8 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__IM_ADDR]], align 8 -// CHECK1-NEXT: call void @_ZNSt7complexIfEC2ERKfS2_(ptr nonnull align 4 dereferenceable(8) [[THIS1]], ptr nonnull align 4 dereferenceable(4) [[TMP0]], ptr nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR12]] +// CHECK1-NEXT: call void @_ZNSt7complexIfEC2ERKfS2_(ptr nonnull align 4 dereferenceable(8) [[THIS1]], ptr nonnull align 4 dereferenceable(4) [[TMP0]], ptr nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR11]] // CHECK1-NEXT: ret void // // @@ -197,79 +197,79 @@ void test() { // CHECK1-NEXT: [[REF_TMP15:%.*]] = alloca float, align 4 // CHECK1-NEXT: [[REF_TMP16:%.*]] = alloca float, align 4 // CHECK1-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8 -// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: store ptr [[ISTART]], ptr [[ISTART_ADDR]], align 8 -// CHECK1-NEXT: store ptr [[IEND]], ptr [[IEND_ADDR]], align 8 -// CHECK1-NEXT: store ptr [[PARTIAL_SUM]], ptr [[PARTIAL_SUM_ADDR]], align 8 -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ISTART_ADDR]], align 8 -// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[IEND_ADDR]], align 8 -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[PARTIAL_SUM_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA17]] +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA17]] +// CHECK1-NEXT: store ptr [[ISTART]], ptr [[ISTART_ADDR]], align 8, !tbaa [[TBAA17]] +// CHECK1-NEXT: store ptr [[IEND]], ptr [[IEND_ADDR]], align 8, !tbaa [[TBAA17]] +// CHECK1-NEXT: store ptr [[PARTIAL_SUM]], ptr [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA23]] +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ISTART_ADDR]], align 8, !tbaa [[TBAA17]] +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[IEND_ADDR]], align 8, !tbaa [[TBAA17]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA23]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_IV]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTCAPTURE_EXPR_]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4 -// CHECK1-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTCAPTURE_EXPR_1]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP1]], align 4 -// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP1]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTCAPTURE_EXPR_2]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[SUB:%.*]] = sub i32 [[TMP5]], [[TMP6]] // CHECK1-NEXT: [[SUB3:%.*]] = sub i32 [[SUB]], 1 // CHECK1-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], 1 // CHECK1-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], 1 // CHECK1-NEXT: [[SUB4:%.*]] = sub i32 [[DIV]], 1 -// CHECK1-NEXT: store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 -// CHECK1-NEXT: store i32 [[TMP7]], ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i32 [[TMP7]], ptr [[I]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 -// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP8]], [[TMP9]] // CHECK1-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] // CHECK1: omp.precond.then: // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_LB]]) #[[ATTR4]] -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_UB]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 -// CHECK1-NEXT: store i32 [[TMP10]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i32 [[TMP10]], ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_STRIDE]]) #[[ATTR4]] -// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_IS_LAST]]) #[[ATTR4]] -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[PARTIAL_SUM5]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[REF_TMP]]) #[[ATTR4]] -// CHECK1-NEXT: store float 0.000000e+00, ptr [[REF_TMP]], align 4 +// CHECK1-NEXT: store float 0.000000e+00, ptr [[REF_TMP]], align 4, !tbaa [[TBAA19]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[REF_TMP6]]) #[[ATTR4]] -// CHECK1-NEXT: store float 0.000000e+00, ptr [[REF_TMP6]], align 4 -// CHECK1-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(ptr nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP6]]) #[[ATTR12]] +// CHECK1-NEXT: store float 0.000000e+00, ptr [[REF_TMP6]], align 4, !tbaa [[TBAA19]] +// CHECK1-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(ptr nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP6]]) #[[ATTR11]] // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[REF_TMP6]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[REF_TMP]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I7]]) #[[ATTR4]] // CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP11]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP11]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB3:[0-9]+]], i32 [[TMP12]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]] // CHECK1: omp.dispatch.cond: -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[TMP13]], [[TMP14]] // CHECK1-NEXT: br i1 [[CMP8]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK1: cond.true: -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: br label [[COND_END:%.*]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: br label [[COND_END]] // CHECK1: cond.end: // CHECK1-NEXT: [[COND:%.*]] = phi i32 [ [[TMP15]], [[COND_TRUE]] ], [ [[TMP16]], [[COND_FALSE]] ] -// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 -// CHECK1-NEXT: store i32 [[TMP17]], ptr [[DOTOMP_IV]], align 4 -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 -// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i32 [[TMP17]], ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[ADD9:%.*]] = add i32 [[TMP19]], 1 // CHECK1-NEXT: [[CMP10:%.*]] = icmp ult i32 [[TMP18]], [[ADD9]] // CHECK1-NEXT: br i1 [[CMP10]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_CLEANUP:%.*]] @@ -278,30 +278,30 @@ void test() { // CHECK1: omp.dispatch.body: // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 -// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[ADD11:%.*]] = add i32 [[TMP21]], 1 // CHECK1-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP20]], [[ADD11]] // CHECK1-NEXT: br i1 [[CMP12]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]] // CHECK1: omp.inner.for.cond.cleanup: // CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 -// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[MUL:%.*]] = mul i32 [[TMP23]], 1 // CHECK1-NEXT: [[ADD13:%.*]] = add i32 [[TMP22]], [[MUL]] -// CHECK1-NEXT: store i32 [[ADD13]], ptr [[I7]], align 4 +// CHECK1-NEXT: store i32 [[ADD13]], ptr [[I7]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[REF_TMP14]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[REF_TMP15]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[I7]], align 4 +// CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[I7]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP24]] to float -// CHECK1-NEXT: store float [[CONV]], ptr [[REF_TMP15]], align 4 +// CHECK1-NEXT: store float [[CONV]], ptr [[REF_TMP15]], align 4, !tbaa [[TBAA19]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[REF_TMP16]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[I7]], align 4 +// CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[I7]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[CONV17:%.*]] = sitofp i32 [[TMP25]] to float -// CHECK1-NEXT: store float [[CONV17]], ptr [[REF_TMP16]], align 4 -// CHECK1-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(ptr nonnull align 4 dereferenceable(8) [[REF_TMP14]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP15]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP16]]) #[[ATTR12]] -// CHECK1-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(ptr nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP14]]) #[[ATTR12]] +// CHECK1-NEXT: store float [[CONV17]], ptr [[REF_TMP16]], align 4, !tbaa [[TBAA19]] +// CHECK1-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(ptr nonnull align 4 dereferenceable(8) [[REF_TMP14]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP15]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP16]]) #[[ATTR11]] +// CHECK1-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(ptr nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP14]]) #[[ATTR11]] // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[REF_TMP16]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[REF_TMP15]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[REF_TMP14]]) #[[ATTR4]] @@ -309,25 +309,25 @@ void test() { // CHECK1: omp.body.continue: // CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK1: omp.inner.for.inc: -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[ADD18:%.*]] = add i32 [[TMP26]], 1 -// CHECK1-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK1: omp.dispatch.inc: -// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[ADD19:%.*]] = add i32 [[TMP27]], [[TMP28]] -// CHECK1-NEXT: store i32 [[ADD19]], ptr [[DOTOMP_LB]], align 4 -// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 -// CHECK1-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 [[ADD19]], ptr [[DOTOMP_LB]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[ADD20:%.*]] = add i32 [[TMP29]], [[TMP30]] -// CHECK1-NEXT: store i32 [[ADD20]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 [[ADD20]], ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK1: omp.dispatch.end: // CHECK1-NEXT: [[TMP31:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP31]], align 4 +// CHECK1-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP31]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP32]]) // CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 // CHECK1-NEXT: store ptr [[PARTIAL_SUM5]], ptr [[TMP33]], align 8 @@ -335,7 +335,7 @@ void test() { // CHECK1-NEXT: [[TMP35:%.*]] = icmp eq i32 [[TMP34]], 1 // CHECK1-NEXT: br i1 [[TMP35]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]] // CHECK1: .omp.reduction.then: -// CHECK1-NEXT: [[CALL21:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(ptr nonnull align 4 dereferenceable(8) [[TMP2]], ptr nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]]) #[[ATTR12]] +// CHECK1-NEXT: [[CALL21:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(ptr nonnull align 4 dereferenceable(8) [[TMP2]], ptr nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]]) #[[ATTR11]] // CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DONE]] // CHECK1: .omp.reduction.done: // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[I7]]) #[[ATTR4]] @@ -354,30 +354,30 @@ void test() { // // // CHECK1-LABEL: define {{[^@]+}}@_ZNSt7complexIfEpLIfEERS0_RKS_IT_E -// CHECK1-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]], ptr nonnull align 4 dereferenceable(8) [[__C:%.*]]) #[[ATTR6:[0-9]+]] comdat align 2 { +// CHECK1-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]], ptr nonnull align 4 dereferenceable(8) [[__C:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[__C_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK1-NEXT: store ptr [[__C]], ptr [[__C_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8, !tbaa [[TBAA23]] +// CHECK1-NEXT: store ptr [[__C]], ptr [[__C_ADDR]], align 8, !tbaa [[TBAA23]] // CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__C_ADDR]], align 8 -// CHECK1-NEXT: [[CALL:%.*]] = call float @_ZNKSt7complexIfE4realEv(ptr nonnull align 4 dereferenceable(8) [[TMP0]]) #[[ATTR12]] +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__C_ADDR]], align 8, !tbaa [[TBAA23]] +// CHECK1-NEXT: [[CALL:%.*]] = call float @_ZNKSt7complexIfE4realEv(ptr nonnull align 4 dereferenceable(8) [[TMP0]]) #[[ATTR11]] // CHECK1-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", ptr [[THIS1]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP1:%.*]] = load float, ptr [[__RE_]], align 4 +// CHECK1-NEXT: [[TMP1:%.*]] = load float, ptr [[__RE_]], align 4, !tbaa [[TBAA26:![0-9]+]] // CHECK1-NEXT: [[ADD:%.*]] = fadd float [[TMP1]], [[CALL]] -// CHECK1-NEXT: store float [[ADD]], ptr [[__RE_]], align 4 -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__C_ADDR]], align 8 -// CHECK1-NEXT: [[CALL2:%.*]] = call float @_ZNKSt7complexIfE4imagEv(ptr nonnull align 4 dereferenceable(8) [[TMP2]]) #[[ATTR12]] +// CHECK1-NEXT: store float [[ADD]], ptr [[__RE_]], align 4, !tbaa [[TBAA26]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__C_ADDR]], align 8, !tbaa [[TBAA23]] +// CHECK1-NEXT: [[CALL2:%.*]] = call float @_ZNKSt7complexIfE4imagEv(ptr nonnull align 4 dereferenceable(8) [[TMP2]]) #[[ATTR11]] // CHECK1-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", ptr [[THIS1]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP3:%.*]] = load float, ptr [[__IM_]], align 4 +// CHECK1-NEXT: [[TMP3:%.*]] = load float, ptr [[__IM_]], align 4, !tbaa [[TBAA28:![0-9]+]] // CHECK1-NEXT: [[ADD3:%.*]] = fadd float [[TMP3]], [[CALL2]] -// CHECK1-NEXT: store float [[ADD3]], ptr [[__IM_]], align 4 +// CHECK1-NEXT: store float [[ADD3]], ptr [[__IM_]], align 4, !tbaa [[TBAA28]] // CHECK1-NEXT: ret ptr [[THIS1]] // // // CHECK1-LABEL: define {{[^@]+}}@_omp_reduction_shuffle_and_reduce_func -// CHECK1-SAME: (ptr noundef [[TMP0:%.*]], i16 noundef signext [[TMP1:%.*]], i16 noundef signext [[TMP2:%.*]], i16 noundef signext [[TMP3:%.*]]) #[[ATTR7:[0-9]+]] { +// CHECK1-SAME: (ptr noundef [[TMP0:%.*]], i16 noundef signext [[TMP1:%.*]], i16 noundef signext [[TMP2:%.*]], i16 noundef signext [[TMP3:%.*]]) #[[ATTR1]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i16, align 2 @@ -442,59 +442,59 @@ void test() { // // // CHECK1-LABEL: define {{[^@]+}}@_omp_reduction_inter_warp_copy_func -// CHECK1-SAME: (ptr noundef [[TMP0:%.*]], i32 noundef [[TMP1:%.*]]) #[[ATTR7]] { +// CHECK1-SAME: (ptr noundef [[TMP0:%.*]], i32 noundef [[TMP1:%.*]]) #[[ATTR1]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[DOTCNT_ADDR:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 // CHECK1-NEXT: store i32 [[TMP1]], ptr [[DOTADDR1]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() // CHECK1-NEXT: [[TMP3:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() +// CHECK1-NEXT: [[NVPTX_LANE_ID:%.*]] = and i32 [[TMP3]], 31 // CHECK1-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() -// CHECK1-NEXT: [[NVPTX_LANE_ID:%.*]] = and i32 [[TMP4]], 31 -// CHECK1-NEXT: [[TMP5:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() -// CHECK1-NEXT: [[NVPTX_WARP_ID:%.*]] = ashr i32 [[TMP5]], 5 -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[DOTADDR]], align 8 +// CHECK1-NEXT: [[NVPTX_WARP_ID:%.*]] = ashr i32 [[TMP4]], 5 +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTADDR]], align 8 // CHECK1-NEXT: store i32 0, ptr [[DOTCNT_ADDR]], align 4 // CHECK1-NEXT: br label [[PRECOND:%.*]] // CHECK1: precond: -// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTCNT_ADDR]], align 4 -// CHECK1-NEXT: [[TMP8:%.*]] = icmp ult i32 [[TMP7]], 2 -// CHECK1-NEXT: br i1 [[TMP8]], label [[BODY:%.*]], label [[EXIT:%.*]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCNT_ADDR]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = icmp ult i32 [[TMP6]], 2 +// CHECK1-NEXT: br i1 [[TMP7]], label [[BODY:%.*]], label [[EXIT:%.*]] // CHECK1: body: -// CHECK1-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) -// CHECK1-NEXT: call void @__kmpc_barrier(ptr @[[GLOB4:[0-9]+]], i32 [[TMP2]]) +// CHECK1-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) +// CHECK1-NEXT: call void @__kmpc_barrier(ptr @[[GLOB4:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM]]) // CHECK1-NEXT: [[WARP_MASTER:%.*]] = icmp eq i32 [[NVPTX_LANE_ID]], 0 // CHECK1-NEXT: br i1 [[WARP_MASTER]], label [[THEN:%.*]], label [[ELSE:%.*]] // CHECK1: then: -// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP6]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[TMP9]], align 8 -// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr i32, ptr [[TMP10]], i32 [[TMP7]] -// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [32 x i32], ptr addrspace(3) @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[NVPTX_WARP_ID]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP11]], align 4 -// CHECK1-NEXT: store volatile i32 [[TMP13]], ptr addrspace(3) [[TMP12]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP5]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[TMP8]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr i32, ptr [[TMP9]], i32 [[TMP6]] +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [32 x i32], ptr addrspace(3) @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[NVPTX_WARP_ID]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP10]], align 4 +// CHECK1-NEXT: store volatile i32 [[TMP12]], ptr addrspace(3) [[TMP11]], align 4 // CHECK1-NEXT: br label [[IFCONT:%.*]] // CHECK1: else: // CHECK1-NEXT: br label [[IFCONT]] // CHECK1: ifcont: -// CHECK1-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) -// CHECK1-NEXT: call void @__kmpc_barrier(ptr @[[GLOB4]], i32 [[TMP2]]) -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTADDR1]], align 4 -// CHECK1-NEXT: [[IS_ACTIVE_THREAD:%.*]] = icmp ult i32 [[TMP3]], [[TMP14]] -// CHECK1-NEXT: br i1 [[IS_ACTIVE_THREAD]], label [[THEN2:%.*]], label [[ELSE3:%.*]] +// CHECK1-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) +// CHECK1-NEXT: call void @__kmpc_barrier(ptr @[[GLOB4]], i32 [[OMP_GLOBAL_THREAD_NUM2]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTADDR1]], align 4 +// CHECK1-NEXT: [[IS_ACTIVE_THREAD:%.*]] = icmp ult i32 [[TMP2]], [[TMP13]] +// CHECK1-NEXT: br i1 [[IS_ACTIVE_THREAD]], label [[THEN3:%.*]], label [[ELSE4:%.*]] // CHECK1: then3: -// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [32 x i32], ptr addrspace(3) @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[TMP3]] -// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP6]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr i32, ptr [[TMP17]], i32 [[TMP7]] -// CHECK1-NEXT: [[TMP19:%.*]] = load volatile i32, ptr addrspace(3) [[TMP15]], align 4 -// CHECK1-NEXT: store i32 [[TMP19]], ptr [[TMP18]], align 4 -// CHECK1-NEXT: br label [[IFCONT4:%.*]] +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [32 x i32], ptr addrspace(3) @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[TMP2]] +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP5]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP16:%.*]] = load ptr, ptr [[TMP15]], align 8 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr i32, ptr [[TMP16]], i32 [[TMP6]] +// CHECK1-NEXT: [[TMP18:%.*]] = load volatile i32, ptr addrspace(3) [[TMP14]], align 4 +// CHECK1-NEXT: store i32 [[TMP18]], ptr [[TMP17]], align 4 +// CHECK1-NEXT: br label [[IFCONT5:%.*]] // CHECK1: else4: -// CHECK1-NEXT: br label [[IFCONT4]] +// CHECK1-NEXT: br label [[IFCONT5]] // CHECK1: ifcont5: -// CHECK1-NEXT: [[TMP20:%.*]] = add nsw i32 [[TMP7]], 1 -// CHECK1-NEXT: store i32 [[TMP20]], ptr [[DOTCNT_ADDR]], align 4 +// CHECK1-NEXT: [[TMP19:%.*]] = add nsw i32 [[TMP6]], 1 +// CHECK1-NEXT: store i32 [[TMP19]], ptr [[DOTCNT_ADDR]], align 4 // CHECK1-NEXT: br label [[PRECOND]] // CHECK1: exit: // CHECK1-NEXT: ret void @@ -507,17 +507,17 @@ void test() { // CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[GLOBAL_ARGS:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store i16 [[TMP0]], ptr [[DOTADDR]], align 2 -// CHECK1-NEXT: store i32 [[TMP1]], ptr [[DOTADDR1]], align 4 +// CHECK1-NEXT: store i16 [[TMP0]], ptr [[DOTADDR]], align 2, !tbaa [[TBAA29:![0-9]+]] +// CHECK1-NEXT: store i32 [[TMP1]], ptr [[DOTADDR1]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: store i32 0, ptr [[DOTZERO_ADDR]], align 4 // CHECK1-NEXT: call void @__kmpc_get_shared_variables(ptr [[GLOBAL_ARGS]]) // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[GLOBAL_ARGS]], align 8 // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds ptr, ptr [[TMP2]], i64 0 -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP3]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP3]], align 8, !tbaa [[TBAA23]] // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds ptr, ptr [[TMP2]], i64 1 -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[TMP5]], align 8 +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[TMP5]], align 8, !tbaa [[TBAA23]] // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds ptr, ptr [[TMP2]], i64 2 -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[TMP7]], align 8, !tbaa [[TBAA23]] // CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z17complex_reductionIfEvv_l16_omp_outlined_omp_outlined(ptr [[DOTADDR1]], ptr [[DOTZERO_ADDR]], ptr [[TMP4]], ptr [[TMP6]], ptr [[TMP8]]) #[[ATTR4]] // CHECK1-NEXT: ret void // @@ -528,14 +528,14 @@ void test() { // CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[DOTTHREADID_TEMP_:%.*]] = alloca i32, align 4 -// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8, !tbaa [[TBAA10]] // CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_target_init(ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z17complex_reductionIdEvv_l16_kernel_environment, ptr [[DYN_PTR]]) // CHECK1-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP0]], -1 // CHECK1-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]] // CHECK1: user_code.entry: // CHECK1-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) // CHECK1-NEXT: store i32 0, ptr [[DOTZERO_ADDR]], align 4 -// CHECK1-NEXT: store i32 [[TMP1]], ptr [[DOTTHREADID_TEMP_]], align 4 +// CHECK1-NEXT: store i32 [[TMP1]], ptr [[DOTTHREADID_TEMP_]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z17complex_reductionIdEvv_l16_omp_outlined(ptr [[DOTTHREADID_TEMP_]], ptr [[DOTZERO_ADDR]]) #[[ATTR4]] // CHECK1-NEXT: call void @__kmpc_target_deinit() // CHECK1-NEXT: ret void @@ -558,78 +558,78 @@ void test() { // CHECK1-NEXT: [[REF_TMP:%.*]] = alloca double, align 8 // CHECK1-NEXT: [[REF_TMP2:%.*]] = alloca double, align 8 // CHECK1-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [3 x ptr], align 8 -// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA17]] +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA17]] // CHECK1-NEXT: [[ISTART:%.*]] = call align 16 ptr @__kmpc_alloc_shared(i64 4) // CHECK1-NEXT: [[IEND:%.*]] = call align 16 ptr @__kmpc_alloc_shared(i64 4) // CHECK1-NEXT: [[PARTIAL_SUM:%.*]] = call align 16 ptr @__kmpc_alloc_shared(i64 16) // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_IV]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_LB]]) #[[ATTR4]] -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_UB]]) #[[ATTR4]] -// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_STRIDE]]) #[[ATTR4]] -// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_IS_LAST]]) #[[ATTR4]] -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[IB]]) #[[ATTR4]] // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @__kmpc_distribute_static_init_4(ptr @[[GLOB2]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) -// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 // CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK1: cond.true: // CHECK1-NEXT: br label [[COND_END:%.*]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: br label [[COND_END]] // CHECK1: cond.end: // CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] -// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 -// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 -// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] // CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]] // CHECK1: omp.inner.for.cond.cleanup: // CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1 // CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] -// CHECK1-NEXT: store i32 [[ADD]], ptr [[IB]], align 4 +// CHECK1-NEXT: store i32 [[ADD]], ptr [[IB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[REF_TMP]]) #[[ATTR4]] -// CHECK1-NEXT: store double 0.000000e+00, ptr [[REF_TMP]], align 8 +// CHECK1-NEXT: store double 0.000000e+00, ptr [[REF_TMP]], align 8, !tbaa [[TBAA31:![0-9]+]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[REF_TMP2]]) #[[ATTR4]] -// CHECK1-NEXT: store double 0.000000e+00, ptr [[REF_TMP2]], align 8 -// CHECK1-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(ptr nonnull align 8 dereferenceable(16) [[PARTIAL_SUM]], ptr nonnull align 8 dereferenceable(8) [[REF_TMP]], ptr nonnull align 8 dereferenceable(8) [[REF_TMP2]]) #[[ATTR12]] +// CHECK1-NEXT: store double 0.000000e+00, ptr [[REF_TMP2]], align 8, !tbaa [[TBAA31]] +// CHECK1-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(ptr nonnull align 8 dereferenceable(16) [[PARTIAL_SUM]], ptr nonnull align 8 dereferenceable(8) [[REF_TMP]], ptr nonnull align 8 dereferenceable(8) [[REF_TMP2]]) #[[ATTR11]] // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[REF_TMP2]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[REF_TMP]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[IB]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[IB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[MUL3:%.*]] = mul nsw i32 [[TMP8]], 4 -// CHECK1-NEXT: store i32 [[MUL3]], ptr [[ISTART]], align 4 -// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[IB]], align 4 +// CHECK1-NEXT: store i32 [[MUL3]], ptr [[ISTART]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[IB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP9]], 1 // CHECK1-NEXT: [[MUL5:%.*]] = mul nsw i32 [[ADD4]], 4 -// CHECK1-NEXT: store i32 [[MUL5]], ptr [[IEND]], align 4 +// CHECK1-NEXT: store i32 [[MUL5]], ptr [[IEND]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [3 x ptr], ptr [[CAPTURED_VARS_ADDRS]], i64 0, i64 0 -// CHECK1-NEXT: store ptr [[ISTART]], ptr [[TMP10]], align 8 +// CHECK1-NEXT: store ptr [[ISTART]], ptr [[TMP10]], align 8, !tbaa [[TBAA21]] // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [3 x ptr], ptr [[CAPTURED_VARS_ADDRS]], i64 0, i64 1 -// CHECK1-NEXT: store ptr [[IEND]], ptr [[TMP11]], align 8 +// CHECK1-NEXT: store ptr [[IEND]], ptr [[TMP11]], align 8, !tbaa [[TBAA21]] // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [3 x ptr], ptr [[CAPTURED_VARS_ADDRS]], i64 0, i64 2 -// CHECK1-NEXT: store ptr [[PARTIAL_SUM]], ptr [[TMP12]], align 8 +// CHECK1-NEXT: store ptr [[PARTIAL_SUM]], ptr [[TMP12]], align 8, !tbaa [[TBAA21]] // CHECK1-NEXT: call void @__kmpc_parallel_51(ptr @[[GLOB1]], i32 [[TMP1]], i32 1, i32 -1, i32 -1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z17complex_reductionIdEvv_l16_omp_outlined_omp_outlined, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z17complex_reductionIdEvv_l16_omp_outlined_omp_outlined_wrapper, ptr [[CAPTURED_VARS_ADDRS]], i64 3) // CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK1: omp.body.continue: // CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK1: omp.inner.for.inc: -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP13]], 1 -// CHECK1-NEXT: store i32 [[ADD6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: store i32 [[ADD6]], ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] @@ -653,13 +653,13 @@ void test() { // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[__RE_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[__IM_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK1-NEXT: store ptr [[__RE]], ptr [[__RE_ADDR]], align 8 -// CHECK1-NEXT: store ptr [[__IM]], ptr [[__IM_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8, !tbaa [[TBAA23]] +// CHECK1-NEXT: store ptr [[__RE]], ptr [[__RE_ADDR]], align 8, !tbaa [[TBAA33:![0-9]+]] +// CHECK1-NEXT: store ptr [[__IM]], ptr [[__IM_ADDR]], align 8, !tbaa [[TBAA33]] // CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RE_ADDR]], align 8 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__IM_ADDR]], align 8 -// CHECK1-NEXT: call void @_ZNSt7complexIdEC2ERKdS2_(ptr nonnull align 8 dereferenceable(16) [[THIS1]], ptr nonnull align 8 dereferenceable(8) [[TMP0]], ptr nonnull align 8 dereferenceable(8) [[TMP1]]) #[[ATTR12]] +// CHECK1-NEXT: call void @_ZNSt7complexIdEC2ERKdS2_(ptr nonnull align 8 dereferenceable(16) [[THIS1]], ptr nonnull align 8 dereferenceable(8) [[TMP0]], ptr nonnull align 8 dereferenceable(8) [[TMP1]]) #[[ATTR11]] // CHECK1-NEXT: ret void // // @@ -689,79 +689,79 @@ void test() { // CHECK1-NEXT: [[REF_TMP15:%.*]] = alloca double, align 8 // CHECK1-NEXT: [[REF_TMP16:%.*]] = alloca double, align 8 // CHECK1-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8 -// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: store ptr [[ISTART]], ptr [[ISTART_ADDR]], align 8 -// CHECK1-NEXT: store ptr [[IEND]], ptr [[IEND_ADDR]], align 8 -// CHECK1-NEXT: store ptr [[PARTIAL_SUM]], ptr [[PARTIAL_SUM_ADDR]], align 8 -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ISTART_ADDR]], align 8 -// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[IEND_ADDR]], align 8 -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[PARTIAL_SUM_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA17]] +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA17]] +// CHECK1-NEXT: store ptr [[ISTART]], ptr [[ISTART_ADDR]], align 8, !tbaa [[TBAA17]] +// CHECK1-NEXT: store ptr [[IEND]], ptr [[IEND_ADDR]], align 8, !tbaa [[TBAA17]] +// CHECK1-NEXT: store ptr [[PARTIAL_SUM]], ptr [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA23]] +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ISTART_ADDR]], align 8, !tbaa [[TBAA17]] +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[IEND_ADDR]], align 8, !tbaa [[TBAA17]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA23]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_IV]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTCAPTURE_EXPR_]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4 -// CHECK1-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTCAPTURE_EXPR_1]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP1]], align 4 -// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP1]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTCAPTURE_EXPR_2]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[SUB:%.*]] = sub i32 [[TMP5]], [[TMP6]] // CHECK1-NEXT: [[SUB3:%.*]] = sub i32 [[SUB]], 1 // CHECK1-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], 1 // CHECK1-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], 1 // CHECK1-NEXT: [[SUB4:%.*]] = sub i32 [[DIV]], 1 -// CHECK1-NEXT: store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 -// CHECK1-NEXT: store i32 [[TMP7]], ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i32 [[TMP7]], ptr [[I]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 -// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP8]], [[TMP9]] // CHECK1-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] // CHECK1: omp.precond.then: // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_LB]]) #[[ATTR4]] -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_UB]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 -// CHECK1-NEXT: store i32 [[TMP10]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i32 [[TMP10]], ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_STRIDE]]) #[[ATTR4]] -// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[DOTOMP_IS_LAST]]) #[[ATTR4]] -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr [[PARTIAL_SUM5]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[REF_TMP]]) #[[ATTR4]] -// CHECK1-NEXT: store double 0.000000e+00, ptr [[REF_TMP]], align 8 +// CHECK1-NEXT: store double 0.000000e+00, ptr [[REF_TMP]], align 8, !tbaa [[TBAA31]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[REF_TMP6]]) #[[ATTR4]] -// CHECK1-NEXT: store double 0.000000e+00, ptr [[REF_TMP6]], align 8 -// CHECK1-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(ptr nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]], ptr nonnull align 8 dereferenceable(8) [[REF_TMP]], ptr nonnull align 8 dereferenceable(8) [[REF_TMP6]]) #[[ATTR12]] +// CHECK1-NEXT: store double 0.000000e+00, ptr [[REF_TMP6]], align 8, !tbaa [[TBAA31]] +// CHECK1-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(ptr nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]], ptr nonnull align 8 dereferenceable(8) [[REF_TMP]], ptr nonnull align 8 dereferenceable(8) [[REF_TMP6]]) #[[ATTR11]] // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[REF_TMP6]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[REF_TMP]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I7]]) #[[ATTR4]] // CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP11]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP11]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB3]], i32 [[TMP12]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]] // CHECK1: omp.dispatch.cond: -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[TMP13]], [[TMP14]] // CHECK1-NEXT: br i1 [[CMP8]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK1: cond.true: -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: br label [[COND_END:%.*]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: br label [[COND_END]] // CHECK1: cond.end: // CHECK1-NEXT: [[COND:%.*]] = phi i32 [ [[TMP15]], [[COND_TRUE]] ], [ [[TMP16]], [[COND_FALSE]] ] -// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 -// CHECK1-NEXT: store i32 [[TMP17]], ptr [[DOTOMP_IV]], align 4 -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 -// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i32 [[TMP17]], ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[ADD9:%.*]] = add i32 [[TMP19]], 1 // CHECK1-NEXT: [[CMP10:%.*]] = icmp ult i32 [[TMP18]], [[ADD9]] // CHECK1-NEXT: br i1 [[CMP10]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_CLEANUP:%.*]] @@ -770,30 +770,30 @@ void test() { // CHECK1: omp.dispatch.body: // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 -// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[ADD11:%.*]] = add i32 [[TMP21]], 1 // CHECK1-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP20]], [[ADD11]] // CHECK1-NEXT: br i1 [[CMP12]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]] // CHECK1: omp.inner.for.cond.cleanup: // CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 -// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[MUL:%.*]] = mul i32 [[TMP23]], 1 // CHECK1-NEXT: [[ADD13:%.*]] = add i32 [[TMP22]], [[MUL]] -// CHECK1-NEXT: store i32 [[ADD13]], ptr [[I7]], align 4 +// CHECK1-NEXT: store i32 [[ADD13]], ptr [[I7]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr [[REF_TMP14]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[REF_TMP15]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[I7]], align 4 +// CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[I7]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP24]] to double -// CHECK1-NEXT: store double [[CONV]], ptr [[REF_TMP15]], align 8 +// CHECK1-NEXT: store double [[CONV]], ptr [[REF_TMP15]], align 8, !tbaa [[TBAA31]] // CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[REF_TMP16]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[I7]], align 4 +// CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[I7]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[CONV17:%.*]] = sitofp i32 [[TMP25]] to double -// CHECK1-NEXT: store double [[CONV17]], ptr [[REF_TMP16]], align 8 -// CHECK1-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(ptr nonnull align 8 dereferenceable(16) [[REF_TMP14]], ptr nonnull align 8 dereferenceable(8) [[REF_TMP15]], ptr nonnull align 8 dereferenceable(8) [[REF_TMP16]]) #[[ATTR12]] -// CHECK1-NEXT: [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) ptr @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(ptr nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]], ptr nonnull align 8 dereferenceable(16) [[REF_TMP14]]) #[[ATTR12]] +// CHECK1-NEXT: store double [[CONV17]], ptr [[REF_TMP16]], align 8, !tbaa [[TBAA31]] +// CHECK1-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(ptr nonnull align 8 dereferenceable(16) [[REF_TMP14]], ptr nonnull align 8 dereferenceable(8) [[REF_TMP15]], ptr nonnull align 8 dereferenceable(8) [[REF_TMP16]]) #[[ATTR11]] +// CHECK1-NEXT: [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) ptr @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(ptr nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]], ptr nonnull align 8 dereferenceable(16) [[REF_TMP14]]) #[[ATTR11]] // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[REF_TMP16]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[REF_TMP15]]) #[[ATTR4]] // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr [[REF_TMP14]]) #[[ATTR4]] @@ -801,25 +801,25 @@ void test() { // CHECK1: omp.body.continue: // CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK1: omp.inner.for.inc: -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[ADD18:%.*]] = add i32 [[TMP26]], 1 -// CHECK1-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK1: omp.dispatch.inc: -// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[ADD19:%.*]] = add i32 [[TMP27]], [[TMP28]] -// CHECK1-NEXT: store i32 [[ADD19]], ptr [[DOTOMP_LB]], align 4 -// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 -// CHECK1-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 [[ADD19]], ptr [[DOTOMP_LB]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: [[ADD20:%.*]] = add i32 [[TMP29]], [[TMP30]] -// CHECK1-NEXT: store i32 [[ADD20]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 [[ADD20]], ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK1: omp.dispatch.end: // CHECK1-NEXT: [[TMP31:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP31]], align 4 +// CHECK1-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP31]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP32]]) // CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 // CHECK1-NEXT: store ptr [[PARTIAL_SUM5]], ptr [[TMP33]], align 8 @@ -827,7 +827,7 @@ void test() { // CHECK1-NEXT: [[TMP35:%.*]] = icmp eq i32 [[TMP34]], 1 // CHECK1-NEXT: br i1 [[TMP35]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]] // CHECK1: .omp.reduction.then: -// CHECK1-NEXT: [[CALL21:%.*]] = call nonnull align 8 dereferenceable(16) ptr @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(ptr nonnull align 8 dereferenceable(16) [[TMP2]], ptr nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]]) #[[ATTR12]] +// CHECK1-NEXT: [[CALL21:%.*]] = call nonnull align 8 dereferenceable(16) ptr @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(ptr nonnull align 8 dereferenceable(16) [[TMP2]], ptr nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]]) #[[ATTR11]] // CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DONE]] // CHECK1: .omp.reduction.done: // CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[I7]]) #[[ATTR4]] @@ -846,30 +846,30 @@ void test() { // // // CHECK1-LABEL: define {{[^@]+}}@_ZNSt7complexIdEpLIdEERS0_RKS_IT_E -// CHECK1-SAME: (ptr nonnull align 8 dereferenceable(16) [[THIS:%.*]], ptr nonnull align 8 dereferenceable(16) [[__C:%.*]]) #[[ATTR6]] comdat align 2 { +// CHECK1-SAME: (ptr nonnull align 8 dereferenceable(16) [[THIS:%.*]], ptr nonnull align 8 dereferenceable(16) [[__C:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[__C_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK1-NEXT: store ptr [[__C]], ptr [[__C_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8, !tbaa [[TBAA23]] +// CHECK1-NEXT: store ptr [[__C]], ptr [[__C_ADDR]], align 8, !tbaa [[TBAA23]] // CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__C_ADDR]], align 8 -// CHECK1-NEXT: [[CALL:%.*]] = call double @_ZNKSt7complexIdE4realEv(ptr nonnull align 8 dereferenceable(16) [[TMP0]]) #[[ATTR12]] +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__C_ADDR]], align 8, !tbaa [[TBAA23]] +// CHECK1-NEXT: [[CALL:%.*]] = call double @_ZNKSt7complexIdE4realEv(ptr nonnull align 8 dereferenceable(16) [[TMP0]]) #[[ATTR11]] // CHECK1-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.0", ptr [[THIS1]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP1:%.*]] = load double, ptr [[__RE_]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load double, ptr [[__RE_]], align 8, !tbaa [[TBAA35:![0-9]+]] // CHECK1-NEXT: [[ADD:%.*]] = fadd double [[TMP1]], [[CALL]] -// CHECK1-NEXT: store double [[ADD]], ptr [[__RE_]], align 8 -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__C_ADDR]], align 8 -// CHECK1-NEXT: [[CALL2:%.*]] = call double @_ZNKSt7complexIdE4imagEv(ptr nonnull align 8 dereferenceable(16) [[TMP2]]) #[[ATTR12]] +// CHECK1-NEXT: store double [[ADD]], ptr [[__RE_]], align 8, !tbaa [[TBAA35]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__C_ADDR]], align 8, !tbaa [[TBAA23]] +// CHECK1-NEXT: [[CALL2:%.*]] = call double @_ZNKSt7complexIdE4imagEv(ptr nonnull align 8 dereferenceable(16) [[TMP2]]) #[[ATTR11]] // CHECK1-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.0", ptr [[THIS1]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP3:%.*]] = load double, ptr [[__IM_]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load double, ptr [[__IM_]], align 8, !tbaa [[TBAA37:![0-9]+]] // CHECK1-NEXT: [[ADD3:%.*]] = fadd double [[TMP3]], [[CALL2]] -// CHECK1-NEXT: store double [[ADD3]], ptr [[__IM_]], align 8 +// CHECK1-NEXT: store double [[ADD3]], ptr [[__IM_]], align 8, !tbaa [[TBAA37]] // CHECK1-NEXT: ret ptr [[THIS1]] // // // CHECK1-LABEL: define {{[^@]+}}@_omp_reduction_shuffle_and_reduce_func1 -// CHECK1-SAME: (ptr noundef [[TMP0:%.*]], i16 noundef signext [[TMP1:%.*]], i16 noundef signext [[TMP2:%.*]], i16 noundef signext [[TMP3:%.*]]) #[[ATTR7]] { +// CHECK1-SAME: (ptr noundef [[TMP0:%.*]], i16 noundef signext [[TMP1:%.*]], i16 noundef signext [[TMP2:%.*]], i16 noundef signext [[TMP3:%.*]]) #[[ATTR1]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i16, align 2 @@ -947,59 +947,59 @@ void test() { // // // CHECK1-LABEL: define {{[^@]+}}@_omp_reduction_inter_warp_copy_func2 -// CHECK1-SAME: (ptr noundef [[TMP0:%.*]], i32 noundef [[TMP1:%.*]]) #[[ATTR7]] { +// CHECK1-SAME: (ptr noundef [[TMP0:%.*]], i32 noundef [[TMP1:%.*]]) #[[ATTR1]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[DOTCNT_ADDR:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 // CHECK1-NEXT: store i32 [[TMP1]], ptr [[DOTADDR1]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() // CHECK1-NEXT: [[TMP3:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() +// CHECK1-NEXT: [[NVPTX_LANE_ID:%.*]] = and i32 [[TMP3]], 31 // CHECK1-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() -// CHECK1-NEXT: [[NVPTX_LANE_ID:%.*]] = and i32 [[TMP4]], 31 -// CHECK1-NEXT: [[TMP5:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() -// CHECK1-NEXT: [[NVPTX_WARP_ID:%.*]] = ashr i32 [[TMP5]], 5 -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[DOTADDR]], align 8 +// CHECK1-NEXT: [[NVPTX_WARP_ID:%.*]] = ashr i32 [[TMP4]], 5 +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTADDR]], align 8 // CHECK1-NEXT: store i32 0, ptr [[DOTCNT_ADDR]], align 4 // CHECK1-NEXT: br label [[PRECOND:%.*]] // CHECK1: precond: -// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTCNT_ADDR]], align 4 -// CHECK1-NEXT: [[TMP8:%.*]] = icmp ult i32 [[TMP7]], 4 -// CHECK1-NEXT: br i1 [[TMP8]], label [[BODY:%.*]], label [[EXIT:%.*]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCNT_ADDR]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = icmp ult i32 [[TMP6]], 4 +// CHECK1-NEXT: br i1 [[TMP7]], label [[BODY:%.*]], label [[EXIT:%.*]] // CHECK1: body: -// CHECK1-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) -// CHECK1-NEXT: call void @__kmpc_barrier(ptr @[[GLOB4]], i32 [[TMP2]]) +// CHECK1-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) +// CHECK1-NEXT: call void @__kmpc_barrier(ptr @[[GLOB4]], i32 [[OMP_GLOBAL_THREAD_NUM]]) // CHECK1-NEXT: [[WARP_MASTER:%.*]] = icmp eq i32 [[NVPTX_LANE_ID]], 0 // CHECK1-NEXT: br i1 [[WARP_MASTER]], label [[THEN:%.*]], label [[ELSE:%.*]] // CHECK1: then: -// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP6]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[TMP9]], align 8 -// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr i32, ptr [[TMP10]], i32 [[TMP7]] -// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [32 x i32], ptr addrspace(3) @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[NVPTX_WARP_ID]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP11]], align 4 -// CHECK1-NEXT: store volatile i32 [[TMP13]], ptr addrspace(3) [[TMP12]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP5]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[TMP8]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr i32, ptr [[TMP9]], i32 [[TMP6]] +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [32 x i32], ptr addrspace(3) @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[NVPTX_WARP_ID]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP10]], align 4 +// CHECK1-NEXT: store volatile i32 [[TMP12]], ptr addrspace(3) [[TMP11]], align 4 // CHECK1-NEXT: br label [[IFCONT:%.*]] // CHECK1: else: // CHECK1-NEXT: br label [[IFCONT]] // CHECK1: ifcont: -// CHECK1-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) -// CHECK1-NEXT: call void @__kmpc_barrier(ptr @[[GLOB4]], i32 [[TMP2]]) -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTADDR1]], align 4 -// CHECK1-NEXT: [[IS_ACTIVE_THREAD:%.*]] = icmp ult i32 [[TMP3]], [[TMP14]] -// CHECK1-NEXT: br i1 [[IS_ACTIVE_THREAD]], label [[THEN2:%.*]], label [[ELSE3:%.*]] +// CHECK1-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) +// CHECK1-NEXT: call void @__kmpc_barrier(ptr @[[GLOB4]], i32 [[OMP_GLOBAL_THREAD_NUM2]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTADDR1]], align 4 +// CHECK1-NEXT: [[IS_ACTIVE_THREAD:%.*]] = icmp ult i32 [[TMP2]], [[TMP13]] +// CHECK1-NEXT: br i1 [[IS_ACTIVE_THREAD]], label [[THEN3:%.*]], label [[ELSE4:%.*]] // CHECK1: then3: -// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [32 x i32], ptr addrspace(3) @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[TMP3]] -// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP6]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr i32, ptr [[TMP17]], i32 [[TMP7]] -// CHECK1-NEXT: [[TMP19:%.*]] = load volatile i32, ptr addrspace(3) [[TMP15]], align 4 -// CHECK1-NEXT: store i32 [[TMP19]], ptr [[TMP18]], align 4 -// CHECK1-NEXT: br label [[IFCONT4:%.*]] +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [32 x i32], ptr addrspace(3) @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[TMP2]] +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP5]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP16:%.*]] = load ptr, ptr [[TMP15]], align 8 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr i32, ptr [[TMP16]], i32 [[TMP6]] +// CHECK1-NEXT: [[TMP18:%.*]] = load volatile i32, ptr addrspace(3) [[TMP14]], align 4 +// CHECK1-NEXT: store i32 [[TMP18]], ptr [[TMP17]], align 4 +// CHECK1-NEXT: br label [[IFCONT5:%.*]] // CHECK1: else4: -// CHECK1-NEXT: br label [[IFCONT4]] +// CHECK1-NEXT: br label [[IFCONT5]] // CHECK1: ifcont5: -// CHECK1-NEXT: [[TMP20:%.*]] = add nsw i32 [[TMP7]], 1 -// CHECK1-NEXT: store i32 [[TMP20]], ptr [[DOTCNT_ADDR]], align 4 +// CHECK1-NEXT: [[TMP19:%.*]] = add nsw i32 [[TMP6]], 1 +// CHECK1-NEXT: store i32 [[TMP19]], ptr [[DOTCNT_ADDR]], align 4 // CHECK1-NEXT: br label [[PRECOND]] // CHECK1: exit: // CHECK1-NEXT: ret void @@ -1012,17 +1012,17 @@ void test() { // CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[GLOBAL_ARGS:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store i16 [[TMP0]], ptr [[DOTADDR]], align 2 -// CHECK1-NEXT: store i32 [[TMP1]], ptr [[DOTADDR1]], align 4 +// CHECK1-NEXT: store i16 [[TMP0]], ptr [[DOTADDR]], align 2, !tbaa [[TBAA29]] +// CHECK1-NEXT: store i32 [[TMP1]], ptr [[DOTADDR1]], align 4, !tbaa [[TBAA15]] // CHECK1-NEXT: store i32 0, ptr [[DOTZERO_ADDR]], align 4 // CHECK1-NEXT: call void @__kmpc_get_shared_variables(ptr [[GLOBAL_ARGS]]) // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[GLOBAL_ARGS]], align 8 // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds ptr, ptr [[TMP2]], i64 0 -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP3]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP3]], align 8, !tbaa [[TBAA23]] // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds ptr, ptr [[TMP2]], i64 1 -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[TMP5]], align 8 +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[TMP5]], align 8, !tbaa [[TBAA23]] // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds ptr, ptr [[TMP2]], i64 2 -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[TMP7]], align 8, !tbaa [[TBAA23]] // CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z17complex_reductionIdEvv_l16_omp_outlined_omp_outlined(ptr [[DOTADDR1]], ptr [[DOTZERO_ADDR]], ptr [[TMP4]], ptr [[TMP6]], ptr [[TMP8]]) #[[ATTR4]] // CHECK1-NEXT: ret void // @@ -1033,40 +1033,40 @@ void test() { // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[__RE_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[__IM_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK1-NEXT: store ptr [[__RE]], ptr [[__RE_ADDR]], align 8 -// CHECK1-NEXT: store ptr [[__IM]], ptr [[__IM_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8, !tbaa [[TBAA23]] +// CHECK1-NEXT: store ptr [[__RE]], ptr [[__RE_ADDR]], align 8, !tbaa [[TBAA24]] +// CHECK1-NEXT: store ptr [[__IM]], ptr [[__IM_ADDR]], align 8, !tbaa [[TBAA24]] // CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", ptr [[THIS1]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RE_ADDR]], align 8 -// CHECK1-NEXT: [[TMP1:%.*]] = load float, ptr [[TMP0]], align 4 -// CHECK1-NEXT: store float [[TMP1]], ptr [[__RE_]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RE_ADDR]], align 8, !tbaa [[TBAA24]] +// CHECK1-NEXT: [[TMP1:%.*]] = load float, ptr [[TMP0]], align 4, !tbaa [[TBAA19]] +// CHECK1-NEXT: store float [[TMP1]], ptr [[__RE_]], align 4, !tbaa [[TBAA26]] // CHECK1-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", ptr [[THIS1]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__IM_ADDR]], align 8 -// CHECK1-NEXT: [[TMP3:%.*]] = load float, ptr [[TMP2]], align 4 -// CHECK1-NEXT: store float [[TMP3]], ptr [[__IM_]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__IM_ADDR]], align 8, !tbaa [[TBAA24]] +// CHECK1-NEXT: [[TMP3:%.*]] = load float, ptr [[TMP2]], align 4, !tbaa [[TBAA19]] +// CHECK1-NEXT: store float [[TMP3]], ptr [[__IM_]], align 4, !tbaa [[TBAA28]] // CHECK1-NEXT: ret void // // // CHECK1-LABEL: define {{[^@]+}}@_ZNKSt7complexIfE4realEv -// CHECK1-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]]) #[[ATTR6]] comdat align 2 { +// CHECK1-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8, !tbaa [[TBAA23]] // CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", ptr [[THIS1]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP0:%.*]] = load float, ptr [[__RE_]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load float, ptr [[__RE_]], align 4, !tbaa [[TBAA26]] // CHECK1-NEXT: ret float [[TMP0]] // // // CHECK1-LABEL: define {{[^@]+}}@_ZNKSt7complexIfE4imagEv -// CHECK1-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]]) #[[ATTR6]] comdat align 2 { +// CHECK1-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8, !tbaa [[TBAA23]] // CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", ptr [[THIS1]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP0:%.*]] = load float, ptr [[__IM_]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load float, ptr [[__IM_]], align 4, !tbaa [[TBAA28]] // CHECK1-NEXT: ret float [[TMP0]] // // @@ -1076,39 +1076,39 @@ void test() { // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[__RE_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[__IM_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK1-NEXT: store ptr [[__RE]], ptr [[__RE_ADDR]], align 8 -// CHECK1-NEXT: store ptr [[__IM]], ptr [[__IM_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8, !tbaa [[TBAA23]] +// CHECK1-NEXT: store ptr [[__RE]], ptr [[__RE_ADDR]], align 8, !tbaa [[TBAA33]] +// CHECK1-NEXT: store ptr [[__IM]], ptr [[__IM_ADDR]], align 8, !tbaa [[TBAA33]] // CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.0", ptr [[THIS1]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RE_ADDR]], align 8 -// CHECK1-NEXT: [[TMP1:%.*]] = load double, ptr [[TMP0]], align 8 -// CHECK1-NEXT: store double [[TMP1]], ptr [[__RE_]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RE_ADDR]], align 8, !tbaa [[TBAA33]] +// CHECK1-NEXT: [[TMP1:%.*]] = load double, ptr [[TMP0]], align 8, !tbaa [[TBAA31]] +// CHECK1-NEXT: store double [[TMP1]], ptr [[__RE_]], align 8, !tbaa [[TBAA35]] // CHECK1-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.0", ptr [[THIS1]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__IM_ADDR]], align 8 -// CHECK1-NEXT: [[TMP3:%.*]] = load double, ptr [[TMP2]], align 8 -// CHECK1-NEXT: store double [[TMP3]], ptr [[__IM_]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__IM_ADDR]], align 8, !tbaa [[TBAA33]] +// CHECK1-NEXT: [[TMP3:%.*]] = load double, ptr [[TMP2]], align 8, !tbaa [[TBAA31]] +// CHECK1-NEXT: store double [[TMP3]], ptr [[__IM_]], align 8, !tbaa [[TBAA37]] // CHECK1-NEXT: ret void // // // CHECK1-LABEL: define {{[^@]+}}@_ZNKSt7complexIdE4realEv -// CHECK1-SAME: (ptr nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR6]] comdat align 2 { +// CHECK1-SAME: (ptr nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8, !tbaa [[TBAA23]] // CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.0", ptr [[THIS1]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP0:%.*]] = load double, ptr [[__RE_]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load double, ptr [[__RE_]], align 8, !tbaa [[TBAA35]] // CHECK1-NEXT: ret double [[TMP0]] // // // CHECK1-LABEL: define {{[^@]+}}@_ZNKSt7complexIdE4imagEv -// CHECK1-SAME: (ptr nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR6]] comdat align 2 { +// CHECK1-SAME: (ptr nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8, !tbaa [[TBAA23]] // CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.0", ptr [[THIS1]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP0:%.*]] = load double, ptr [[__IM_]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load double, ptr [[__IM_]], align 8, !tbaa [[TBAA37]] // CHECK1-NEXT: ret double [[TMP0]] // diff --git a/clang/test/OpenMP/nvptx_target_printf_codegen.c b/clang/test/OpenMP/nvptx_target_printf_codegen.c deleted file mode 100644 index f53daf65205c9..0000000000000 --- a/clang/test/OpenMP/nvptx_target_printf_codegen.c +++ /dev/null @@ -1,179 +0,0 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ -// Test target codegen - host bc file has to be created first. -// RUN: %clang_cc1 -verify -fopenmp -x c -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix=CHECK-64 -// RUN: %clang_cc1 -verify -fopenmp -x c -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix=CHECK-32 -// expected-no-diagnostics -extern int printf(const char *, ...); - - -// Check a simple call to printf end-to-end. -int CheckSimple(void) { -#pragma omp target - { - // printf in master-only basic block. - const char* fmt = "%d %lld %f"; - - printf(fmt, 1, 2ll, 3.0); - } - - return 0; -} - -void CheckNoArgs(void) { -#pragma omp target - { - // printf in master-only basic block. - printf("hello, world!"); - } -} - -// Check that printf's alloca happens in the entry block, not inside the if -// statement. -int foo; -void CheckAllocaIsInEntryBlock(void) { -#pragma omp target - { - if (foo) { - printf("%d", 42); - } - } -} -// CHECK-64-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_CheckSimple_l13 -// CHECK-64-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR0:[0-9]+]] { -// CHECK-64-NEXT: entry: -// CHECK-64-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-64-NEXT: [[FMT:%.*]] = alloca ptr, align 8 -// CHECK-64-NEXT: [[TMP:%.*]] = alloca [[PRINTF_ARGS:%.*]], align 8 -// CHECK-64-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 -// CHECK-64-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_target_init(ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_CheckSimple_l13_kernel_environment, ptr [[DYN_PTR]]) -// CHECK-64-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP0]], -1 -// CHECK-64-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]] -// CHECK-64: user_code.entry: -// CHECK-64-NEXT: store ptr @.str, ptr [[FMT]], align 8 -// CHECK-64-NEXT: [[TMP1:%.*]] = load ptr, ptr [[FMT]], align 8 -// CHECK-64-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[PRINTF_ARGS]], ptr [[TMP]], i32 0, i32 0 -// CHECK-64-NEXT: store i32 1, ptr [[TMP2]], align 4 -// CHECK-64-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[PRINTF_ARGS]], ptr [[TMP]], i32 0, i32 1 -// CHECK-64-NEXT: store i64 2, ptr [[TMP3]], align 8 -// CHECK-64-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[PRINTF_ARGS]], ptr [[TMP]], i32 0, i32 2 -// CHECK-64-NEXT: store double 3.000000e+00, ptr [[TMP4]], align 8 -// CHECK-64-NEXT: [[TMP5:%.*]] = call i32 @__llvm_omp_vprintf(ptr [[TMP1]], ptr [[TMP]], i32 24) -// CHECK-64-NEXT: call void @__kmpc_target_deinit() -// CHECK-64-NEXT: ret void -// CHECK-64: worker.exit: -// CHECK-64-NEXT: ret void -// -// -// CHECK-64-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_CheckNoArgs_l25 -// CHECK-64-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR0]] { -// CHECK-64-NEXT: entry: -// CHECK-64-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-64-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 -// CHECK-64-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_target_init(ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_CheckNoArgs_l25_kernel_environment, ptr [[DYN_PTR]]) -// CHECK-64-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP0]], -1 -// CHECK-64-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]] -// CHECK-64: user_code.entry: -// CHECK-64-NEXT: [[TMP1:%.*]] = call i32 @__llvm_omp_vprintf(ptr @.str1, ptr null, i32 0) -// CHECK-64-NEXT: call void @__kmpc_target_deinit() -// CHECK-64-NEXT: ret void -// CHECK-64: worker.exit: -// CHECK-64-NEXT: ret void -// -// -// CHECK-64-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_CheckAllocaIsInEntryBlock_l36 -// CHECK-64-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], i64 noundef [[FOO:%.*]]) #[[ATTR0]] { -// CHECK-64-NEXT: entry: -// CHECK-64-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-64-NEXT: [[FOO_ADDR:%.*]] = alloca i64, align 8 -// CHECK-64-NEXT: [[TMP:%.*]] = alloca [[PRINTF_ARGS_0:%.*]], align 8 -// CHECK-64-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 -// CHECK-64-NEXT: store i64 [[FOO]], ptr [[FOO_ADDR]], align 8 -// CHECK-64-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_target_init(ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_CheckAllocaIsInEntryBlock_l36_kernel_environment, ptr [[DYN_PTR]]) -// CHECK-64-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP0]], -1 -// CHECK-64-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]] -// CHECK-64: user_code.entry: -// CHECK-64-NEXT: [[TMP1:%.*]] = load i32, ptr [[FOO_ADDR]], align 4 -// CHECK-64-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 -// CHECK-64-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -// CHECK-64: if.then: -// CHECK-64-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[PRINTF_ARGS_0]], ptr [[TMP]], i32 0, i32 0 -// CHECK-64-NEXT: store i32 42, ptr [[TMP2]], align 4 -// CHECK-64-NEXT: [[TMP3:%.*]] = call i32 @__llvm_omp_vprintf(ptr @.str2, ptr [[TMP]], i32 4) -// CHECK-64-NEXT: br label [[IF_END]] -// CHECK-64: worker.exit: -// CHECK-64-NEXT: ret void -// CHECK-64: if.end: -// CHECK-64-NEXT: call void @__kmpc_target_deinit() -// CHECK-64-NEXT: ret void -// -// -// CHECK-32-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_CheckSimple_l13 -// CHECK-32-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR0:[0-9]+]] { -// CHECK-32-NEXT: entry: -// CHECK-32-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 4 -// CHECK-32-NEXT: [[FMT:%.*]] = alloca ptr, align 4 -// CHECK-32-NEXT: [[TMP:%.*]] = alloca [[PRINTF_ARGS:%.*]], align 8 -// CHECK-32-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 4 -// CHECK-32-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_target_init(ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_CheckSimple_l13_kernel_environment, ptr [[DYN_PTR]]) -// CHECK-32-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP0]], -1 -// CHECK-32-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]] -// CHECK-32: user_code.entry: -// CHECK-32-NEXT: store ptr @.str, ptr [[FMT]], align 4 -// CHECK-32-NEXT: [[TMP1:%.*]] = load ptr, ptr [[FMT]], align 4 -// CHECK-32-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[PRINTF_ARGS]], ptr [[TMP]], i32 0, i32 0 -// CHECK-32-NEXT: store i32 1, ptr [[TMP2]], align 4 -// CHECK-32-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[PRINTF_ARGS]], ptr [[TMP]], i32 0, i32 1 -// CHECK-32-NEXT: store i64 2, ptr [[TMP3]], align 8 -// CHECK-32-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[PRINTF_ARGS]], ptr [[TMP]], i32 0, i32 2 -// CHECK-32-NEXT: store double 3.000000e+00, ptr [[TMP4]], align 8 -// CHECK-32-NEXT: [[TMP5:%.*]] = call i32 @__llvm_omp_vprintf(ptr [[TMP1]], ptr [[TMP]], i32 24) -// CHECK-32-NEXT: call void @__kmpc_target_deinit() -// CHECK-32-NEXT: ret void -// CHECK-32: worker.exit: -// CHECK-32-NEXT: ret void -// -// -// CHECK-32-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_CheckNoArgs_l25 -// CHECK-32-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR0]] { -// CHECK-32-NEXT: entry: -// CHECK-32-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 4 -// CHECK-32-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 4 -// CHECK-32-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_target_init(ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_CheckNoArgs_l25_kernel_environment, ptr [[DYN_PTR]]) -// CHECK-32-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP0]], -1 -// CHECK-32-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]] -// CHECK-32: user_code.entry: -// CHECK-32-NEXT: [[TMP1:%.*]] = call i32 @__llvm_omp_vprintf(ptr @.str1, ptr null, i32 0) -// CHECK-32-NEXT: call void @__kmpc_target_deinit() -// CHECK-32-NEXT: ret void -// CHECK-32: worker.exit: -// CHECK-32-NEXT: ret void -// -// -// CHECK-32-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_CheckAllocaIsInEntryBlock_l36 -// CHECK-32-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], i32 noundef [[FOO:%.*]]) #[[ATTR0]] { -// CHECK-32-NEXT: entry: -// CHECK-32-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 4 -// CHECK-32-NEXT: [[FOO_ADDR:%.*]] = alloca i32, align 4 -// CHECK-32-NEXT: [[TMP:%.*]] = alloca [[PRINTF_ARGS_0:%.*]], align 8 -// CHECK-32-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 4 -// CHECK-32-NEXT: store i32 [[FOO]], ptr [[FOO_ADDR]], align 4 -// CHECK-32-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_target_init(ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_CheckAllocaIsInEntryBlock_l36_kernel_environment, ptr [[DYN_PTR]]) -// CHECK-32-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP0]], -1 -// CHECK-32-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]] -// CHECK-32: user_code.entry: -// CHECK-32-NEXT: [[TMP1:%.*]] = load i32, ptr [[FOO_ADDR]], align 4 -// CHECK-32-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 -// CHECK-32-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -// CHECK-32: if.then: -// CHECK-32-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[PRINTF_ARGS_0]], ptr [[TMP]], i32 0, i32 0 -// CHECK-32-NEXT: store i32 42, ptr [[TMP2]], align 4 -// CHECK-32-NEXT: [[TMP3:%.*]] = call i32 @__llvm_omp_vprintf(ptr @.str2, ptr [[TMP]], i32 4) -// CHECK-32-NEXT: br label [[IF_END]] -// CHECK-32: worker.exit: -// CHECK-32-NEXT: ret void -// CHECK-32: if.end: -// CHECK-32-NEXT: call void @__kmpc_target_deinit() -// CHECK-32-NEXT: ret void -// diff --git a/clang/test/OpenMP/ompx_attributes_codegen.cpp b/clang/test/OpenMP/ompx_attributes_codegen.cpp index 87eb2913537ba..6c163c1875171 100644 --- a/clang/test/OpenMP/ompx_attributes_codegen.cpp +++ b/clang/test/OpenMP/ompx_attributes_codegen.cpp @@ -3,15 +3,17 @@ // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fopenmp-targets=amdgcn-amd-amdhsa -emit-llvm-bc %s -o %t-ppc-host.bc // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple amdgcn-amd-amdhsa -fopenmp-targets=amdgcn-amd-amdhsa -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix=AMD // RUN: %clang_cc1 -target-cpu gfx900 -fopenmp -x c++ -std=c++11 -triple amdgcn-amd-amdhsa -fopenmp-targets=amdgcn-amd-amdhsa -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix=AMD +// RUN: %clang_cc1 -target-cpu gfx900 -fopenmp -x c++ -std=c++11 -triple amdgcn-amd-amdhsa -fopenmp-targets=amdgcn-amd-amdhsa -dwarf-version=5 -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix=AMD // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple nvptx64 -fopenmp-targets=nvptx64 -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix=NVIDIA +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple nvptx64 -fopenmp-targets=nvptx64 -emit-llvm %s -fopenmp-is-target-device -dwarf-version=5 -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix=NVIDIA // expected-no-diagnostics // Check that the target attributes are set on the generated kernel void func() { - // AMD: amdgpu_kernel void @__omp_offloading[[HASH:.*]]_l16(ptr {{[^,]+}}) #0 - // AMD: amdgpu_kernel void @__omp_offloading[[HASH:.*]]_l18(ptr {{[^,]+}}) - // AMD: amdgpu_kernel void @__omp_offloading[[HASH:.*]]_l20(ptr {{[^,]+}}) #4 + // AMD: amdgpu_kernel void @__omp_offloading[[HASH:.*]]_l18(ptr {{[^,]+}}) #0 + // AMD: amdgpu_kernel void @__omp_offloading[[HASH:.*]]_l20(ptr {{[^,]+}}) + // AMD: amdgpu_kernel void @__omp_offloading[[HASH:.*]]_l22(ptr {{[^,]+}}) #4 #pragma omp target ompx_attribute([[clang::amdgpu_flat_work_group_size(10, 20)]]) {} @@ -35,6 +37,6 @@ void func() { // NVIDIA: "omp_target_thread_limit"="20" // NVIDIA: "omp_target_thread_limit"="45" // NVIDIA: "omp_target_thread_limit"="17" -// NVIDIA: !{ptr @__omp_offloading[[HASH1:.*]]_l16, !"maxntidx", i32 20} -// NVIDIA: !{ptr @__omp_offloading[[HASH2:.*]]_l18, !"maxntidx", i32 45} -// NVIDIA: !{ptr @__omp_offloading[[HASH3:.*]]_l20, !"maxntidx", i32 17} +// NVIDIA: !{ptr @__omp_offloading[[HASH1:.*]]_l18, !"maxntidx", i32 20} +// NVIDIA: !{ptr @__omp_offloading[[HASH2:.*]]_l20, !"maxntidx", i32 45} +// NVIDIA: !{ptr @__omp_offloading[[HASH3:.*]]_l22, !"maxntidx", i32 17} diff --git a/clang/test/OpenMP/parallel_codegen.cpp b/clang/test/OpenMP/parallel_codegen.cpp index 41d43048d6a12..2a0a881b109be 100644 --- a/clang/test/OpenMP/parallel_codegen.cpp +++ b/clang/test/OpenMP/parallel_codegen.cpp @@ -323,8 +323,8 @@ int main (int argc, char **argv) { // CHECK2-NEXT: #dbg_declare(ptr [[__VLA_EXPR0]], [[META24:![0-9]+]], !DIExpression(), [[META26:![0-9]+]]) // CHECK2-NEXT: #dbg_declare(ptr [[VLA]], [[META27:![0-9]+]], !DIExpression(), [[META31:![0-9]+]]) // CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1:[0-9]+]], i32 2, ptr @main.omp_outlined, i64 [[TMP1]], ptr [[VLA]]), !dbg [[DBG32:![0-9]+]] -// CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB5:[0-9]+]], i32 1, ptr @main.omp_outlined.2, i64 [[TMP1]]), !dbg [[DBG33:![0-9]+]] -// CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB9:[0-9]+]], i32 2, ptr @main.omp_outlined.4, i64 [[TMP1]], ptr [[VLA]]), !dbg [[DBG34:![0-9]+]] +// CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB5:[0-9]+]], i32 1, ptr @main.omp_outlined.1, i64 [[TMP1]]), !dbg [[DBG33:![0-9]+]] +// CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB9:[0-9]+]], i32 2, ptr @main.omp_outlined.3, i64 [[TMP1]], ptr [[VLA]]), !dbg [[DBG34:![0-9]+]] // CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8, !dbg [[DBG35:![0-9]+]] // CHECK2-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIPPcEiT_(ptr noundef [[TMP3]]), !dbg [[DBG36:![0-9]+]] // CHECK2-NEXT: store i32 [[CALL]], ptr [[RETVAL]], align 4, !dbg [[DBG37:![0-9]+]] @@ -368,47 +368,47 @@ int main (int argc, char **argv) { // CHECK2-NEXT: unreachable, !dbg [[DBG53]] // // -// CHECK2-LABEL: define {{[^@]+}}@_Z3fooIiEvT_ -// CHECK2-SAME: (i32 noundef [[ARGC:%.*]]) #[[ATTR3:[0-9]+]] comdat !dbg [[DBG58:![0-9]+]] { -// CHECK2-NEXT: entry: -// CHECK2-NEXT: [[ARGC_ADDR:%.*]] = alloca i32, align 4 -// CHECK2-NEXT: store i32 [[ARGC]], ptr [[ARGC_ADDR]], align 4 -// CHECK2-NEXT: #dbg_declare(ptr [[ARGC_ADDR]], [[META63:![0-9]+]], !DIExpression(), [[META64:![0-9]+]]) -// CHECK2-NEXT: ret void, !dbg [[DBG65:![0-9]+]] -// -// -// CHECK2-LABEL: define {{[^@]+}}@__clang_call_terminate -// CHECK2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR4:[0-9]+]] comdat { -// CHECK2-NEXT: [[TMP2:%.*]] = call ptr @__cxa_begin_catch(ptr [[TMP0]]) #[[ATTR5:[0-9]+]] -// CHECK2-NEXT: call void @_ZSt9terminatev() #[[ATTR6]] -// CHECK2-NEXT: unreachable -// -// // CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined -// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR2]] !dbg [[DBG66:![0-9]+]] { +// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR2]] !dbg [[DBG58:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8 // CHECK2-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META67:![0-9]+]], !DIExpression(), [[META68:![0-9]+]]) +// CHECK2-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META59:![0-9]+]], !DIExpression(), [[META60:![0-9]+]]) // CHECK2-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META69:![0-9]+]], !DIExpression(), [[META68]]) +// CHECK2-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META61:![0-9]+]], !DIExpression(), [[META60]]) // CHECK2-NEXT: store i64 [[VLA]], ptr [[VLA_ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[VLA_ADDR]], [[META70:![0-9]+]], !DIExpression(), [[META68]]) +// CHECK2-NEXT: #dbg_declare(ptr [[VLA_ADDR]], [[META62:![0-9]+]], !DIExpression(), [[META60]]) // CHECK2-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META71:![0-9]+]], !DIExpression(), [[META68]]) -// CHECK2-NEXT: [[TMP0:%.*]] = load i64, ptr [[VLA_ADDR]], align 8, !dbg [[DBG72:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG72]] -// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG72]] -// CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG72]] -// CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG72]] -// CHECK2-NEXT: call void @main.omp_outlined_debug__(ptr [[TMP2]], ptr [[TMP3]], i64 [[TMP0]], ptr [[TMP4]]) #[[ATTR5]], !dbg [[DBG72]] -// CHECK2-NEXT: ret void, !dbg [[DBG72]] +// CHECK2-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META63:![0-9]+]], !DIExpression(), [[META60]]) +// CHECK2-NEXT: [[TMP0:%.*]] = load i64, ptr [[VLA_ADDR]], align 8, !dbg [[DBG64:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG64]] +// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG64]] +// CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG64]] +// CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG64]] +// CHECK2-NEXT: call void @main.omp_outlined_debug__(ptr [[TMP2]], ptr [[TMP3]], i64 [[TMP0]], ptr [[TMP4]]) #[[ATTR5:[0-9]+]], !dbg [[DBG64]] +// CHECK2-NEXT: ret void, !dbg [[DBG64]] // // -// CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined_debug__.1 +// CHECK2-LABEL: define {{[^@]+}}@_Z3fooIiEvT_ +// CHECK2-SAME: (i32 noundef [[ARGC:%.*]]) #[[ATTR3:[0-9]+]] comdat !dbg [[DBG65:![0-9]+]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[ARGC_ADDR:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: store i32 [[ARGC]], ptr [[ARGC_ADDR]], align 4 +// CHECK2-NEXT: #dbg_declare(ptr [[ARGC_ADDR]], [[META70:![0-9]+]], !DIExpression(), [[META71:![0-9]+]]) +// CHECK2-NEXT: ret void, !dbg [[DBG72:![0-9]+]] +// +// +// CHECK2-LABEL: define {{[^@]+}}@__clang_call_terminate +// CHECK2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR4:[0-9]+]] comdat { +// CHECK2-NEXT: [[TMP2:%.*]] = call ptr @__cxa_begin_catch(ptr [[TMP0]]) #[[ATTR5]] +// CHECK2-NEXT: call void @_ZSt9terminatev() #[[ATTR6]] +// CHECK2-NEXT: unreachable +// +// +// CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined_debug__.2 // CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]]) #[[ATTR2]] !dbg [[DBG75:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -431,14 +431,33 @@ int main (int argc, char **argv) { // CHECK2-NEXT: store i64 [[TMP0]], ptr [[__VLA_EXPR0]], align 8, !dbg [[DBG82]] // CHECK2-NEXT: #dbg_declare(ptr [[__VLA_EXPR0]], [[META84:![0-9]+]], !DIExpression(), [[META79]]) // CHECK2-NEXT: #dbg_declare(ptr [[VLA1]], [[META85:![0-9]+]], !DIExpression(), [[META79]]) -// CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3:[0-9]+]], i32 3, ptr @main.omp_outlined_debug__.1.omp_outlined, i64 [[TMP0]], ptr [[VLA1]], ptr [[GLOBAL]]), !dbg [[DBG82]] +// CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3:[0-9]+]], i32 3, ptr @main.omp_outlined_debug__.2.omp_outlined, i64 [[TMP0]], ptr [[VLA1]], ptr [[GLOBAL]]), !dbg [[DBG82]] // CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[SAVED_STACK]], align 8, !dbg [[DBG86:![0-9]+]] // CHECK2-NEXT: call void @llvm.stackrestore.p0(ptr [[TMP2]]), !dbg [[DBG86]] // CHECK2-NEXT: ret void, !dbg [[DBG88:![0-9]+]] // // -// CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined_debug__.1.omp_outlined_debug__ -// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[GLOBAL:%.*]]) #[[ATTR2]] personality ptr @__gxx_personality_v0 !dbg [[DBG89:![0-9]+]] { +// CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined.1 +// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]]) #[[ATTR2]] !dbg [[DBG89:![0-9]+]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK2-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META90:![0-9]+]], !DIExpression(), [[META91:![0-9]+]]) +// CHECK2-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK2-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META92:![0-9]+]], !DIExpression(), [[META91]]) +// CHECK2-NEXT: store i64 [[VLA]], ptr [[VLA_ADDR]], align 8 +// CHECK2-NEXT: #dbg_declare(ptr [[VLA_ADDR]], [[META93:![0-9]+]], !DIExpression(), [[META91]]) +// CHECK2-NEXT: [[TMP0:%.*]] = load i64, ptr [[VLA_ADDR]], align 8, !dbg [[DBG94:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG94]] +// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG94]] +// CHECK2-NEXT: call void @main.omp_outlined_debug__.2(ptr [[TMP1]], ptr [[TMP2]], i64 [[TMP0]]) #[[ATTR5]], !dbg [[DBG94]] +// CHECK2-NEXT: ret void, !dbg [[DBG94]] +// +// +// CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined_debug__.2.omp_outlined_debug__ +// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[GLOBAL:%.*]]) #[[ATTR2]] personality ptr @__gxx_personality_v0 !dbg [[DBG95:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -446,37 +465,37 @@ int main (int argc, char **argv) { // CHECK2-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[GLOBAL_ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META92:![0-9]+]], !DIExpression(), [[META93:![0-9]+]]) +// CHECK2-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META98:![0-9]+]], !DIExpression(), [[META99:![0-9]+]]) // CHECK2-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META94:![0-9]+]], !DIExpression(), [[META93]]) +// CHECK2-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META100:![0-9]+]], !DIExpression(), [[META99]]) // CHECK2-NEXT: store i64 [[VLA]], ptr [[VLA_ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[VLA_ADDR]], [[META95:![0-9]+]], !DIExpression(), [[META93]]) +// CHECK2-NEXT: #dbg_declare(ptr [[VLA_ADDR]], [[META101:![0-9]+]], !DIExpression(), [[META99]]) // CHECK2-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META96:![0-9]+]], !DIExpression(), [[META97:![0-9]+]]) +// CHECK2-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META102:![0-9]+]], !DIExpression(), [[META103:![0-9]+]]) // CHECK2-NEXT: store ptr [[GLOBAL]], ptr [[GLOBAL_ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[GLOBAL_ADDR]], [[META98:![0-9]+]], !DIExpression(), [[META99:![0-9]+]]) -// CHECK2-NEXT: [[TMP0:%.*]] = load i64, ptr [[VLA_ADDR]], align 8, !dbg [[DBG100:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG100]] -// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[GLOBAL_ADDR]], align 8, !dbg [[DBG100]] -// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 1, !dbg [[DBG101:![0-9]+]] -// CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !dbg [[DBG101]] +// CHECK2-NEXT: #dbg_declare(ptr [[GLOBAL_ADDR]], [[META104:![0-9]+]], !DIExpression(), [[META105:![0-9]+]]) +// CHECK2-NEXT: [[TMP0:%.*]] = load i64, ptr [[VLA_ADDR]], align 8, !dbg [[DBG106:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG106]] +// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[GLOBAL_ADDR]], align 8, !dbg [[DBG106]] +// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 1, !dbg [[DBG107:![0-9]+]] +// CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !dbg [[DBG107]] // CHECK2-NEXT: invoke void @_Z3fooIiEvT_(i32 noundef [[TMP3]]) -// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG100]] +// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG106]] // CHECK2: invoke.cont: -// CHECK2-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP2]], align 4, !dbg [[DBG102:![0-9]+]] -// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 1, !dbg [[DBG103:![0-9]+]] -// CHECK2-NEXT: store i32 [[TMP4]], ptr [[ARRAYIDX1]], align 4, !dbg [[DBG104:![0-9]+]] -// CHECK2-NEXT: ret void, !dbg [[DBG102]] +// CHECK2-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP2]], align 4, !dbg [[DBG108:![0-9]+]] +// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 1, !dbg [[DBG109:![0-9]+]] +// CHECK2-NEXT: store i32 [[TMP4]], ptr [[ARRAYIDX1]], align 4, !dbg [[DBG110:![0-9]+]] +// CHECK2-NEXT: ret void, !dbg [[DBG108]] // CHECK2: terminate.lpad: // CHECK2-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } -// CHECK2-NEXT: catch ptr null, !dbg [[DBG100]] -// CHECK2-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0, !dbg [[DBG100]] -// CHECK2-NEXT: call void @__clang_call_terminate(ptr [[TMP6]]) #[[ATTR6]], !dbg [[DBG100]] -// CHECK2-NEXT: unreachable, !dbg [[DBG100]] +// CHECK2-NEXT: catch ptr null, !dbg [[DBG106]] +// CHECK2-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0, !dbg [[DBG106]] +// CHECK2-NEXT: call void @__clang_call_terminate(ptr [[TMP6]]) #[[ATTR6]], !dbg [[DBG106]] +// CHECK2-NEXT: unreachable, !dbg [[DBG106]] // // -// CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined_debug__.1.omp_outlined -// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[GLOBAL:%.*]]) #[[ATTR2]] !dbg [[DBG105:![0-9]+]] { +// CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined_debug__.2.omp_outlined +// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[GLOBAL:%.*]]) #[[ATTR2]] !dbg [[DBG111:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -484,46 +503,27 @@ int main (int argc, char **argv) { // CHECK2-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[GLOBAL_ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META106:![0-9]+]], !DIExpression(), [[META107:![0-9]+]]) +// CHECK2-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META112:![0-9]+]], !DIExpression(), [[META113:![0-9]+]]) // CHECK2-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META108:![0-9]+]], !DIExpression(), [[META107]]) +// CHECK2-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META114:![0-9]+]], !DIExpression(), [[META113]]) // CHECK2-NEXT: store i64 [[VLA]], ptr [[VLA_ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[VLA_ADDR]], [[META109:![0-9]+]], !DIExpression(), [[META107]]) +// CHECK2-NEXT: #dbg_declare(ptr [[VLA_ADDR]], [[META115:![0-9]+]], !DIExpression(), [[META113]]) // CHECK2-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META110:![0-9]+]], !DIExpression(), [[META107]]) +// CHECK2-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META116:![0-9]+]], !DIExpression(), [[META113]]) // CHECK2-NEXT: store ptr [[GLOBAL]], ptr [[GLOBAL_ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[GLOBAL_ADDR]], [[META111:![0-9]+]], !DIExpression(), [[META107]]) -// CHECK2-NEXT: [[TMP0:%.*]] = load i64, ptr [[VLA_ADDR]], align 8, !dbg [[DBG112:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG112]] -// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[GLOBAL_ADDR]], align 8, !dbg [[DBG112]] -// CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG112]] -// CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG112]] -// CHECK2-NEXT: [[TMP5:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG112]] -// CHECK2-NEXT: [[TMP6:%.*]] = load ptr, ptr [[GLOBAL_ADDR]], align 8, !dbg [[DBG112]] -// CHECK2-NEXT: call void @main.omp_outlined_debug__.1.omp_outlined_debug__(ptr [[TMP3]], ptr [[TMP4]], i64 [[TMP0]], ptr [[TMP5]], ptr [[TMP6]]) #[[ATTR5]], !dbg [[DBG112]] -// CHECK2-NEXT: ret void, !dbg [[DBG112]] -// -// -// CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined.2 -// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]]) #[[ATTR2]] !dbg [[DBG113:![0-9]+]] { -// CHECK2-NEXT: entry: -// CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 -// CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 -// CHECK2-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8 -// CHECK2-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META114:![0-9]+]], !DIExpression(), [[META115:![0-9]+]]) -// CHECK2-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META116:![0-9]+]], !DIExpression(), [[META115]]) -// CHECK2-NEXT: store i64 [[VLA]], ptr [[VLA_ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[VLA_ADDR]], [[META117:![0-9]+]], !DIExpression(), [[META115]]) +// CHECK2-NEXT: #dbg_declare(ptr [[GLOBAL_ADDR]], [[META117:![0-9]+]], !DIExpression(), [[META113]]) // CHECK2-NEXT: [[TMP0:%.*]] = load i64, ptr [[VLA_ADDR]], align 8, !dbg [[DBG118:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG118]] -// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG118]] -// CHECK2-NEXT: call void @main.omp_outlined_debug__.1(ptr [[TMP1]], ptr [[TMP2]], i64 [[TMP0]]) #[[ATTR5]], !dbg [[DBG118]] +// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG118]] +// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[GLOBAL_ADDR]], align 8, !dbg [[DBG118]] +// CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG118]] +// CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG118]] +// CHECK2-NEXT: [[TMP5:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG118]] +// CHECK2-NEXT: [[TMP6:%.*]] = load ptr, ptr [[GLOBAL_ADDR]], align 8, !dbg [[DBG118]] +// CHECK2-NEXT: call void @main.omp_outlined_debug__.2.omp_outlined_debug__(ptr [[TMP3]], ptr [[TMP4]], i64 [[TMP0]], ptr [[TMP5]], ptr [[TMP6]]) #[[ATTR5]], !dbg [[DBG118]] // CHECK2-NEXT: ret void, !dbg [[DBG118]] // // -// CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined_debug__.3 +// CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined_debug__.4 // CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR2]] !dbg [[DBG119:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -540,12 +540,12 @@ int main (int argc, char **argv) { // CHECK2-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META124:![0-9]+]], !DIExpression(), [[META125:![0-9]+]]) // CHECK2-NEXT: [[TMP0:%.*]] = load i64, ptr [[VLA_ADDR]], align 8, !dbg [[DBG126:![0-9]+]] // CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG126]] -// CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB7:[0-9]+]], i32 2, ptr @main.omp_outlined_debug__.3.omp_outlined, i64 [[TMP0]], ptr [[TMP1]]), !dbg [[DBG126]] +// CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB7:[0-9]+]], i32 2, ptr @main.omp_outlined_debug__.4.omp_outlined, i64 [[TMP0]], ptr [[TMP1]]), !dbg [[DBG126]] // CHECK2-NEXT: ret void, !dbg [[DBG127:![0-9]+]] // // -// CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined_debug__.3.omp_outlined_debug__ -// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR2]] personality ptr @__gxx_personality_v0 !dbg [[DBG128:![0-9]+]] { +// CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined.3 +// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR2]] !dbg [[DBG128:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -558,51 +558,51 @@ int main (int argc, char **argv) { // CHECK2-NEXT: store i64 [[VLA]], ptr [[VLA_ADDR]], align 8 // CHECK2-NEXT: #dbg_declare(ptr [[VLA_ADDR]], [[META132:![0-9]+]], !DIExpression(), [[META130]]) // CHECK2-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META133:![0-9]+]], !DIExpression(), [[META134:![0-9]+]]) -// CHECK2-NEXT: [[TMP0:%.*]] = load i64, ptr [[VLA_ADDR]], align 8, !dbg [[DBG135:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG135]] -// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 1, !dbg [[DBG136:![0-9]+]] -// CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !dbg [[DBG136]] -// CHECK2-NEXT: invoke void @_Z3fooIiEvT_(i32 noundef [[TMP2]]) -// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG135]] -// CHECK2: invoke.cont: -// CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr @global, align 4, !dbg [[DBG137:![0-9]+]] -// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 1, !dbg [[DBG138:![0-9]+]] -// CHECK2-NEXT: store i32 [[TMP3]], ptr [[ARRAYIDX1]], align 4, !dbg [[DBG139:![0-9]+]] -// CHECK2-NEXT: ret void, !dbg [[DBG137]] -// CHECK2: terminate.lpad: -// CHECK2-NEXT: [[TMP4:%.*]] = landingpad { ptr, i32 } -// CHECK2-NEXT: catch ptr null, !dbg [[DBG135]] -// CHECK2-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 0, !dbg [[DBG135]] -// CHECK2-NEXT: call void @__clang_call_terminate(ptr [[TMP5]]) #[[ATTR6]], !dbg [[DBG135]] -// CHECK2-NEXT: unreachable, !dbg [[DBG135]] -// -// -// CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined_debug__.3.omp_outlined -// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR2]] !dbg [[DBG140:![0-9]+]] { +// CHECK2-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META133:![0-9]+]], !DIExpression(), [[META130]]) +// CHECK2-NEXT: [[TMP0:%.*]] = load i64, ptr [[VLA_ADDR]], align 8, !dbg [[DBG134:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG134]] +// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG134]] +// CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG134]] +// CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG134]] +// CHECK2-NEXT: call void @main.omp_outlined_debug__.4(ptr [[TMP2]], ptr [[TMP3]], i64 [[TMP0]], ptr [[TMP4]]) #[[ATTR5]], !dbg [[DBG134]] +// CHECK2-NEXT: ret void, !dbg [[DBG134]] +// +// +// CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined_debug__.4.omp_outlined_debug__ +// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR2]] personality ptr @__gxx_personality_v0 !dbg [[DBG135:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8 // CHECK2-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META141:![0-9]+]], !DIExpression(), [[META142:![0-9]+]]) +// CHECK2-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META136:![0-9]+]], !DIExpression(), [[META137:![0-9]+]]) // CHECK2-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META143:![0-9]+]], !DIExpression(), [[META142]]) +// CHECK2-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META138:![0-9]+]], !DIExpression(), [[META137]]) // CHECK2-NEXT: store i64 [[VLA]], ptr [[VLA_ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[VLA_ADDR]], [[META144:![0-9]+]], !DIExpression(), [[META142]]) +// CHECK2-NEXT: #dbg_declare(ptr [[VLA_ADDR]], [[META139:![0-9]+]], !DIExpression(), [[META137]]) // CHECK2-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META145:![0-9]+]], !DIExpression(), [[META142]]) -// CHECK2-NEXT: [[TMP0:%.*]] = load i64, ptr [[VLA_ADDR]], align 8, !dbg [[DBG146:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG146]] -// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG146]] -// CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG146]] -// CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG146]] -// CHECK2-NEXT: call void @main.omp_outlined_debug__.3.omp_outlined_debug__(ptr [[TMP2]], ptr [[TMP3]], i64 [[TMP0]], ptr [[TMP4]]) #[[ATTR5]], !dbg [[DBG146]] -// CHECK2-NEXT: ret void, !dbg [[DBG146]] +// CHECK2-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META140:![0-9]+]], !DIExpression(), [[META141:![0-9]+]]) +// CHECK2-NEXT: [[TMP0:%.*]] = load i64, ptr [[VLA_ADDR]], align 8, !dbg [[DBG142:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG142]] +// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 1, !dbg [[DBG143:![0-9]+]] +// CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !dbg [[DBG143]] +// CHECK2-NEXT: invoke void @_Z3fooIiEvT_(i32 noundef [[TMP2]]) +// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG142]] +// CHECK2: invoke.cont: +// CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr @global, align 4, !dbg [[DBG144:![0-9]+]] +// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 1, !dbg [[DBG145:![0-9]+]] +// CHECK2-NEXT: store i32 [[TMP3]], ptr [[ARRAYIDX1]], align 4, !dbg [[DBG146:![0-9]+]] +// CHECK2-NEXT: ret void, !dbg [[DBG144]] +// CHECK2: terminate.lpad: +// CHECK2-NEXT: [[TMP4:%.*]] = landingpad { ptr, i32 } +// CHECK2-NEXT: catch ptr null, !dbg [[DBG142]] +// CHECK2-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 0, !dbg [[DBG142]] +// CHECK2-NEXT: call void @__clang_call_terminate(ptr [[TMP5]]) #[[ATTR6]], !dbg [[DBG142]] +// CHECK2-NEXT: unreachable, !dbg [[DBG142]] // // -// CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined.4 +// CHECK2-LABEL: define {{[^@]+}}@main.omp_outlined_debug__.4.omp_outlined // CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR2]] !dbg [[DBG147:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -622,7 +622,7 @@ int main (int argc, char **argv) { // CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG153]] // CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG153]] // CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG153]] -// CHECK2-NEXT: call void @main.omp_outlined_debug__.3(ptr [[TMP2]], ptr [[TMP3]], i64 [[TMP0]], ptr [[TMP4]]) #[[ATTR5]], !dbg [[DBG153]] +// CHECK2-NEXT: call void @main.omp_outlined_debug__.4.omp_outlined_debug__(ptr [[TMP2]], ptr [[TMP3]], i64 [[TMP0]], ptr [[TMP4]]) #[[ATTR5]], !dbg [[DBG153]] // CHECK2-NEXT: ret void, !dbg [[DBG153]] // // @@ -678,37 +678,37 @@ int main (int argc, char **argv) { // CHECK2-NEXT: unreachable, !dbg [[DBG178]] // // -// CHECK2-LABEL: define {{[^@]+}}@_Z3fooIPPcEvT_ -// CHECK2-SAME: (ptr noundef [[ARGC:%.*]]) #[[ATTR3]] comdat !dbg [[DBG189:![0-9]+]] { -// CHECK2-NEXT: entry: -// CHECK2-NEXT: [[ARGC_ADDR:%.*]] = alloca ptr, align 8 -// CHECK2-NEXT: store ptr [[ARGC]], ptr [[ARGC_ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[ARGC_ADDR]], [[META192:![0-9]+]], !DIExpression(), [[META193:![0-9]+]]) -// CHECK2-NEXT: ret void, !dbg [[DBG194:![0-9]+]] -// -// // CHECK2-LABEL: define {{[^@]+}}@_Z5tmainIPPcEiT_.omp_outlined -// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 8 dereferenceable(8) [[ARGC:%.*]], i64 noundef [[VLA:%.*]]) #[[ATTR2]] !dbg [[DBG195:![0-9]+]] { +// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 8 dereferenceable(8) [[ARGC:%.*]], i64 noundef [[VLA:%.*]]) #[[ATTR2]] !dbg [[DBG189:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[ARGC_ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8 // CHECK2-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META196:![0-9]+]], !DIExpression(), [[META197:![0-9]+]]) +// CHECK2-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META190:![0-9]+]], !DIExpression(), [[META191:![0-9]+]]) // CHECK2-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META198:![0-9]+]], !DIExpression(), [[META197]]) +// CHECK2-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META192:![0-9]+]], !DIExpression(), [[META191]]) // CHECK2-NEXT: store ptr [[ARGC]], ptr [[ARGC_ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[ARGC_ADDR]], [[META199:![0-9]+]], !DIExpression(), [[META197]]) +// CHECK2-NEXT: #dbg_declare(ptr [[ARGC_ADDR]], [[META193:![0-9]+]], !DIExpression(), [[META191]]) // CHECK2-NEXT: store i64 [[VLA]], ptr [[VLA_ADDR]], align 8 -// CHECK2-NEXT: #dbg_declare(ptr [[VLA_ADDR]], [[META200:![0-9]+]], !DIExpression(), [[META197]]) -// CHECK2-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGC_ADDR]], align 8, !dbg [[DBG201:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load i64, ptr [[VLA_ADDR]], align 8, !dbg [[DBG201]] -// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG201]] -// CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG201]] -// CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARGC_ADDR]], align 8, !dbg [[DBG201]] -// CHECK2-NEXT: call void @_Z5tmainIPPcEiT_.omp_outlined_debug__(ptr [[TMP2]], ptr [[TMP3]], ptr [[TMP4]], i64 [[TMP1]]) #[[ATTR5]], !dbg [[DBG201]] -// CHECK2-NEXT: ret void, !dbg [[DBG201]] +// CHECK2-NEXT: #dbg_declare(ptr [[VLA_ADDR]], [[META194:![0-9]+]], !DIExpression(), [[META191]]) +// CHECK2-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGC_ADDR]], align 8, !dbg [[DBG195:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load i64, ptr [[VLA_ADDR]], align 8, !dbg [[DBG195]] +// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG195]] +// CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG195]] +// CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARGC_ADDR]], align 8, !dbg [[DBG195]] +// CHECK2-NEXT: call void @_Z5tmainIPPcEiT_.omp_outlined_debug__(ptr [[TMP2]], ptr [[TMP3]], ptr [[TMP4]], i64 [[TMP1]]) #[[ATTR5]], !dbg [[DBG195]] +// CHECK2-NEXT: ret void, !dbg [[DBG195]] +// +// +// CHECK2-LABEL: define {{[^@]+}}@_Z3fooIPPcEvT_ +// CHECK2-SAME: (ptr noundef [[ARGC:%.*]]) #[[ATTR3]] comdat !dbg [[DBG196:![0-9]+]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[ARGC_ADDR:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: store ptr [[ARGC]], ptr [[ARGC_ADDR]], align 8 +// CHECK2-NEXT: #dbg_declare(ptr [[ARGC_ADDR]], [[META199:![0-9]+]], !DIExpression(), [[META200:![0-9]+]]) +// CHECK2-NEXT: ret void, !dbg [[DBG201:![0-9]+]] // // // CHECK3-LABEL: define {{[^@]+}}@main diff --git a/clang/test/OpenMP/reverse_ast_print.cpp b/clang/test/OpenMP/reverse_ast_print.cpp new file mode 100644 index 0000000000000..3ff6d18cfdf8b --- /dev/null +++ b/clang/test/OpenMP/reverse_ast_print.cpp @@ -0,0 +1,159 @@ +// Check no warnings/errors +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=60 -fsyntax-only -verify %s +// expected-no-diagnostics + +// Check AST and unparsing +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=60 -ast-dump %s | FileCheck %s --check-prefix=DUMP +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=60 -ast-print %s | FileCheck %s --check-prefix=PRINT + +// Check same results after serialization round-trip +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=60 -emit-pch -o %t %s +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=60 -include-pch %t -ast-dump-all %s | FileCheck %s --check-prefix=DUMP +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=60 -include-pch %t -ast-print %s | FileCheck %s --check-prefix=PRINT + +#ifndef HEADER +#define HEADER + +// placeholder for loop body code. +extern "C" void body(...); + +// PRINT-LABEL: void foo1( +// DUMP-LABEL: FunctionDecl {{.*}} foo1 +void foo1() { + // PRINT: #pragma omp reverse + // DUMP: OMPReverseDirective + #pragma omp reverse + // PRINT: for (int i = 7; i < 17; i += 3) + // DUMP-NEXT: ForStmt + for (int i = 7; i < 17; i += 3) + // PRINT: body(i); + // DUMP: CallExpr + body(i); +} + + +// PRINT-LABEL: void foo2( +// DUMP-LABEL: FunctionDecl {{.*}} foo2 +void foo2(int start, int end, int step) { + // PRINT: #pragma omp reverse + // DUMP: OMPReverseDirective + #pragma omp reverse + // PRINT: for (int i = start; i < end; i += step) + // DUMP-NEXT: ForStmt + for (int i = start; i < end; i += step) + // PRINT: body(i); + // DUMP: CallExpr + body(i); +} + + +// PRINT-LABEL: void foo3( +// DUMP-LABEL: FunctionDecl {{.*}} foo3 +void foo3() { + // PRINT: #pragma omp for + // DUMP: OMPForDirective + // DUMP-NEXT: CapturedStmt + // DUMP-NEXT: CapturedDecl + #pragma omp for + // PRINT: #pragma omp reverse + // DUMP-NEXT: OMPReverseDirective + #pragma omp reverse + for (int i = 7; i < 17; i += 3) + // PRINT: body(i); + // DUMP: CallExpr + body(i); +} + + +// PRINT-LABEL: void foo4( +// DUMP-LABEL: FunctionDecl {{.*}} foo4 +void foo4() { + // PRINT: #pragma omp for collapse(2) + // DUMP: OMPForDirective + // DUMP-NEXT: OMPCollapseClause + // DUMP-NEXT: ConstantExpr + // DUMP-NEXT: value: Int 2 + // DUMP-NEXT: IntegerLiteral {{.*}} 2 + // DUMP-NEXT: CapturedStmt + // DUMP-NEXT: CapturedDecl + #pragma omp for collapse(2) + // PRINT: #pragma omp reverse + // DUMP: OMPReverseDirective + #pragma omp reverse + // PRINT: for (int i = 7; i < 17; i += 1) + // DUMP-NEXT: ForStmt + for (int i = 7; i < 17; i += 1) + // PRINT: for (int j = 7; j < 17; j += 1) + // DUMP: ForStmt + for (int j = 7; j < 17; j += 1) + // PRINT: body(i, j); + // DUMP: CallExpr + body(i, j); +} + + +// PRINT-LABEL: void foo5( +// DUMP-LABEL: FunctionDecl {{.*}} foo5 +void foo5(int start, int end, int step) { + // PRINT: #pragma omp for collapse(2) + // DUMP: OMPForDirective + // DUMP-NEXT: OMPCollapseClause + // DUMP-NEXT: ConstantExpr + // DUMP-NEXT: value: Int 2 + // DUMP-NEXT: IntegerLiteral {{.*}} 2 + // DUMP-NEXT: CapturedStmt + // DUMP-NEXT: CapturedDecl + #pragma omp for collapse(2) + // PRINT: for (int i = 7; i < 17; i += 1) + // DUMP-NEXT: ForStmt + for (int i = 7; i < 17; i += 1) + // PRINT: #pragma omp reverse + // DUMP: OMPReverseDirective + #pragma omp reverse + // PRINT: for (int j = 7; j < 17; j += 1) + // DUMP-NEXT: ForStmt + for (int j = 7; j < 17; j += 1) + // PRINT: body(i, j); + // DUMP: CallExpr + body(i, j); +} + + +// PRINT-LABEL: void foo6( +// DUMP-LABEL: FunctionTemplateDecl {{.*}} foo6 +template +void foo6(T start, T end) { + // PRINT: #pragma omp reverse + // DUMP: OMPReverseDirective + #pragma omp reverse + // PRINT-NEXT: for (T i = start; i < end; i += Step) + // DUMP-NEXT: ForStmt + for (T i = start; i < end; i += Step) + // PRINT-NEXT: body(i); + // DUMP: CallExpr + body(i); +} + +// Also test instantiating the template. +void tfoo6() { + foo6(0, 42); +} + + +// PRINT-LABEL: void foo7( +// DUMP-LABEL: FunctionDecl {{.*}} foo7 +void foo7() { + double arr[128]; + // PRINT: #pragma omp reverse + // DUMP: OMPReverseDirective + #pragma omp reverse + // PRINT-NEXT: for (auto &&v : arr) + // DUMP-NEXT: CXXForRangeStmt + for (auto &&v : arr) + // PRINT-NEXT: body(v); + // DUMP: CallExpr + body(v); +} + +#endif + diff --git a/clang/test/OpenMP/reverse_codegen.cpp b/clang/test/OpenMP/reverse_codegen.cpp new file mode 100644 index 0000000000000..9adaa6cc7d18d --- /dev/null +++ b/clang/test/OpenMP/reverse_codegen.cpp @@ -0,0 +1,1554 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ + +// expected-no-diagnostics + +// Check code generation +// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -std=c++20 -fclang-abi-compat=latest -fopenmp -fopenmp-version=60 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1 + +// Check same results after serialization round-trip +// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -std=c++20 -fclang-abi-compat=latest -fopenmp -fopenmp-version=60 -emit-pch -o %t %s +// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -std=c++20 -fclang-abi-compat=latest -fopenmp -fopenmp-version=60 -include-pch %t -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK2 + +#ifndef HEADER +#define HEADER + +// placeholder for loop body code. +extern "C" void body(...) {} + + +struct S { + int i; + S() { +#pragma omp reverse + for (i = 7; i < 17; i += 3) + body(i); + } +} s; + + +extern "C" void foo1(int start, int end, int step) { + int i; +#pragma omp reverse + for (i = start; i < end; i += step) + body(i); +} + + +extern "C" void foo2() { +#pragma omp for +#pragma omp reverse + for (int i = 7; i < 17; i += 3) + body(i); +} + + +extern "C" void foo3() { +#pragma omp for collapse(3) + for (int k = 7; k < 17; k += 3) +#pragma omp reverse + for (int i = 7; i < 17; i += 3) + for (int j = 7; j < 17; j += 3) + body(k, i, j); +} + + +extern "C" void foo4() { +#pragma omp parallel for +#pragma omp reverse + for (int i = 7; i < 17; i += 3) + body(i); +} + + +template +void foo5(T start, T end) { +#pragma omp reverse + for (T i = start; i < end; i += Step) + body(i); +} + +extern "C" void tfoo5() { + foo5(0, 42); +} + + +extern "C" void foo6() { + double arr[128]; +#pragma omp reverse + for (int c = 42; auto && v : arr) + body(v, c); +} + + +extern "C" void foo7() { + double A[128]; + +#pragma omp for collapse(3) + for (int k = 7; k < 17; k += 3) +#pragma omp reverse + for (int c = 42; auto && v : A) + for (int j = 7; j < 17; j += 3) + body(k, c, v, j); +} + +#endif /* HEADER */ + +// CHECK1-LABEL: define {{[^@]+}}@body +// CHECK1-SAME: (...) #[[ATTR0:[0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@__cxx_global_var_init +// CHECK1-SAME: () #[[ATTR1:[0-9]+]] section ".text.startup" { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: call void @_ZN1SC1Ev(ptr noundef nonnull align 4 dereferenceable(4) @s) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_ZN1SC1Ev +// CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR0]] comdat align 2 { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK1-NEXT: call void @_ZN1SC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_ZN1SC2Ev +// CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR0]] comdat align 2 { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[I2:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK1-NEXT: [[I:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0 +// CHECK1-NEXT: store i32 7, ptr [[I]], align 4 +// CHECK1-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 +// CHECK1-NEXT: store ptr [[I3]], ptr [[I2]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: br label [[FOR_COND:%.*]] +// CHECK1: for.cond: +// CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 4 +// CHECK1-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +// CHECK1: for.body: +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: [[SUB:%.*]] = sub nsw i32 3, [[TMP1]] +// CHECK1-NEXT: store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP2]], 3 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 7, [[MUL]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[I2]], align 8 +// CHECK1-NEXT: store i32 [[ADD]], ptr [[TMP3]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[I2]], align 8 +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4 +// CHECK1-NEXT: call void (...) @body(i32 noundef [[TMP5]]) +// CHECK1-NEXT: br label [[FOR_INC:%.*]] +// CHECK1: for.inc: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: [[INC:%.*]] = add nsw i32 [[TMP6]], 1 +// CHECK1-NEXT: store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP3:![0-9]+]] +// CHECK1: for.end: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@foo1 +// CHECK1-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]], i32 noundef [[STEP:%.*]]) #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[START_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[END_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[STEP_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTNEW_STEP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_2:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store i32 [[START]], ptr [[START_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[END]], ptr [[END_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[STEP]], ptr [[STEP_ADDR]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr [[START_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP0]], ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[START_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[END_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP2]], ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[STEP_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP3]], ptr [[DOTNEW_STEP]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK1-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], [[TMP5]] +// CHECK1-NEXT: [[SUB3:%.*]] = sub i32 [[SUB]], 1 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 +// CHECK1-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], [[TMP6]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 +// CHECK1-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], [[TMP7]] +// CHECK1-NEXT: [[SUB4:%.*]] = sub i32 [[DIV]], 1 +// CHECK1-NEXT: store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: br label [[FOR_COND:%.*]] +// CHECK1: for.cond: +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: [[ADD5:%.*]] = add i32 [[TMP9]], 1 +// CHECK1-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP8]], [[ADD5]] +// CHECK1-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +// CHECK1: for.body: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: [[ADD6:%.*]] = add i32 [[TMP10]], 1 +// CHECK1-NEXT: [[SUB7:%.*]] = sub i32 [[ADD6]], 1 +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: [[SUB8:%.*]] = sub i32 [[SUB7]], [[TMP11]] +// CHECK1-NEXT: store i32 [[SUB8]], ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul i32 [[TMP13]], [[TMP14]] +// CHECK1-NEXT: [[ADD9:%.*]] = add i32 [[TMP12]], [[MUL]] +// CHECK1-NEXT: store i32 [[ADD9]], ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4 +// CHECK1-NEXT: call void (...) @body(i32 noundef [[TMP15]]) +// CHECK1-NEXT: br label [[FOR_INC:%.*]] +// CHECK1: for.inc: +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: [[INC:%.*]] = add i32 [[TMP16]], 1 +// CHECK1-NEXT: store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP5:![0-9]+]] +// CHECK1: for.end: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@foo2 +// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2:[0-9]+]]) +// CHECK1-NEXT: store i32 7, ptr [[I]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 3 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 3, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP6]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: [[SUB:%.*]] = sub nsw i32 3, [[TMP7]] +// CHECK1-NEXT: store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK1-NEXT: [[MUL2:%.*]] = mul nsw i32 [[TMP8]], 3 +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 7, [[MUL2]] +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[I]], align 4 +// CHECK1-NEXT: call void (...) @body(i32 noundef [[TMP9]]) +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]]) +// CHECK1-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3:[0-9]+]], i32 [[TMP0]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@foo3 +// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[K:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[J:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]]) +// CHECK1-NEXT: store i32 7, ptr [[I]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 63, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 63 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 63, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP3:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]] +// CHECK1-NEXT: br i1 [[CMP3]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP6]], 16 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[DIV]], 3 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 7, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[K]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[DIV4:%.*]] = sdiv i32 [[TMP8]], 16 +// CHECK1-NEXT: [[MUL5:%.*]] = mul nsw i32 [[DIV4]], 16 +// CHECK1-NEXT: [[SUB:%.*]] = sub nsw i32 [[TMP7]], [[MUL5]] +// CHECK1-NEXT: [[DIV6:%.*]] = sdiv i32 [[SUB]], 4 +// CHECK1-NEXT: [[MUL7:%.*]] = mul nsw i32 [[DIV6]], 1 +// CHECK1-NEXT: [[ADD8:%.*]] = add nsw i32 0, [[MUL7]] +// CHECK1-NEXT: store i32 [[ADD8]], ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[DIV9:%.*]] = sdiv i32 [[TMP10]], 16 +// CHECK1-NEXT: [[MUL10:%.*]] = mul nsw i32 [[DIV9]], 16 +// CHECK1-NEXT: [[SUB11:%.*]] = sub nsw i32 [[TMP9]], [[MUL10]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[DIV12:%.*]] = sdiv i32 [[TMP12]], 16 +// CHECK1-NEXT: [[MUL13:%.*]] = mul nsw i32 [[DIV12]], 16 +// CHECK1-NEXT: [[SUB14:%.*]] = sub nsw i32 [[TMP11]], [[MUL13]] +// CHECK1-NEXT: [[DIV15:%.*]] = sdiv i32 [[SUB14]], 4 +// CHECK1-NEXT: [[MUL16:%.*]] = mul nsw i32 [[DIV15]], 4 +// CHECK1-NEXT: [[SUB17:%.*]] = sub nsw i32 [[SUB11]], [[MUL16]] +// CHECK1-NEXT: [[MUL18:%.*]] = mul nsw i32 [[SUB17]], 3 +// CHECK1-NEXT: [[ADD19:%.*]] = add nsw i32 7, [[MUL18]] +// CHECK1-NEXT: store i32 [[ADD19]], ptr [[J]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: [[SUB20:%.*]] = sub nsw i32 3, [[TMP13]] +// CHECK1-NEXT: store i32 [[SUB20]], ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK1-NEXT: [[MUL21:%.*]] = mul nsw i32 [[TMP14]], 3 +// CHECK1-NEXT: [[ADD22:%.*]] = add nsw i32 7, [[MUL21]] +// CHECK1-NEXT: store i32 [[ADD22]], ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[K]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[J]], align 4 +// CHECK1-NEXT: call void (...) @body(i32 noundef [[TMP15]], i32 noundef [[TMP16]], i32 noundef [[TMP17]]) +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD23:%.*]] = add nsw i32 [[TMP18]], 1 +// CHECK1-NEXT: store i32 [[ADD23]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]]) +// CHECK1-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@foo4 +// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 0, ptr @foo4.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@foo4.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR4:[0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 7, ptr [[I]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 3 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 3, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: [[SUB:%.*]] = sub nsw i32 3, [[TMP8]] +// CHECK1-NEXT: store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK1-NEXT: [[MUL2:%.*]] = mul nsw i32 [[TMP9]], 3 +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 7, [[MUL2]] +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[I]], align 4 +// CHECK1-NEXT: call void (...) @body(i32 noundef [[TMP10]]) +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK1-NEXT: store i32 [[ADD4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@tfoo5 +// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: call void @_Z4foo5IiTnT_Li3EEvS0_S0_(i32 noundef 0, i32 noundef 42) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_Z4foo5IiTnT_Li3EEvS0_S0_ +// CHECK1-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]]) #[[ATTR0]] comdat { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[START_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[END_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_2:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store i32 [[START]], ptr [[START_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[END]], ptr [[END_ADDR]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr [[START_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP0]], ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[START_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[END_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP2]], ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK1-NEXT: [[SUB:%.*]] = sub i32 [[TMP3]], [[TMP4]] +// CHECK1-NEXT: [[SUB3:%.*]] = sub i32 [[SUB]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], 3 +// CHECK1-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], 3 +// CHECK1-NEXT: [[SUB4:%.*]] = sub i32 [[DIV]], 1 +// CHECK1-NEXT: store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: br label [[FOR_COND:%.*]] +// CHECK1: for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: [[ADD5:%.*]] = add i32 [[TMP6]], 1 +// CHECK1-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP5]], [[ADD5]] +// CHECK1-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +// CHECK1: for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: [[ADD6:%.*]] = add i32 [[TMP7]], 1 +// CHECK1-NEXT: [[SUB7:%.*]] = sub i32 [[ADD6]], 1 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: [[SUB8:%.*]] = sub i32 [[SUB7]], [[TMP8]] +// CHECK1-NEXT: store i32 [[SUB8]], ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul i32 [[TMP10]], 3 +// CHECK1-NEXT: [[ADD9:%.*]] = add i32 [[TMP9]], [[MUL]] +// CHECK1-NEXT: store i32 [[ADD9]], ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[I]], align 4 +// CHECK1-NEXT: call void (...) @body(i32 noundef [[TMP11]]) +// CHECK1-NEXT: br label [[FOR_INC:%.*]] +// CHECK1: for.inc: +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: [[INC:%.*]] = add i32 [[TMP12]], 1 +// CHECK1-NEXT: store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK1-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP8:![0-9]+]] +// CHECK1: for.end: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@foo6 +// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARR:%.*]] = alloca [128 x double], align 16 +// CHECK1-NEXT: [[C:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[__RANGE2:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[__END2:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[__BEGIN2:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_3:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTFORWARD_IV___BEGIN2:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTREVERSED_IV___BEGIN2:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[V:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store i32 42, ptr [[C]], align 4 +// CHECK1-NEXT: store ptr [[ARR]], ptr [[__RANGE2]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP0]], i64 0, i64 0 +// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 128 +// CHECK1-NEXT: store ptr [[ADD_PTR]], ptr [[__END2]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP1]], i64 0, i64 0 +// CHECK1-NEXT: store ptr [[ARRAYDECAY1]], ptr [[__BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY2:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP2]], i64 0, i64 0 +// CHECK1-NEXT: store ptr [[ARRAYDECAY2]], ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__END2]], align 8 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[DOTCAPTURE_EXPR_3]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_3]], align 8 +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[TMP4]] to i64 +// CHECK1-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[TMP5]] to i64 +// CHECK1-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]] +// CHECK1-NEXT: [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8 +// CHECK1-NEXT: [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i64 [[SUB]], 1 +// CHECK1-NEXT: [[DIV:%.*]] = sdiv i64 [[ADD]], 1 +// CHECK1-NEXT: [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1 +// CHECK1-NEXT: store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK1-NEXT: store i64 0, ptr [[DOTFORWARD_IV___BEGIN2]], align 8 +// CHECK1-NEXT: br label [[FOR_COND:%.*]] +// CHECK1: for.cond: +// CHECK1-NEXT: [[TMP6:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK1-NEXT: [[ADD6:%.*]] = add nsw i64 [[TMP7]], 1 +// CHECK1-NEXT: [[CMP:%.*]] = icmp slt i64 [[TMP6]], [[ADD6]] +// CHECK1-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +// CHECK1: for.body: +// CHECK1-NEXT: [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK1-NEXT: [[ADD7:%.*]] = add nsw i64 [[TMP8]], 1 +// CHECK1-NEXT: [[SUB8:%.*]] = sub nsw i64 [[ADD7]], 1 +// CHECK1-NEXT: [[TMP9:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[SUB9:%.*]] = sub nsw i64 [[SUB8]], [[TMP9]] +// CHECK1-NEXT: store i64 [[SUB9]], ptr [[DOTREVERSED_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = load i64, ptr [[DOTREVERSED_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i64 [[TMP11]], 1 +// CHECK1-NEXT: [[ADD_PTR10:%.*]] = getelementptr inbounds double, ptr [[TMP10]], i64 [[MUL]] +// CHECK1-NEXT: store ptr [[ADD_PTR10]], ptr [[__BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[__BEGIN2]], align 8 +// CHECK1-NEXT: store ptr [[TMP12]], ptr [[V]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = load ptr, ptr [[V]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = load double, ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[C]], align 4 +// CHECK1-NEXT: call void (...) @body(double noundef [[TMP14]], i32 noundef [[TMP15]]) +// CHECK1-NEXT: br label [[FOR_INC:%.*]] +// CHECK1: for.inc: +// CHECK1-NEXT: [[TMP16:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[INC:%.*]] = add nsw i64 [[TMP16]], 1 +// CHECK1-NEXT: store i64 [[INC]], ptr [[DOTFORWARD_IV___BEGIN2]], align 8 +// CHECK1-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK1: for.end: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@foo7 +// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[A:%.*]] = alloca [128 x double], align 16 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[_TMP1:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[C:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[__RANGE3:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[__END3:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[__BEGIN3:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_5:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_6:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_8:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_10:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[K:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTFORWARD_IV___BEGIN3:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[J:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[K15:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTFORWARD_IV___BEGIN316:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[J17:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTREVERSED_IV___BEGIN3:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[V:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]]) +// CHECK1-NEXT: store i32 42, ptr [[C]], align 4 +// CHECK1-NEXT: store ptr [[A]], ptr [[__RANGE3]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE3]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP1]], i64 0, i64 0 +// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 128 +// CHECK1-NEXT: store ptr [[ADD_PTR]], ptr [[__END3]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__RANGE3]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY3:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP2]], i64 0, i64 0 +// CHECK1-NEXT: store ptr [[ARRAYDECAY3]], ptr [[__BEGIN3]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__RANGE3]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY4:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP3]], i64 0, i64 0 +// CHECK1-NEXT: store ptr [[ARRAYDECAY4]], ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[__END3]], align 8 +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[DOTCAPTURE_EXPR_5]], align 8 +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_5]], align 8 +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[TMP5]] to i64 +// CHECK1-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[TMP6]] to i64 +// CHECK1-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]] +// CHECK1-NEXT: [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8 +// CHECK1-NEXT: [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i64 [[SUB]], 1 +// CHECK1-NEXT: [[DIV:%.*]] = sdiv i64 [[ADD]], 1 +// CHECK1-NEXT: [[SUB7:%.*]] = sub nsw i64 [[DIV]], 1 +// CHECK1-NEXT: store i64 [[SUB7]], ptr [[DOTCAPTURE_EXPR_6]], align 8 +// CHECK1-NEXT: [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_6]], align 8 +// CHECK1-NEXT: [[ADD9:%.*]] = add nsw i64 [[TMP7]], 1 +// CHECK1-NEXT: store i64 [[ADD9]], ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK1-NEXT: [[SUB11:%.*]] = sub nsw i64 [[TMP8]], 0 +// CHECK1-NEXT: [[DIV12:%.*]] = sdiv i64 [[SUB11]], 1 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i64 4, [[DIV12]] +// CHECK1-NEXT: [[MUL13:%.*]] = mul nsw i64 [[MUL]], 4 +// CHECK1-NEXT: [[SUB14:%.*]] = sub nsw i64 [[MUL13]], 1 +// CHECK1-NEXT: store i64 [[SUB14]], ptr [[DOTCAPTURE_EXPR_10]], align 8 +// CHECK1-NEXT: store i32 7, ptr [[K]], align 4 +// CHECK1-NEXT: store i64 0, ptr [[DOTFORWARD_IV___BEGIN3]], align 8 +// CHECK1-NEXT: store i32 7, ptr [[J]], align 4 +// CHECK1-NEXT: [[TMP9:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK1-NEXT: [[CMP:%.*]] = icmp slt i64 0, [[TMP9]] +// CHECK1-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] +// CHECK1: omp.precond.then: +// CHECK1-NEXT: store i64 0, ptr [[DOTOMP_LB]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8 +// CHECK1-NEXT: store i64 [[TMP10]], ptr [[DOTOMP_UB]], align 8 +// CHECK1-NEXT: store i64 1, ptr [[DOTOMP_STRIDE]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_8(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i64 1, i64 1) +// CHECK1-NEXT: [[TMP11:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8 +// CHECK1-NEXT: [[CMP18:%.*]] = icmp sgt i64 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: br i1 [[CMP18]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8 +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP14:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i64 [ [[TMP13]], [[COND_TRUE]] ], [ [[TMP14]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i64 [[COND]], ptr [[DOTOMP_UB]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = load i64, ptr [[DOTOMP_LB]], align 8 +// CHECK1-NEXT: store i64 [[TMP15]], ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP16:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP17:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8 +// CHECK1-NEXT: [[CMP19:%.*]] = icmp sle i64 [[TMP16]], [[TMP17]] +// CHECK1-NEXT: br i1 [[CMP19]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP18:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP19:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK1-NEXT: [[SUB20:%.*]] = sub nsw i64 [[TMP19]], 0 +// CHECK1-NEXT: [[DIV21:%.*]] = sdiv i64 [[SUB20]], 1 +// CHECK1-NEXT: [[MUL22:%.*]] = mul nsw i64 1, [[DIV21]] +// CHECK1-NEXT: [[MUL23:%.*]] = mul nsw i64 [[MUL22]], 4 +// CHECK1-NEXT: [[DIV24:%.*]] = sdiv i64 [[TMP18]], [[MUL23]] +// CHECK1-NEXT: [[MUL25:%.*]] = mul nsw i64 [[DIV24]], 3 +// CHECK1-NEXT: [[ADD26:%.*]] = add nsw i64 7, [[MUL25]] +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[ADD26]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[K15]], align 4 +// CHECK1-NEXT: [[TMP20:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP21:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK1-NEXT: [[SUB27:%.*]] = sub nsw i64 [[TMP22]], 0 +// CHECK1-NEXT: [[DIV28:%.*]] = sdiv i64 [[SUB27]], 1 +// CHECK1-NEXT: [[MUL29:%.*]] = mul nsw i64 1, [[DIV28]] +// CHECK1-NEXT: [[MUL30:%.*]] = mul nsw i64 [[MUL29]], 4 +// CHECK1-NEXT: [[DIV31:%.*]] = sdiv i64 [[TMP21]], [[MUL30]] +// CHECK1-NEXT: [[TMP23:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK1-NEXT: [[SUB32:%.*]] = sub nsw i64 [[TMP23]], 0 +// CHECK1-NEXT: [[DIV33:%.*]] = sdiv i64 [[SUB32]], 1 +// CHECK1-NEXT: [[MUL34:%.*]] = mul nsw i64 1, [[DIV33]] +// CHECK1-NEXT: [[MUL35:%.*]] = mul nsw i64 [[MUL34]], 4 +// CHECK1-NEXT: [[MUL36:%.*]] = mul nsw i64 [[DIV31]], [[MUL35]] +// CHECK1-NEXT: [[SUB37:%.*]] = sub nsw i64 [[TMP20]], [[MUL36]] +// CHECK1-NEXT: [[DIV38:%.*]] = sdiv i64 [[SUB37]], 4 +// CHECK1-NEXT: [[MUL39:%.*]] = mul nsw i64 [[DIV38]], 1 +// CHECK1-NEXT: [[ADD40:%.*]] = add nsw i64 0, [[MUL39]] +// CHECK1-NEXT: store i64 [[ADD40]], ptr [[DOTFORWARD_IV___BEGIN316]], align 8 +// CHECK1-NEXT: [[TMP24:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP26:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK1-NEXT: [[SUB41:%.*]] = sub nsw i64 [[TMP26]], 0 +// CHECK1-NEXT: [[DIV42:%.*]] = sdiv i64 [[SUB41]], 1 +// CHECK1-NEXT: [[MUL43:%.*]] = mul nsw i64 1, [[DIV42]] +// CHECK1-NEXT: [[MUL44:%.*]] = mul nsw i64 [[MUL43]], 4 +// CHECK1-NEXT: [[DIV45:%.*]] = sdiv i64 [[TMP25]], [[MUL44]] +// CHECK1-NEXT: [[TMP27:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK1-NEXT: [[SUB46:%.*]] = sub nsw i64 [[TMP27]], 0 +// CHECK1-NEXT: [[DIV47:%.*]] = sdiv i64 [[SUB46]], 1 +// CHECK1-NEXT: [[MUL48:%.*]] = mul nsw i64 1, [[DIV47]] +// CHECK1-NEXT: [[MUL49:%.*]] = mul nsw i64 [[MUL48]], 4 +// CHECK1-NEXT: [[MUL50:%.*]] = mul nsw i64 [[DIV45]], [[MUL49]] +// CHECK1-NEXT: [[SUB51:%.*]] = sub nsw i64 [[TMP24]], [[MUL50]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP29:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[TMP30:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK1-NEXT: [[SUB52:%.*]] = sub nsw i64 [[TMP30]], 0 +// CHECK1-NEXT: [[DIV53:%.*]] = sdiv i64 [[SUB52]], 1 +// CHECK1-NEXT: [[MUL54:%.*]] = mul nsw i64 1, [[DIV53]] +// CHECK1-NEXT: [[MUL55:%.*]] = mul nsw i64 [[MUL54]], 4 +// CHECK1-NEXT: [[DIV56:%.*]] = sdiv i64 [[TMP29]], [[MUL55]] +// CHECK1-NEXT: [[TMP31:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK1-NEXT: [[SUB57:%.*]] = sub nsw i64 [[TMP31]], 0 +// CHECK1-NEXT: [[DIV58:%.*]] = sdiv i64 [[SUB57]], 1 +// CHECK1-NEXT: [[MUL59:%.*]] = mul nsw i64 1, [[DIV58]] +// CHECK1-NEXT: [[MUL60:%.*]] = mul nsw i64 [[MUL59]], 4 +// CHECK1-NEXT: [[MUL61:%.*]] = mul nsw i64 [[DIV56]], [[MUL60]] +// CHECK1-NEXT: [[SUB62:%.*]] = sub nsw i64 [[TMP28]], [[MUL61]] +// CHECK1-NEXT: [[DIV63:%.*]] = sdiv i64 [[SUB62]], 4 +// CHECK1-NEXT: [[MUL64:%.*]] = mul nsw i64 [[DIV63]], 4 +// CHECK1-NEXT: [[SUB65:%.*]] = sub nsw i64 [[SUB51]], [[MUL64]] +// CHECK1-NEXT: [[MUL66:%.*]] = mul nsw i64 [[SUB65]], 3 +// CHECK1-NEXT: [[ADD67:%.*]] = add nsw i64 7, [[MUL66]] +// CHECK1-NEXT: [[CONV68:%.*]] = trunc i64 [[ADD67]] to i32 +// CHECK1-NEXT: store i32 [[CONV68]], ptr [[J17]], align 4 +// CHECK1-NEXT: [[TMP32:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_6]], align 8 +// CHECK1-NEXT: [[ADD69:%.*]] = add nsw i64 [[TMP32]], 1 +// CHECK1-NEXT: [[SUB70:%.*]] = sub nsw i64 [[ADD69]], 1 +// CHECK1-NEXT: [[TMP33:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN316]], align 8 +// CHECK1-NEXT: [[SUB71:%.*]] = sub nsw i64 [[SUB70]], [[TMP33]] +// CHECK1-NEXT: store i64 [[SUB71]], ptr [[DOTREVERSED_IV___BEGIN3]], align 8 +// CHECK1-NEXT: [[TMP34:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[TMP35:%.*]] = load i64, ptr [[DOTREVERSED_IV___BEGIN3]], align 8 +// CHECK1-NEXT: [[MUL72:%.*]] = mul nsw i64 [[TMP35]], 1 +// CHECK1-NEXT: [[ADD_PTR73:%.*]] = getelementptr inbounds double, ptr [[TMP34]], i64 [[MUL72]] +// CHECK1-NEXT: store ptr [[ADD_PTR73]], ptr [[__BEGIN3]], align 8 +// CHECK1-NEXT: [[TMP36:%.*]] = load ptr, ptr [[__BEGIN3]], align 8 +// CHECK1-NEXT: store ptr [[TMP36]], ptr [[V]], align 8 +// CHECK1-NEXT: [[TMP37:%.*]] = load i32, ptr [[K15]], align 4 +// CHECK1-NEXT: [[TMP38:%.*]] = load i32, ptr [[C]], align 4 +// CHECK1-NEXT: [[TMP39:%.*]] = load ptr, ptr [[V]], align 8 +// CHECK1-NEXT: [[TMP40:%.*]] = load double, ptr [[TMP39]], align 8 +// CHECK1-NEXT: [[TMP41:%.*]] = load i32, ptr [[J17]], align 4 +// CHECK1-NEXT: call void (...) @body(i32 noundef [[TMP37]], i32 noundef [[TMP38]], double noundef [[TMP40]], i32 noundef [[TMP41]]) +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP42:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: [[ADD74:%.*]] = add nsw i64 [[TMP42]], 1 +// CHECK1-NEXT: store i64 [[ADD74]], ptr [[DOTOMP_IV]], align 8 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]]) +// CHECK1-NEXT: br label [[OMP_PRECOND_END]] +// CHECK1: omp.precond.end: +// CHECK1-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_GLOBAL__sub_I_reverse_codegen.cpp +// CHECK1-SAME: () #[[ATTR1]] section ".text.startup" { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: call void @__cxx_global_var_init() +// CHECK1-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@__cxx_global_var_init +// CHECK2-SAME: () #[[ATTR0:[0-9]+]] section ".text.startup" { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: call void @_ZN1SC1Ev(ptr noundef nonnull align 4 dereferenceable(4) @s) +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@_ZN1SC1Ev +// CHECK2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK2-NEXT: call void @_ZN1SC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@_ZN1SC2Ev +// CHECK2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[I2:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK2-NEXT: [[I:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0 +// CHECK2-NEXT: store i32 7, ptr [[I]], align 4 +// CHECK2-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 +// CHECK2-NEXT: store ptr [[I3]], ptr [[I2]], align 8 +// CHECK2-NEXT: store i32 0, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: br label [[FOR_COND:%.*]] +// CHECK2: for.cond: +// CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 4 +// CHECK2-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +// CHECK2: for.body: +// CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: [[SUB:%.*]] = sub nsw i32 3, [[TMP1]] +// CHECK2-NEXT: store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP2]], 3 +// CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 7, [[MUL]] +// CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[I2]], align 8 +// CHECK2-NEXT: store i32 [[ADD]], ptr [[TMP3]], align 4 +// CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[I2]], align 8 +// CHECK2-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4 +// CHECK2-NEXT: call void (...) @body(i32 noundef [[TMP5]]) +// CHECK2-NEXT: br label [[FOR_INC:%.*]] +// CHECK2: for.inc: +// CHECK2-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP6]], 1 +// CHECK2-NEXT: store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP3:![0-9]+]] +// CHECK2: for.end: +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@body +// CHECK2-SAME: (...) #[[ATTR1]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@foo1 +// CHECK2-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]], i32 noundef [[STEP:%.*]]) #[[ATTR1]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[START_ADDR:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[END_ADDR:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[STEP_ADDR:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTNEW_STEP:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_2:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: store i32 [[START]], ptr [[START_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[END]], ptr [[END_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[STEP]], ptr [[STEP_ADDR]], align 4 +// CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[START_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP0]], ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[START_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[END_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP2]], ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr [[STEP_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP3]], ptr [[DOTNEW_STEP]], align 4 +// CHECK2-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK2-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK2-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], [[TMP5]] +// CHECK2-NEXT: [[SUB3:%.*]] = sub i32 [[SUB]], 1 +// CHECK2-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 +// CHECK2-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], [[TMP6]] +// CHECK2-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 +// CHECK2-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], [[TMP7]] +// CHECK2-NEXT: [[SUB4:%.*]] = sub i32 [[DIV]], 1 +// CHECK2-NEXT: store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: br label [[FOR_COND:%.*]] +// CHECK2: for.cond: +// CHECK2-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK2-NEXT: [[ADD5:%.*]] = add i32 [[TMP9]], 1 +// CHECK2-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP8]], [[ADD5]] +// CHECK2-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +// CHECK2: for.body: +// CHECK2-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK2-NEXT: [[ADD6:%.*]] = add i32 [[TMP10]], 1 +// CHECK2-NEXT: [[SUB7:%.*]] = sub i32 [[ADD6]], 1 +// CHECK2-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: [[SUB8:%.*]] = sub i32 [[SUB7]], [[TMP11]] +// CHECK2-NEXT: store i32 [[SUB8]], ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK2-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK2-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK2-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 +// CHECK2-NEXT: [[MUL:%.*]] = mul i32 [[TMP13]], [[TMP14]] +// CHECK2-NEXT: [[ADD9:%.*]] = add i32 [[TMP12]], [[MUL]] +// CHECK2-NEXT: store i32 [[ADD9]], ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4 +// CHECK2-NEXT: call void (...) @body(i32 noundef [[TMP15]]) +// CHECK2-NEXT: br label [[FOR_INC:%.*]] +// CHECK2: for.inc: +// CHECK2-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: [[INC:%.*]] = add i32 [[TMP16]], 1 +// CHECK2-NEXT: store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP5:![0-9]+]] +// CHECK2: for.end: +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@foo2 +// CHECK2-SAME: () #[[ATTR1]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2:[0-9]+]]) +// CHECK2-NEXT: store i32 7, ptr [[I]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK2-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 3 +// CHECK2-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK2: cond.true: +// CHECK2-NEXT: br label [[COND_END:%.*]] +// CHECK2: cond.false: +// CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: br label [[COND_END]] +// CHECK2: cond.end: +// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ 3, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ] +// CHECK2-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK2-NEXT: store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK2: omp.inner.for.cond: +// CHECK2-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]] +// CHECK2-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK2: omp.inner.for.body: +// CHECK2-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP6]], 1 +// CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK2-NEXT: store i32 [[ADD]], ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: [[SUB:%.*]] = sub nsw i32 3, [[TMP7]] +// CHECK2-NEXT: store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK2-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK2-NEXT: [[MUL2:%.*]] = mul nsw i32 [[TMP8]], 3 +// CHECK2-NEXT: [[ADD3:%.*]] = add nsw i32 7, [[MUL2]] +// CHECK2-NEXT: store i32 [[ADD3]], ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP9:%.*]] = load i32, ptr [[I]], align 4 +// CHECK2-NEXT: call void (...) @body(i32 noundef [[TMP9]]) +// CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK2: omp.body.continue: +// CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK2: omp.inner.for.inc: +// CHECK2-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK2-NEXT: store i32 [[ADD4]], ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK2: omp.inner.for.end: +// CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK2: omp.loop.exit: +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]]) +// CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3:[0-9]+]], i32 [[TMP0]]) +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@foo3 +// CHECK2-SAME: () #[[ATTR1]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[K:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[J:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]]) +// CHECK2-NEXT: store i32 7, ptr [[I]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK2-NEXT: store i32 63, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK2-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 63 +// CHECK2-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK2: cond.true: +// CHECK2-NEXT: br label [[COND_END:%.*]] +// CHECK2: cond.false: +// CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: br label [[COND_END]] +// CHECK2: cond.end: +// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ 63, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ] +// CHECK2-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK2-NEXT: store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK2: omp.inner.for.cond: +// CHECK2-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[CMP3:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]] +// CHECK2-NEXT: br i1 [[CMP3]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK2: omp.inner.for.body: +// CHECK2-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP6]], 16 +// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[DIV]], 3 +// CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 7, [[MUL]] +// CHECK2-NEXT: store i32 [[ADD]], ptr [[K]], align 4 +// CHECK2-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[DIV4:%.*]] = sdiv i32 [[TMP8]], 16 +// CHECK2-NEXT: [[MUL5:%.*]] = mul nsw i32 [[DIV4]], 16 +// CHECK2-NEXT: [[SUB:%.*]] = sub nsw i32 [[TMP7]], [[MUL5]] +// CHECK2-NEXT: [[DIV6:%.*]] = sdiv i32 [[SUB]], 4 +// CHECK2-NEXT: [[MUL7:%.*]] = mul nsw i32 [[DIV6]], 1 +// CHECK2-NEXT: [[ADD8:%.*]] = add nsw i32 0, [[MUL7]] +// CHECK2-NEXT: store i32 [[ADD8]], ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[DIV9:%.*]] = sdiv i32 [[TMP10]], 16 +// CHECK2-NEXT: [[MUL10:%.*]] = mul nsw i32 [[DIV9]], 16 +// CHECK2-NEXT: [[SUB11:%.*]] = sub nsw i32 [[TMP9]], [[MUL10]] +// CHECK2-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[DIV12:%.*]] = sdiv i32 [[TMP12]], 16 +// CHECK2-NEXT: [[MUL13:%.*]] = mul nsw i32 [[DIV12]], 16 +// CHECK2-NEXT: [[SUB14:%.*]] = sub nsw i32 [[TMP11]], [[MUL13]] +// CHECK2-NEXT: [[DIV15:%.*]] = sdiv i32 [[SUB14]], 4 +// CHECK2-NEXT: [[MUL16:%.*]] = mul nsw i32 [[DIV15]], 4 +// CHECK2-NEXT: [[SUB17:%.*]] = sub nsw i32 [[SUB11]], [[MUL16]] +// CHECK2-NEXT: [[MUL18:%.*]] = mul nsw i32 [[SUB17]], 3 +// CHECK2-NEXT: [[ADD19:%.*]] = add nsw i32 7, [[MUL18]] +// CHECK2-NEXT: store i32 [[ADD19]], ptr [[J]], align 4 +// CHECK2-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: [[SUB20:%.*]] = sub nsw i32 3, [[TMP13]] +// CHECK2-NEXT: store i32 [[SUB20]], ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK2-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK2-NEXT: [[MUL21:%.*]] = mul nsw i32 [[TMP14]], 3 +// CHECK2-NEXT: [[ADD22:%.*]] = add nsw i32 7, [[MUL21]] +// CHECK2-NEXT: store i32 [[ADD22]], ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP15:%.*]] = load i32, ptr [[K]], align 4 +// CHECK2-NEXT: [[TMP16:%.*]] = load i32, ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP17:%.*]] = load i32, ptr [[J]], align 4 +// CHECK2-NEXT: call void (...) @body(i32 noundef [[TMP15]], i32 noundef [[TMP16]], i32 noundef [[TMP17]]) +// CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK2: omp.body.continue: +// CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK2: omp.inner.for.inc: +// CHECK2-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[ADD23:%.*]] = add nsw i32 [[TMP18]], 1 +// CHECK2-NEXT: store i32 [[ADD23]], ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK2: omp.inner.for.end: +// CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK2: omp.loop.exit: +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]]) +// CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]]) +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@foo4 +// CHECK2-SAME: () #[[ATTR1]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 0, ptr @foo4.omp_outlined) +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@foo4.omp_outlined +// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR4:[0-9]+]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK2-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK2-NEXT: store i32 7, ptr [[I]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK2-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK2-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 3 +// CHECK2-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK2: cond.true: +// CHECK2-NEXT: br label [[COND_END:%.*]] +// CHECK2: cond.false: +// CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: br label [[COND_END]] +// CHECK2: cond.end: +// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ 3, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK2-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK2-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK2: omp.inner.for.cond: +// CHECK2-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK2-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK2-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK2: omp.inner.for.body: +// CHECK2-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1 +// CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK2-NEXT: store i32 [[ADD]], ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: [[SUB:%.*]] = sub nsw i32 3, [[TMP8]] +// CHECK2-NEXT: store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK2-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK2-NEXT: [[MUL2:%.*]] = mul nsw i32 [[TMP9]], 3 +// CHECK2-NEXT: [[ADD3:%.*]] = add nsw i32 7, [[MUL2]] +// CHECK2-NEXT: store i32 [[ADD3]], ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP10:%.*]] = load i32, ptr [[I]], align 4 +// CHECK2-NEXT: call void (...) @body(i32 noundef [[TMP10]]) +// CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK2: omp.body.continue: +// CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK2: omp.inner.for.inc: +// CHECK2-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK2-NEXT: store i32 [[ADD4]], ptr [[DOTOMP_IV]], align 4 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK2: omp.inner.for.end: +// CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK2: omp.loop.exit: +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@foo6 +// CHECK2-SAME: () #[[ATTR1]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[ARR:%.*]] = alloca [128 x double], align 16 +// CHECK2-NEXT: [[C:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[__RANGE2:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[__END2:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[__BEGIN2:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_3:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTFORWARD_IV___BEGIN2:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTREVERSED_IV___BEGIN2:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[V:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: store i32 42, ptr [[C]], align 4 +// CHECK2-NEXT: store ptr [[ARR]], ptr [[__RANGE2]], align 8 +// CHECK2-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP0]], i64 0, i64 0 +// CHECK2-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 128 +// CHECK2-NEXT: store ptr [[ADD_PTR]], ptr [[__END2]], align 8 +// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP1]], i64 0, i64 0 +// CHECK2-NEXT: store ptr [[ARRAYDECAY1]], ptr [[__BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY2:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP2]], i64 0, i64 0 +// CHECK2-NEXT: store ptr [[ARRAYDECAY2]], ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__END2]], align 8 +// CHECK2-NEXT: store ptr [[TMP3]], ptr [[DOTCAPTURE_EXPR_3]], align 8 +// CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_3]], align 8 +// CHECK2-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[TMP4]] to i64 +// CHECK2-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[TMP5]] to i64 +// CHECK2-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]] +// CHECK2-NEXT: [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8 +// CHECK2-NEXT: [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1 +// CHECK2-NEXT: [[ADD:%.*]] = add nsw i64 [[SUB]], 1 +// CHECK2-NEXT: [[DIV:%.*]] = sdiv i64 [[ADD]], 1 +// CHECK2-NEXT: [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1 +// CHECK2-NEXT: store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK2-NEXT: store i64 0, ptr [[DOTFORWARD_IV___BEGIN2]], align 8 +// CHECK2-NEXT: br label [[FOR_COND:%.*]] +// CHECK2: for.cond: +// CHECK2-NEXT: [[TMP6:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK2-NEXT: [[ADD6:%.*]] = add nsw i64 [[TMP7]], 1 +// CHECK2-NEXT: [[CMP:%.*]] = icmp slt i64 [[TMP6]], [[ADD6]] +// CHECK2-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +// CHECK2: for.body: +// CHECK2-NEXT: [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK2-NEXT: [[ADD7:%.*]] = add nsw i64 [[TMP8]], 1 +// CHECK2-NEXT: [[SUB8:%.*]] = sub nsw i64 [[ADD7]], 1 +// CHECK2-NEXT: [[TMP9:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[SUB9:%.*]] = sub nsw i64 [[SUB8]], [[TMP9]] +// CHECK2-NEXT: store i64 [[SUB9]], ptr [[DOTREVERSED_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[TMP11:%.*]] = load i64, ptr [[DOTREVERSED_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i64 [[TMP11]], 1 +// CHECK2-NEXT: [[ADD_PTR10:%.*]] = getelementptr inbounds double, ptr [[TMP10]], i64 [[MUL]] +// CHECK2-NEXT: store ptr [[ADD_PTR10]], ptr [[__BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP12:%.*]] = load ptr, ptr [[__BEGIN2]], align 8 +// CHECK2-NEXT: store ptr [[TMP12]], ptr [[V]], align 8 +// CHECK2-NEXT: [[TMP13:%.*]] = load ptr, ptr [[V]], align 8 +// CHECK2-NEXT: [[TMP14:%.*]] = load double, ptr [[TMP13]], align 8 +// CHECK2-NEXT: [[TMP15:%.*]] = load i32, ptr [[C]], align 4 +// CHECK2-NEXT: call void (...) @body(double noundef [[TMP14]], i32 noundef [[TMP15]]) +// CHECK2-NEXT: br label [[FOR_INC:%.*]] +// CHECK2: for.inc: +// CHECK2-NEXT: [[TMP16:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[INC:%.*]] = add nsw i64 [[TMP16]], 1 +// CHECK2-NEXT: store i64 [[INC]], ptr [[DOTFORWARD_IV___BEGIN2]], align 8 +// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP8:![0-9]+]] +// CHECK2: for.end: +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@foo7 +// CHECK2-SAME: () #[[ATTR1]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[A:%.*]] = alloca [128 x double], align 16 +// CHECK2-NEXT: [[DOTOMP_IV:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[_TMP1:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[C:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[__RANGE3:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[__END3:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[__BEGIN3:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_5:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_6:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_8:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_10:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[K:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTFORWARD_IV___BEGIN3:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[J:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTOMP_LB:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTOMP_UB:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[K15:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTFORWARD_IV___BEGIN316:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[J17:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTREVERSED_IV___BEGIN3:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[V:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]]) +// CHECK2-NEXT: store i32 42, ptr [[C]], align 4 +// CHECK2-NEXT: store ptr [[A]], ptr [[__RANGE3]], align 8 +// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE3]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP1]], i64 0, i64 0 +// CHECK2-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 128 +// CHECK2-NEXT: store ptr [[ADD_PTR]], ptr [[__END3]], align 8 +// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__RANGE3]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY3:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP2]], i64 0, i64 0 +// CHECK2-NEXT: store ptr [[ARRAYDECAY3]], ptr [[__BEGIN3]], align 8 +// CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__RANGE3]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY4:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP3]], i64 0, i64 0 +// CHECK2-NEXT: store ptr [[ARRAYDECAY4]], ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[__END3]], align 8 +// CHECK2-NEXT: store ptr [[TMP4]], ptr [[DOTCAPTURE_EXPR_5]], align 8 +// CHECK2-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_5]], align 8 +// CHECK2-NEXT: [[TMP6:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[TMP5]] to i64 +// CHECK2-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[TMP6]] to i64 +// CHECK2-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]] +// CHECK2-NEXT: [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8 +// CHECK2-NEXT: [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1 +// CHECK2-NEXT: [[ADD:%.*]] = add nsw i64 [[SUB]], 1 +// CHECK2-NEXT: [[DIV:%.*]] = sdiv i64 [[ADD]], 1 +// CHECK2-NEXT: [[SUB7:%.*]] = sub nsw i64 [[DIV]], 1 +// CHECK2-NEXT: store i64 [[SUB7]], ptr [[DOTCAPTURE_EXPR_6]], align 8 +// CHECK2-NEXT: [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_6]], align 8 +// CHECK2-NEXT: [[ADD9:%.*]] = add nsw i64 [[TMP7]], 1 +// CHECK2-NEXT: store i64 [[ADD9]], ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK2-NEXT: [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK2-NEXT: [[SUB11:%.*]] = sub nsw i64 [[TMP8]], 0 +// CHECK2-NEXT: [[DIV12:%.*]] = sdiv i64 [[SUB11]], 1 +// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i64 4, [[DIV12]] +// CHECK2-NEXT: [[MUL13:%.*]] = mul nsw i64 [[MUL]], 4 +// CHECK2-NEXT: [[SUB14:%.*]] = sub nsw i64 [[MUL13]], 1 +// CHECK2-NEXT: store i64 [[SUB14]], ptr [[DOTCAPTURE_EXPR_10]], align 8 +// CHECK2-NEXT: store i32 7, ptr [[K]], align 4 +// CHECK2-NEXT: store i64 0, ptr [[DOTFORWARD_IV___BEGIN3]], align 8 +// CHECK2-NEXT: store i32 7, ptr [[J]], align 4 +// CHECK2-NEXT: [[TMP9:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK2-NEXT: [[CMP:%.*]] = icmp slt i64 0, [[TMP9]] +// CHECK2-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] +// CHECK2: omp.precond.then: +// CHECK2-NEXT: store i64 0, ptr [[DOTOMP_LB]], align 8 +// CHECK2-NEXT: [[TMP10:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8 +// CHECK2-NEXT: store i64 [[TMP10]], ptr [[DOTOMP_UB]], align 8 +// CHECK2-NEXT: store i64 1, ptr [[DOTOMP_STRIDE]], align 8 +// CHECK2-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK2-NEXT: call void @__kmpc_for_static_init_8(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i64 1, i64 1) +// CHECK2-NEXT: [[TMP11:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8 +// CHECK2-NEXT: [[TMP12:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8 +// CHECK2-NEXT: [[CMP18:%.*]] = icmp sgt i64 [[TMP11]], [[TMP12]] +// CHECK2-NEXT: br i1 [[CMP18]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK2: cond.true: +// CHECK2-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8 +// CHECK2-NEXT: br label [[COND_END:%.*]] +// CHECK2: cond.false: +// CHECK2-NEXT: [[TMP14:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8 +// CHECK2-NEXT: br label [[COND_END]] +// CHECK2: cond.end: +// CHECK2-NEXT: [[COND:%.*]] = phi i64 [ [[TMP13]], [[COND_TRUE]] ], [ [[TMP14]], [[COND_FALSE]] ] +// CHECK2-NEXT: store i64 [[COND]], ptr [[DOTOMP_UB]], align 8 +// CHECK2-NEXT: [[TMP15:%.*]] = load i64, ptr [[DOTOMP_LB]], align 8 +// CHECK2-NEXT: store i64 [[TMP15]], ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK2: omp.inner.for.cond: +// CHECK2-NEXT: [[TMP16:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP17:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8 +// CHECK2-NEXT: [[CMP19:%.*]] = icmp sle i64 [[TMP16]], [[TMP17]] +// CHECK2-NEXT: br i1 [[CMP19]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK2: omp.inner.for.body: +// CHECK2-NEXT: [[TMP18:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP19:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK2-NEXT: [[SUB20:%.*]] = sub nsw i64 [[TMP19]], 0 +// CHECK2-NEXT: [[DIV21:%.*]] = sdiv i64 [[SUB20]], 1 +// CHECK2-NEXT: [[MUL22:%.*]] = mul nsw i64 1, [[DIV21]] +// CHECK2-NEXT: [[MUL23:%.*]] = mul nsw i64 [[MUL22]], 4 +// CHECK2-NEXT: [[DIV24:%.*]] = sdiv i64 [[TMP18]], [[MUL23]] +// CHECK2-NEXT: [[MUL25:%.*]] = mul nsw i64 [[DIV24]], 3 +// CHECK2-NEXT: [[ADD26:%.*]] = add nsw i64 7, [[MUL25]] +// CHECK2-NEXT: [[CONV:%.*]] = trunc i64 [[ADD26]] to i32 +// CHECK2-NEXT: store i32 [[CONV]], ptr [[K15]], align 4 +// CHECK2-NEXT: [[TMP20:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP21:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK2-NEXT: [[SUB27:%.*]] = sub nsw i64 [[TMP22]], 0 +// CHECK2-NEXT: [[DIV28:%.*]] = sdiv i64 [[SUB27]], 1 +// CHECK2-NEXT: [[MUL29:%.*]] = mul nsw i64 1, [[DIV28]] +// CHECK2-NEXT: [[MUL30:%.*]] = mul nsw i64 [[MUL29]], 4 +// CHECK2-NEXT: [[DIV31:%.*]] = sdiv i64 [[TMP21]], [[MUL30]] +// CHECK2-NEXT: [[TMP23:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK2-NEXT: [[SUB32:%.*]] = sub nsw i64 [[TMP23]], 0 +// CHECK2-NEXT: [[DIV33:%.*]] = sdiv i64 [[SUB32]], 1 +// CHECK2-NEXT: [[MUL34:%.*]] = mul nsw i64 1, [[DIV33]] +// CHECK2-NEXT: [[MUL35:%.*]] = mul nsw i64 [[MUL34]], 4 +// CHECK2-NEXT: [[MUL36:%.*]] = mul nsw i64 [[DIV31]], [[MUL35]] +// CHECK2-NEXT: [[SUB37:%.*]] = sub nsw i64 [[TMP20]], [[MUL36]] +// CHECK2-NEXT: [[DIV38:%.*]] = sdiv i64 [[SUB37]], 4 +// CHECK2-NEXT: [[MUL39:%.*]] = mul nsw i64 [[DIV38]], 1 +// CHECK2-NEXT: [[ADD40:%.*]] = add nsw i64 0, [[MUL39]] +// CHECK2-NEXT: store i64 [[ADD40]], ptr [[DOTFORWARD_IV___BEGIN316]], align 8 +// CHECK2-NEXT: [[TMP24:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP26:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK2-NEXT: [[SUB41:%.*]] = sub nsw i64 [[TMP26]], 0 +// CHECK2-NEXT: [[DIV42:%.*]] = sdiv i64 [[SUB41]], 1 +// CHECK2-NEXT: [[MUL43:%.*]] = mul nsw i64 1, [[DIV42]] +// CHECK2-NEXT: [[MUL44:%.*]] = mul nsw i64 [[MUL43]], 4 +// CHECK2-NEXT: [[DIV45:%.*]] = sdiv i64 [[TMP25]], [[MUL44]] +// CHECK2-NEXT: [[TMP27:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK2-NEXT: [[SUB46:%.*]] = sub nsw i64 [[TMP27]], 0 +// CHECK2-NEXT: [[DIV47:%.*]] = sdiv i64 [[SUB46]], 1 +// CHECK2-NEXT: [[MUL48:%.*]] = mul nsw i64 1, [[DIV47]] +// CHECK2-NEXT: [[MUL49:%.*]] = mul nsw i64 [[MUL48]], 4 +// CHECK2-NEXT: [[MUL50:%.*]] = mul nsw i64 [[DIV45]], [[MUL49]] +// CHECK2-NEXT: [[SUB51:%.*]] = sub nsw i64 [[TMP24]], [[MUL50]] +// CHECK2-NEXT: [[TMP28:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP29:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[TMP30:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK2-NEXT: [[SUB52:%.*]] = sub nsw i64 [[TMP30]], 0 +// CHECK2-NEXT: [[DIV53:%.*]] = sdiv i64 [[SUB52]], 1 +// CHECK2-NEXT: [[MUL54:%.*]] = mul nsw i64 1, [[DIV53]] +// CHECK2-NEXT: [[MUL55:%.*]] = mul nsw i64 [[MUL54]], 4 +// CHECK2-NEXT: [[DIV56:%.*]] = sdiv i64 [[TMP29]], [[MUL55]] +// CHECK2-NEXT: [[TMP31:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8 +// CHECK2-NEXT: [[SUB57:%.*]] = sub nsw i64 [[TMP31]], 0 +// CHECK2-NEXT: [[DIV58:%.*]] = sdiv i64 [[SUB57]], 1 +// CHECK2-NEXT: [[MUL59:%.*]] = mul nsw i64 1, [[DIV58]] +// CHECK2-NEXT: [[MUL60:%.*]] = mul nsw i64 [[MUL59]], 4 +// CHECK2-NEXT: [[MUL61:%.*]] = mul nsw i64 [[DIV56]], [[MUL60]] +// CHECK2-NEXT: [[SUB62:%.*]] = sub nsw i64 [[TMP28]], [[MUL61]] +// CHECK2-NEXT: [[DIV63:%.*]] = sdiv i64 [[SUB62]], 4 +// CHECK2-NEXT: [[MUL64:%.*]] = mul nsw i64 [[DIV63]], 4 +// CHECK2-NEXT: [[SUB65:%.*]] = sub nsw i64 [[SUB51]], [[MUL64]] +// CHECK2-NEXT: [[MUL66:%.*]] = mul nsw i64 [[SUB65]], 3 +// CHECK2-NEXT: [[ADD67:%.*]] = add nsw i64 7, [[MUL66]] +// CHECK2-NEXT: [[CONV68:%.*]] = trunc i64 [[ADD67]] to i32 +// CHECK2-NEXT: store i32 [[CONV68]], ptr [[J17]], align 4 +// CHECK2-NEXT: [[TMP32:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_6]], align 8 +// CHECK2-NEXT: [[ADD69:%.*]] = add nsw i64 [[TMP32]], 1 +// CHECK2-NEXT: [[SUB70:%.*]] = sub nsw i64 [[ADD69]], 1 +// CHECK2-NEXT: [[TMP33:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN316]], align 8 +// CHECK2-NEXT: [[SUB71:%.*]] = sub nsw i64 [[SUB70]], [[TMP33]] +// CHECK2-NEXT: store i64 [[SUB71]], ptr [[DOTREVERSED_IV___BEGIN3]], align 8 +// CHECK2-NEXT: [[TMP34:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[TMP35:%.*]] = load i64, ptr [[DOTREVERSED_IV___BEGIN3]], align 8 +// CHECK2-NEXT: [[MUL72:%.*]] = mul nsw i64 [[TMP35]], 1 +// CHECK2-NEXT: [[ADD_PTR73:%.*]] = getelementptr inbounds double, ptr [[TMP34]], i64 [[MUL72]] +// CHECK2-NEXT: store ptr [[ADD_PTR73]], ptr [[__BEGIN3]], align 8 +// CHECK2-NEXT: [[TMP36:%.*]] = load ptr, ptr [[__BEGIN3]], align 8 +// CHECK2-NEXT: store ptr [[TMP36]], ptr [[V]], align 8 +// CHECK2-NEXT: [[TMP37:%.*]] = load i32, ptr [[K15]], align 4 +// CHECK2-NEXT: [[TMP38:%.*]] = load i32, ptr [[C]], align 4 +// CHECK2-NEXT: [[TMP39:%.*]] = load ptr, ptr [[V]], align 8 +// CHECK2-NEXT: [[TMP40:%.*]] = load double, ptr [[TMP39]], align 8 +// CHECK2-NEXT: [[TMP41:%.*]] = load i32, ptr [[J17]], align 4 +// CHECK2-NEXT: call void (...) @body(i32 noundef [[TMP37]], i32 noundef [[TMP38]], double noundef [[TMP40]], i32 noundef [[TMP41]]) +// CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK2: omp.body.continue: +// CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK2: omp.inner.for.inc: +// CHECK2-NEXT: [[TMP42:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: [[ADD74:%.*]] = add nsw i64 [[TMP42]], 1 +// CHECK2-NEXT: store i64 [[ADD74]], ptr [[DOTOMP_IV]], align 8 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK2: omp.inner.for.end: +// CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK2: omp.loop.exit: +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]]) +// CHECK2-NEXT: br label [[OMP_PRECOND_END]] +// CHECK2: omp.precond.end: +// CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]]) +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@tfoo5 +// CHECK2-SAME: () #[[ATTR1]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: call void @_Z4foo5IiTnT_Li3EEvS0_S0_(i32 noundef 0, i32 noundef 42) +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@_Z4foo5IiTnT_Li3EEvS0_S0_ +// CHECK2-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]]) #[[ATTR1]] comdat { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[START_ADDR:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[END_ADDR:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_2:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: store i32 [[START]], ptr [[START_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[END]], ptr [[END_ADDR]], align 4 +// CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[START_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP0]], ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[START_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[END_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP2]], ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK2-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK2-NEXT: [[SUB:%.*]] = sub i32 [[TMP3]], [[TMP4]] +// CHECK2-NEXT: [[SUB3:%.*]] = sub i32 [[SUB]], 1 +// CHECK2-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], 3 +// CHECK2-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], 3 +// CHECK2-NEXT: [[SUB4:%.*]] = sub i32 [[DIV]], 1 +// CHECK2-NEXT: store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK2-NEXT: store i32 0, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: br label [[FOR_COND:%.*]] +// CHECK2: for.cond: +// CHECK2-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK2-NEXT: [[ADD5:%.*]] = add i32 [[TMP6]], 1 +// CHECK2-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP5]], [[ADD5]] +// CHECK2-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +// CHECK2: for.body: +// CHECK2-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK2-NEXT: [[ADD6:%.*]] = add i32 [[TMP7]], 1 +// CHECK2-NEXT: [[SUB7:%.*]] = sub i32 [[ADD6]], 1 +// CHECK2-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: [[SUB8:%.*]] = sub i32 [[SUB7]], [[TMP8]] +// CHECK2-NEXT: store i32 [[SUB8]], ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK2-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK2-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4 +// CHECK2-NEXT: [[MUL:%.*]] = mul i32 [[TMP10]], 3 +// CHECK2-NEXT: [[ADD9:%.*]] = add i32 [[TMP9]], [[MUL]] +// CHECK2-NEXT: store i32 [[ADD9]], ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP11:%.*]] = load i32, ptr [[I]], align 4 +// CHECK2-NEXT: call void (...) @body(i32 noundef [[TMP11]]) +// CHECK2-NEXT: br label [[FOR_INC:%.*]] +// CHECK2: for.inc: +// CHECK2-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: [[INC:%.*]] = add i32 [[TMP12]], 1 +// CHECK2-NEXT: store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4 +// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK2: for.end: +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define {{[^@]+}}@_GLOBAL__sub_I_reverse_codegen.cpp +// CHECK2-SAME: () #[[ATTR0]] section ".text.startup" { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: call void @__cxx_global_var_init() +// CHECK2-NEXT: ret void + diff --git a/clang/test/OpenMP/reverse_messages.cpp b/clang/test/OpenMP/reverse_messages.cpp new file mode 100644 index 0000000000000..9636a70bf2753 --- /dev/null +++ b/clang/test/OpenMP/reverse_messages.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -std=c++20 -fopenmp -fopenmp-version=60 -fsyntax-only -Wuninitialized -verify %s + +void func() { + + // expected-error@+2 {{statement after '#pragma omp reverse' must be a for loop}} + #pragma omp reverse + ; + + // expected-error@+2 {{statement after '#pragma omp reverse' must be a for loop}} + #pragma omp reverse + int b = 0; + + // expected-error@+2 {{statement after '#pragma omp reverse' must be a for loop}} + #pragma omp reverse + #pragma omp for + for (int i = 0; i < 7; ++i) + ; + + { + // expected-error@+2 {{expected statement}} + #pragma omp reverse + } + + // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', '>=', or '!=') of loop variable 'i'}} + #pragma omp reverse + for (int i = 0; i/3<7; ++i) + ; + + // expected-error@+1 {{unexpected OpenMP clause 'sizes' in directive '#pragma omp reverse'}} + #pragma omp reverse sizes(5) + for (int i = 0; i < 7; ++i) + ; + + // expected-warning@+1 {{extra tokens at the end of '#pragma omp reverse' are ignored}} + #pragma omp reverse foo + for (int i = 0; i < 7; ++i) + ; + +} + diff --git a/clang/test/OpenMP/target_defaultmap_messages.cpp b/clang/test/OpenMP/target_defaultmap_messages.cpp index 8052e34d5c933..88ae3b7962d55 100644 --- a/clang/test/OpenMP/target_defaultmap_messages.cpp +++ b/clang/test/OpenMP/target_defaultmap_messages.cpp @@ -1,5 +1,8 @@ -// RUN: %clang_cc1 -verify -Wno-vla -fopenmp %s -verify=expected,omp51 -Wuninitialized -DOMP51 -// RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd %s -verify=expected,omp51 -Wuninitialized -DOMP51 +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized + +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized -DOMP51 +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized -DOMP51 // RUN: %clang_cc1 -verify -Wno-vla -fopenmp -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -DOMP5 // RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -DOMP5 @@ -30,23 +33,23 @@ template T tmain(T argc, S **argv) { #pragma omp target defaultmap // expected-error {{expected '(' after 'defaultmap'}} foo(); -#pragma omp target defaultmap( // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target defaultmap( // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); -#pragma omp target defaultmap() // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target defaultmap() // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); - #pragma omp target defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + #pragma omp target defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); - #pragma omp target defaultmap (scalar: // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} + #pragma omp target defaultmap (scalar: // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); - #pragma omp target defaultmap(tofrom:scalar) defaultmap(tofrom:scalar) // omp45-error {{directive '#pragma omp target' cannot contain more than one 'defaultmap' clause}} omp5-error {{at most one defaultmap clause for each variable-category can appear on the directive}} omp51-error {{at most one defaultmap clause for each variable-category can appear on the directive}} + #pragma omp target defaultmap(tofrom:scalar) defaultmap(tofrom:scalar) // omp45-error {{directive '#pragma omp target' cannot contain more than one 'defaultmap' clause}} omp5-error {{at most one defaultmap clause for each variable-category can appear on the directive}} omp5x-error {{at most one defaultmap clause for each variable-category can appear on the directive}} foo(); @@ -93,23 +96,23 @@ T tmain(T argc, S **argv) { int main(int argc, char **argv) { #pragma omp target defaultmap // expected-error {{expected '(' after 'defaultmap'}} foo(); -#pragma omp target defaultmap( // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target defaultmap( // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); -#pragma omp target defaultmap() // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target defaultmap() // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); -#pragma omp target defaultmap(tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} +#pragma omp target defaultmap(tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); -#pragma omp target defaultmap(scalar: // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target defaultmap(scalar: // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); -#pragma omp target defaultmap(tofrom: scalar) defaultmap(tofrom: scalar) // omp45-error {{directive '#pragma omp target' cannot contain more than one 'defaultmap' clause}} omp5-error {{at most one defaultmap clause for each variable-category can appear on the directive}} omp51-error {{at most one defaultmap clause for each variable-category can appear on the directive}} +#pragma omp target defaultmap(tofrom: scalar) defaultmap(tofrom: scalar) // omp45-error {{directive '#pragma omp target' cannot contain more than one 'defaultmap' clause}} omp5-error {{at most one defaultmap clause for each variable-category can appear on the directive}} omp5x-error {{at most one defaultmap clause for each variable-category can appear on the directive}} foo(); #ifdef OMP5 diff --git a/clang/test/OpenMP/target_parallel_debug_codegen.cpp b/clang/test/OpenMP/target_parallel_debug_codegen.cpp index 7f5592841fa68..ec26cf2186285 100644 --- a/clang/test/OpenMP/target_parallel_debug_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_debug_codegen.cpp @@ -122,8 +122,40 @@ int main() { // CHECK1-NEXT: ret void, !dbg [[DBG58]] // // +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l23 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR1:[0-9]+]] !dbg [[DBG64:![0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META71:![0-9]+]], !DIExpression(), [[META72:![0-9]+]]) +// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META73:![0-9]+]], !DIExpression(), [[META72]]) +// CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META74:![0-9]+]], !DIExpression(), [[META72]]) +// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META75:![0-9]+]], !DIExpression(), [[META72]]) +// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META76:![0-9]+]], !DIExpression(), [[META72]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG77:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG77]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG77]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG77]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG77]] +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG77]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG77]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG77]] +// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(1), !dbg [[DBG77]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG77]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l23_debug__(ptr [[TMP3]], ptr addrspace(1) [[TMP8]], i32 [[TMP5]], ptr [[TMP6]], ptr addrspace(1) [[TMP9]]) #[[ATTR3:[0-9]+]], !dbg [[DBG77]] +// CHECK1-NEXT: ret void, !dbg [[DBG77]] +// +// // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l23_debug___omp_outlined_debug__ -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], i32 noundef [[A:%.*]], ptr noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR1:[0-9]+]] !dbg [[DBG64:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], i32 noundef [[A:%.*]], ptr noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG78:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -140,83 +172,83 @@ int main() { // CHECK1-NEXT: [[H:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[D:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META71:![0-9]+]], !DIExpression(), [[META72:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META85:![0-9]+]], !DIExpression(), [[META86:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META73:![0-9]+]], !DIExpression(), [[META72]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META87:![0-9]+]], !DIExpression(), [[META86]]) // CHECK1-NEXT: store ptr addrspace(1) [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META74:![0-9]+]], !DIExpression(), [[META75:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META88:![0-9]+]], !DIExpression(), [[META89:![0-9]+]]) // CHECK1-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META76:![0-9]+]], !DIExpression(), [[META77:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META90:![0-9]+]], !DIExpression(), [[META91:![0-9]+]]) // CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META78:![0-9]+]], !DIExpression(), [[META79:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META92:![0-9]+]], !DIExpression(), [[META93:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META80:![0-9]+]], !DIExpression(), [[META81:![0-9]+]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG82:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG82]] -// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG82]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG82]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG82]] -// CHECK1-NEXT: store ptr [[TMP3]], ptr [[_TMP1]], align 8, !dbg [[DBG82]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG82]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG82]] -// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast ptr addrspace(1) [[TMP5]] to ptr, !dbg [[DBG82]] -// CHECK1-NEXT: store ptr [[TMP6]], ptr [[_TMP2]], align 8, !dbg [[DBG82]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG82]] -// CHECK1-NEXT: #dbg_declare(ptr [[B3]], [[META83:![0-9]+]], !DIExpression(), [[META72]]) -// CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[B3]], ptr align 4 [[TMP4]], i64 400, i1 false), !dbg [[DBG82]] -// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META84:![0-9]+]], !DIExpression(), [[META87:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG88:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG88]] -// CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX4]], i64 0, i64 1, !dbg [[DBG88]] -// CHECK1-NEXT: store ptr [[ARRAYIDX5]], ptr [[F]], align 8, !dbg [[META87]] -// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META89:![0-9]+]], !DIExpression(), [[META90:![0-9]+]]) -// CHECK1-NEXT: store ptr [[A_ADDR]], ptr [[G]], align 8, !dbg [[META90]] -// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META91:![0-9]+]], !DIExpression(), [[META92:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B3]], i64 0, i64 1, !dbg [[DBG93:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX6]], i64 0, i64 1, !dbg [[DBG93]] -// CHECK1-NEXT: store ptr [[ARRAYIDX7]], ptr [[H]], align 8, !dbg [[META92]] -// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META94:![0-9]+]], !DIExpression(), [[META95:![0-9]+]]) -// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META95]] -// CHECK1-NEXT: store i32 5, ptr [[A_ADDR]], align 4, !dbg [[DBG96:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B3]], i64 0, i64 0, !dbg [[DBG97:![0-9]+]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG98:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP8]] to i64, !dbg [[DBG97]] -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX8]], i64 0, i64 [[IDXPROM]], !dbg [[DBG97]] -// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX9]], align 4, !dbg [[DBG99:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG100:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX10]], i64 0, i64 0, !dbg [[DBG100]] -// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG101:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM12:%.*]] = sext i32 [[TMP9]] to i64, !dbg [[DBG100]] -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX11]], i64 0, i64 [[IDXPROM12]], !dbg [[DBG100]] -// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX13]], align 4, !dbg [[DBG102:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG103:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX14]], i64 0, i64 0, !dbg [[DBG103]] -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG104:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM16:%.*]] = sext i32 [[TMP10]] to i64, !dbg [[DBG103]] -// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX15]], i64 0, i64 [[IDXPROM16]], !dbg [[DBG103]] -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX17]], align 4, !dbg [[DBG103]] -// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B3]], i64 0, i64 0, !dbg [[DBG105:![0-9]+]] -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG106:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP12]] to i64, !dbg [[DBG105]] -// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG105]] -// CHECK1-NEXT: store i32 [[TMP11]], ptr [[ARRAYIDX20]], align 4, !dbg [[DBG107:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B3]], i64 0, i64 0, !dbg [[DBG108:![0-9]+]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG109:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP13]] to i64, !dbg [[DBG108]] -// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG108]] -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX23]], align 4, !dbg [[DBG108]] -// CHECK1-NEXT: [[TMP15:%.*]] = load i8, ptr [[TMP7]], align 1, !dbg [[DBG110:![0-9]+]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP15]] to i1, !dbg [[DBG110]] -// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG110]] -// CHECK1-NEXT: [[OR:%.*]] = or i32 [[CONV]], [[TMP14]], !dbg [[DBG110]] -// CHECK1-NEXT: [[TOBOOL24:%.*]] = icmp ne i32 [[OR]], 0, !dbg [[DBG110]] -// CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TOBOOL24]] to i8, !dbg [[DBG110]] -// CHECK1-NEXT: store i8 [[FROMBOOL]], ptr [[TMP7]], align 1, !dbg [[DBG110]] -// CHECK1-NEXT: ret void, !dbg [[DBG111:![0-9]+]] +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META94:![0-9]+]], !DIExpression(), [[META95:![0-9]+]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG96:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG96]] +// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG96]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG96]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG96]] +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[_TMP1]], align 8, !dbg [[DBG96]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG96]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG96]] +// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast ptr addrspace(1) [[TMP5]] to ptr, !dbg [[DBG96]] +// CHECK1-NEXT: store ptr [[TMP6]], ptr [[_TMP2]], align 8, !dbg [[DBG96]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG96]] +// CHECK1-NEXT: #dbg_declare(ptr [[B3]], [[META97:![0-9]+]], !DIExpression(), [[META86]]) +// CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[B3]], ptr align 4 [[TMP4]], i64 400, i1 false), !dbg [[DBG96]] +// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META98:![0-9]+]], !DIExpression(), [[META101:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG102:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG102]] +// CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX4]], i64 0, i64 1, !dbg [[DBG102]] +// CHECK1-NEXT: store ptr [[ARRAYIDX5]], ptr [[F]], align 8, !dbg [[META101]] +// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META103:![0-9]+]], !DIExpression(), [[META104:![0-9]+]]) +// CHECK1-NEXT: store ptr [[A_ADDR]], ptr [[G]], align 8, !dbg [[META104]] +// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META105:![0-9]+]], !DIExpression(), [[META106:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B3]], i64 0, i64 1, !dbg [[DBG107:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX6]], i64 0, i64 1, !dbg [[DBG107]] +// CHECK1-NEXT: store ptr [[ARRAYIDX7]], ptr [[H]], align 8, !dbg [[META106]] +// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META108:![0-9]+]], !DIExpression(), [[META109:![0-9]+]]) +// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META109]] +// CHECK1-NEXT: store i32 5, ptr [[A_ADDR]], align 4, !dbg [[DBG110:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B3]], i64 0, i64 0, !dbg [[DBG111:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG112:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP8]] to i64, !dbg [[DBG111]] +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX8]], i64 0, i64 [[IDXPROM]], !dbg [[DBG111]] +// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX9]], align 4, !dbg [[DBG113:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG114:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX10]], i64 0, i64 0, !dbg [[DBG114]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG115:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM12:%.*]] = sext i32 [[TMP9]] to i64, !dbg [[DBG114]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX11]], i64 0, i64 [[IDXPROM12]], !dbg [[DBG114]] +// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX13]], align 4, !dbg [[DBG116:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG117:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX14]], i64 0, i64 0, !dbg [[DBG117]] +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG118:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM16:%.*]] = sext i32 [[TMP10]] to i64, !dbg [[DBG117]] +// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX15]], i64 0, i64 [[IDXPROM16]], !dbg [[DBG117]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX17]], align 4, !dbg [[DBG117]] +// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B3]], i64 0, i64 0, !dbg [[DBG119:![0-9]+]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG120:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP12]] to i64, !dbg [[DBG119]] +// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG119]] +// CHECK1-NEXT: store i32 [[TMP11]], ptr [[ARRAYIDX20]], align 4, !dbg [[DBG121:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B3]], i64 0, i64 0, !dbg [[DBG122:![0-9]+]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG123:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP13]] to i64, !dbg [[DBG122]] +// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG122]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX23]], align 4, !dbg [[DBG122]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i8, ptr [[TMP7]], align 1, !dbg [[DBG124:![0-9]+]] +// CHECK1-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP15]] to i1, !dbg [[DBG124]] +// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[LOADEDV]] to i32, !dbg [[DBG124]] +// CHECK1-NEXT: [[OR:%.*]] = or i32 [[CONV]], [[TMP14]], !dbg [[DBG124]] +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[OR]], 0, !dbg [[DBG124]] +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8, !dbg [[DBG124]] +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[TMP7]], align 1, !dbg [[DBG124]] +// CHECK1-NEXT: ret void, !dbg [[DBG125:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l23_debug___omp_outlined -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG112:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG126:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -225,61 +257,29 @@ int main() { // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META119:![0-9]+]], !DIExpression(), [[META120:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META129:![0-9]+]], !DIExpression(), [[META130:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META121:![0-9]+]], !DIExpression(), [[META120]]) -// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META122:![0-9]+]], !DIExpression(), [[META120]]) -// CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META123:![0-9]+]], !DIExpression(), [[META120]]) -// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META124:![0-9]+]], !DIExpression(), [[META120]]) -// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META125:![0-9]+]], !DIExpression(), [[META120]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG126:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG126]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG126]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG126]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG126]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG126]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG126]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG126]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG126]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG126]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG126]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l23_debug___omp_outlined_debug__(ptr [[TMP3]], ptr [[TMP4]], ptr addrspace(1) [[TMP9]], i32 [[TMP6]], ptr [[TMP7]], ptr addrspace(1) [[TMP10]]) #[[ATTR3:[0-9]+]], !dbg [[DBG126]] -// CHECK1-NEXT: ret void, !dbg [[DBG126]] -// -// -// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l23 -// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR5:[0-9]+]] !dbg [[DBG127:![0-9]+]] { -// CHECK1-NEXT: entry: -// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 -// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META130:![0-9]+]], !DIExpression(), [[META131:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META131:![0-9]+]], !DIExpression(), [[META130]]) // CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META132:![0-9]+]], !DIExpression(), [[META131]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META132:![0-9]+]], !DIExpression(), [[META130]]) // CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META133:![0-9]+]], !DIExpression(), [[META131]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META133:![0-9]+]], !DIExpression(), [[META130]]) // CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META134:![0-9]+]], !DIExpression(), [[META131]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META134:![0-9]+]], !DIExpression(), [[META130]]) // CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META135:![0-9]+]], !DIExpression(), [[META131]]) +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META135:![0-9]+]], !DIExpression(), [[META130]]) // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG136:![0-9]+]] // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG136]] // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG136]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG136]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG136]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG136]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG136]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG136]] -// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(1), !dbg [[DBG136]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG136]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l23_debug__(ptr [[TMP3]], ptr addrspace(1) [[TMP8]], i32 [[TMP5]], ptr [[TMP6]], ptr addrspace(1) [[TMP9]]) #[[ATTR3]], !dbg [[DBG136]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG136]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG136]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG136]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG136]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG136]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG136]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG136]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG136]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l23_debug___omp_outlined_debug__(ptr [[TMP3]], ptr [[TMP4]], ptr addrspace(1) [[TMP9]], i32 [[TMP6]], ptr [[TMP7]], ptr addrspace(1) [[TMP10]]) #[[ATTR3]], !dbg [[DBG136]] // CHECK1-NEXT: ret void, !dbg [[DBG136]] // // @@ -342,8 +342,41 @@ int main() { // CHECK1-NEXT: ret void, !dbg [[DBG152]] // // +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l37 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG158:![0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META159:![0-9]+]], !DIExpression(), [[META160:![0-9]+]]) +// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META161:![0-9]+]], !DIExpression(), [[META160]]) +// CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META162:![0-9]+]], !DIExpression(), [[META160]]) +// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META163:![0-9]+]], !DIExpression(), [[META160]]) +// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META164:![0-9]+]], !DIExpression(), [[META160]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG165:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG165]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG165]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG165]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG165]] +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG165]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG165]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG165]] +// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(1), !dbg [[DBG165]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP6]] to ptr addrspace(1), !dbg [[DBG165]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG165]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l37_debug__(ptr [[TMP3]], ptr addrspace(1) [[TMP8]], i32 [[TMP5]], ptr addrspace(1) [[TMP9]], ptr addrspace(1) [[TMP10]]) #[[ATTR3]], !dbg [[DBG165]] +// CHECK1-NEXT: ret void, !dbg [[DBG165]] +// +// // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l37_debug___omp_outlined_debug__ -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], i32 noundef [[A:%.*]], ptr addrspace(1) noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG158:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], i32 noundef [[A:%.*]], ptr addrspace(1) noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG166:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -359,74 +392,74 @@ int main() { // CHECK1-NEXT: [[H:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[D:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META161:![0-9]+]], !DIExpression(), [[META162:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META169:![0-9]+]], !DIExpression(), [[META170:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META163:![0-9]+]], !DIExpression(), [[META162]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META171:![0-9]+]], !DIExpression(), [[META170]]) // CHECK1-NEXT: store ptr addrspace(1) [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META164:![0-9]+]], !DIExpression(), [[META165:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META172:![0-9]+]], !DIExpression(), [[META173:![0-9]+]]) // CHECK1-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META166:![0-9]+]], !DIExpression(), [[META167:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META174:![0-9]+]], !DIExpression(), [[META175:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META168:![0-9]+]], !DIExpression(), [[META169:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META176:![0-9]+]], !DIExpression(), [[META177:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META170:![0-9]+]], !DIExpression(), [[META171:![0-9]+]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG172:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG172]] -// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG172]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG172]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr addrspace(1), ptr [[B_ADDR]], align 8, !dbg [[DBG172]] -// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[TMP3]] to ptr, !dbg [[DBG172]] -// CHECK1-NEXT: store ptr [[TMP4]], ptr [[_TMP1]], align 8, !dbg [[DBG172]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG172]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG172]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast ptr addrspace(1) [[TMP6]] to ptr, !dbg [[DBG172]] -// CHECK1-NEXT: store ptr [[TMP7]], ptr [[_TMP2]], align 8, !dbg [[DBG172]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG172]] -// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META173:![0-9]+]], !DIExpression(), [[META175:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG176:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG176]] -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX3]], i64 0, i64 1, !dbg [[DBG176]] -// CHECK1-NEXT: store ptr [[ARRAYIDX4]], ptr [[F]], align 8, !dbg [[META175]] -// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META177:![0-9]+]], !DIExpression(), [[META178:![0-9]+]]) -// CHECK1-NEXT: store ptr [[A_ADDR]], ptr [[G]], align 8, !dbg [[META178]] -// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META179:![0-9]+]], !DIExpression(), [[META180:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 1, !dbg [[DBG181:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX5]], i64 0, i64 1, !dbg [[DBG181]] -// CHECK1-NEXT: store ptr [[ARRAYIDX6]], ptr [[H]], align 8, !dbg [[META180]] -// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META182:![0-9]+]], !DIExpression(), [[META183:![0-9]+]]) -// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META183]] -// CHECK1-NEXT: store i32 5, ptr [[A_ADDR]], align 4, !dbg [[DBG184:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 0, !dbg [[DBG185:![0-9]+]] -// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG186:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP9]] to i64, !dbg [[DBG185]] -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX7]], i64 0, i64 [[IDXPROM]], !dbg [[DBG185]] -// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX8]], align 4, !dbg [[DBG187:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG188:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX9]], i64 0, i64 0, !dbg [[DBG188]] -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG189:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM11:%.*]] = sext i32 [[TMP10]] to i64, !dbg [[DBG188]] -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX10]], i64 0, i64 [[IDXPROM11]], !dbg [[DBG188]] -// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX12]], align 4, !dbg [[DBG190:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG191:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX13]], i64 0, i64 0, !dbg [[DBG191]] -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG192:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP11]] to i64, !dbg [[DBG191]] -// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX14]], i64 0, i64 [[IDXPROM15]], !dbg [[DBG191]] -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[ARRAYIDX16]], align 4, !dbg [[DBG191]] -// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 0, !dbg [[DBG193:![0-9]+]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG194:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM18:%.*]] = sext i32 [[TMP13]] to i64, !dbg [[DBG193]] -// CHECK1-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX17]], i64 0, i64 [[IDXPROM18]], !dbg [[DBG193]] -// CHECK1-NEXT: store i32 [[TMP12]], ptr [[ARRAYIDX19]], align 4, !dbg [[DBG195:![0-9]+]] -// CHECK1-NEXT: [[TMP14:%.*]] = load i8, ptr [[TMP8]], align 1, !dbg [[DBG196:![0-9]+]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP14]] to i1, !dbg [[DBG196]] -// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG196]] -// CHECK1-NEXT: store i32 [[CONV]], ptr [[D]], align 4, !dbg [[DBG197:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG198:![0-9]+]] +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META178:![0-9]+]], !DIExpression(), [[META179:![0-9]+]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG180:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG180]] +// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr addrspace(1), ptr [[B_ADDR]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[TMP3]] to ptr, !dbg [[DBG180]] +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[_TMP1]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast ptr addrspace(1) [[TMP6]] to ptr, !dbg [[DBG180]] +// CHECK1-NEXT: store ptr [[TMP7]], ptr [[_TMP2]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META181:![0-9]+]], !DIExpression(), [[META183:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG184:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG184]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX3]], i64 0, i64 1, !dbg [[DBG184]] +// CHECK1-NEXT: store ptr [[ARRAYIDX4]], ptr [[F]], align 8, !dbg [[META183]] +// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META185:![0-9]+]], !DIExpression(), [[META186:![0-9]+]]) +// CHECK1-NEXT: store ptr [[A_ADDR]], ptr [[G]], align 8, !dbg [[META186]] +// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META187:![0-9]+]], !DIExpression(), [[META188:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 1, !dbg [[DBG189:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX5]], i64 0, i64 1, !dbg [[DBG189]] +// CHECK1-NEXT: store ptr [[ARRAYIDX6]], ptr [[H]], align 8, !dbg [[META188]] +// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META190:![0-9]+]], !DIExpression(), [[META191:![0-9]+]]) +// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META191]] +// CHECK1-NEXT: store i32 5, ptr [[A_ADDR]], align 4, !dbg [[DBG192:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 0, !dbg [[DBG193:![0-9]+]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG194:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP9]] to i64, !dbg [[DBG193]] +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX7]], i64 0, i64 [[IDXPROM]], !dbg [[DBG193]] +// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX8]], align 4, !dbg [[DBG195:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG196:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX9]], i64 0, i64 0, !dbg [[DBG196]] +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG197:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM11:%.*]] = sext i32 [[TMP10]] to i64, !dbg [[DBG196]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX10]], i64 0, i64 [[IDXPROM11]], !dbg [[DBG196]] +// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX12]], align 4, !dbg [[DBG198:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG199:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX13]], i64 0, i64 0, !dbg [[DBG199]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG200:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP11]] to i64, !dbg [[DBG199]] +// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX14]], i64 0, i64 [[IDXPROM15]], !dbg [[DBG199]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[ARRAYIDX16]], align 4, !dbg [[DBG199]] +// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 0, !dbg [[DBG201:![0-9]+]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG202:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM18:%.*]] = sext i32 [[TMP13]] to i64, !dbg [[DBG201]] +// CHECK1-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX17]], i64 0, i64 [[IDXPROM18]], !dbg [[DBG201]] +// CHECK1-NEXT: store i32 [[TMP12]], ptr [[ARRAYIDX19]], align 4, !dbg [[DBG203:![0-9]+]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i8, ptr [[TMP8]], align 1, !dbg [[DBG204:![0-9]+]] +// CHECK1-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP14]] to i1, !dbg [[DBG204]] +// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[LOADEDV]] to i32, !dbg [[DBG204]] +// CHECK1-NEXT: store i32 [[CONV]], ptr [[D]], align 4, !dbg [[DBG205:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG206:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l37_debug___omp_outlined -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG199:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG207:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -435,63 +468,30 @@ int main() { // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META200:![0-9]+]], !DIExpression(), [[META201:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META208:![0-9]+]], !DIExpression(), [[META209:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META202:![0-9]+]], !DIExpression(), [[META201]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META210:![0-9]+]], !DIExpression(), [[META209]]) // CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META203:![0-9]+]], !DIExpression(), [[META201]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META211:![0-9]+]], !DIExpression(), [[META209]]) // CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META204:![0-9]+]], !DIExpression(), [[META201]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META212:![0-9]+]], !DIExpression(), [[META209]]) // CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META205:![0-9]+]], !DIExpression(), [[META201]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META213:![0-9]+]], !DIExpression(), [[META209]]) // CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META206:![0-9]+]], !DIExpression(), [[META201]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG207:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG207]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG207]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG207]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG207]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG207]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG207]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG207]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG207]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG207]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG207]] -// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG207]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l37_debug___omp_outlined_debug__(ptr [[TMP3]], ptr [[TMP4]], ptr addrspace(1) [[TMP9]], i32 [[TMP6]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]]) #[[ATTR3]], !dbg [[DBG207]] -// CHECK1-NEXT: ret void, !dbg [[DBG207]] -// -// -// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l37 -// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR5]] !dbg [[DBG208:![0-9]+]] { -// CHECK1-NEXT: entry: -// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 -// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META209:![0-9]+]], !DIExpression(), [[META210:![0-9]+]]) -// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META211:![0-9]+]], !DIExpression(), [[META210]]) -// CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META212:![0-9]+]], !DIExpression(), [[META210]]) -// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META213:![0-9]+]], !DIExpression(), [[META210]]) -// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META214:![0-9]+]], !DIExpression(), [[META210]]) +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META214:![0-9]+]], !DIExpression(), [[META209]]) // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG215:![0-9]+]] // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG215]] // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG215]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG215]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG215]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG215]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG215]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG215]] -// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(1), !dbg [[DBG215]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP6]] to ptr addrspace(1), !dbg [[DBG215]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG215]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG215]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG215]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG215]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG215]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG215]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG215]] // CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG215]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l37_debug__(ptr [[TMP3]], ptr addrspace(1) [[TMP8]], i32 [[TMP5]], ptr addrspace(1) [[TMP9]], ptr addrspace(1) [[TMP10]]) #[[ATTR3]], !dbg [[DBG215]] +// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG215]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l37_debug___omp_outlined_debug__(ptr [[TMP3]], ptr [[TMP4]], ptr addrspace(1) [[TMP9]], i32 [[TMP6]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]]) #[[ATTR3]], !dbg [[DBG215]] // CHECK1-NEXT: ret void, !dbg [[DBG215]] // // @@ -554,8 +554,43 @@ int main() { // CHECK1-NEXT: ret void, !dbg [[DBG231]] // // +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l51 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG237:![0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META240:![0-9]+]], !DIExpression(), [[META241:![0-9]+]]) +// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META242:![0-9]+]], !DIExpression(), [[META241]]) +// CHECK1-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META243:![0-9]+]], !DIExpression(), [[META241]]) +// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META244:![0-9]+]], !DIExpression(), [[META241]]) +// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META245:![0-9]+]], !DIExpression(), [[META241]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG246:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG246]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG246]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG246]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG246]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG246]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG246]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG246]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG246]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG246]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP6]] to ptr addrspace(1), !dbg [[DBG246]] +// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG246]] +// CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG246]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l51_debug__(ptr [[TMP4]], ptr addrspace(1) [[TMP9]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]], ptr addrspace(1) [[TMP12]]) #[[ATTR3]], !dbg [[DBG246]] +// CHECK1-NEXT: ret void, !dbg [[DBG246]] +// +// // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l51_debug___omp_outlined_debug__ -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], ptr addrspace(1) noalias noundef [[A:%.*]], ptr addrspace(1) noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG237:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], ptr addrspace(1) noalias noundef [[A:%.*]], ptr addrspace(1) noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG247:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -572,82 +607,82 @@ int main() { // CHECK1-NEXT: [[H:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[D:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META240:![0-9]+]], !DIExpression(), [[META241:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META250:![0-9]+]], !DIExpression(), [[META251:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META242:![0-9]+]], !DIExpression(), [[META241]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META252:![0-9]+]], !DIExpression(), [[META251]]) // CHECK1-NEXT: store ptr addrspace(1) [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META243:![0-9]+]], !DIExpression(), [[META244:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META253:![0-9]+]], !DIExpression(), [[META254:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META245:![0-9]+]], !DIExpression(), [[META246:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META255:![0-9]+]], !DIExpression(), [[META256:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META247:![0-9]+]], !DIExpression(), [[META248:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META257:![0-9]+]], !DIExpression(), [[META258:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META249:![0-9]+]], !DIExpression(), [[META250:![0-9]+]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG251:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG251]] -// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG251]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG251]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr addrspace(1), ptr [[A_ADDR]], align 8, !dbg [[DBG251]] -// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[TMP3]] to ptr, !dbg [[DBG251]] -// CHECK1-NEXT: store ptr [[TMP4]], ptr [[_TMP1]], align 8, !dbg [[DBG251]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG251]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr addrspace(1), ptr [[B_ADDR]], align 8, !dbg [[DBG251]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast ptr addrspace(1) [[TMP6]] to ptr, !dbg [[DBG251]] -// CHECK1-NEXT: store ptr [[TMP7]], ptr [[_TMP2]], align 8, !dbg [[DBG251]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG251]] -// CHECK1-NEXT: [[TMP9:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG251]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr addrspace(1) [[TMP9]] to ptr, !dbg [[DBG251]] -// CHECK1-NEXT: store ptr [[TMP10]], ptr [[_TMP3]], align 8, !dbg [[DBG251]] -// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[_TMP3]], align 8, !dbg [[DBG251]] -// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META252:![0-9]+]], !DIExpression(), [[META254:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG255:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG255]] -// CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX4]], i64 0, i64 1, !dbg [[DBG255]] -// CHECK1-NEXT: store ptr [[ARRAYIDX5]], ptr [[F]], align 8, !dbg [[META254]] -// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META256:![0-9]+]], !DIExpression(), [[META257:![0-9]+]]) -// CHECK1-NEXT: store ptr [[TMP5]], ptr [[G]], align 8, !dbg [[META257]] -// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META258:![0-9]+]], !DIExpression(), [[META259:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 1, !dbg [[DBG260:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX6]], i64 0, i64 1, !dbg [[DBG260]] -// CHECK1-NEXT: store ptr [[ARRAYIDX7]], ptr [[H]], align 8, !dbg [[META259]] -// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META261:![0-9]+]], !DIExpression(), [[META262:![0-9]+]]) -// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META262]] -// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4, !dbg [[DBG263:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG264:![0-9]+]] -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG265:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP12]] to i64, !dbg [[DBG264]] -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX8]], i64 0, i64 [[IDXPROM]], !dbg [[DBG264]] -// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX9]], align 4, !dbg [[DBG266:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG267:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX10]], i64 0, i64 0, !dbg [[DBG267]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG268:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM12:%.*]] = sext i32 [[TMP13]] to i64, !dbg [[DBG267]] -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX11]], i64 0, i64 [[IDXPROM12]], !dbg [[DBG267]] -// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX13]], align 4, !dbg [[DBG269:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG270:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX14]], i64 0, i64 0, !dbg [[DBG270]] -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG271:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM16:%.*]] = sext i32 [[TMP14]] to i64, !dbg [[DBG270]] -// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX15]], i64 0, i64 [[IDXPROM16]], !dbg [[DBG270]] -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX17]], align 4, !dbg [[DBG270]] -// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG272:![0-9]+]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG273:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP16]] to i64, !dbg [[DBG272]] -// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG272]] -// CHECK1-NEXT: store i32 [[TMP15]], ptr [[ARRAYIDX20]], align 4, !dbg [[DBG274:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG275:![0-9]+]] -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG276:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP17]] to i64, !dbg [[DBG275]] -// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[ARRAYIDX23]], align 4, !dbg [[DBG275]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP18]], 0, !dbg [[DBG275]] -// CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TOBOOL]] to i8, !dbg [[DBG277:![0-9]+]] -// CHECK1-NEXT: store i8 [[FROMBOOL]], ptr [[TMP11]], align 1, !dbg [[DBG277]] -// CHECK1-NEXT: ret void, !dbg [[DBG278:![0-9]+]] +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META259:![0-9]+]], !DIExpression(), [[META260:![0-9]+]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG261:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG261]] +// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG261]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG261]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr addrspace(1), ptr [[A_ADDR]], align 8, !dbg [[DBG261]] +// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[TMP3]] to ptr, !dbg [[DBG261]] +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[_TMP1]], align 8, !dbg [[DBG261]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG261]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr addrspace(1), ptr [[B_ADDR]], align 8, !dbg [[DBG261]] +// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast ptr addrspace(1) [[TMP6]] to ptr, !dbg [[DBG261]] +// CHECK1-NEXT: store ptr [[TMP7]], ptr [[_TMP2]], align 8, !dbg [[DBG261]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG261]] +// CHECK1-NEXT: [[TMP9:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG261]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr addrspace(1) [[TMP9]] to ptr, !dbg [[DBG261]] +// CHECK1-NEXT: store ptr [[TMP10]], ptr [[_TMP3]], align 8, !dbg [[DBG261]] +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[_TMP3]], align 8, !dbg [[DBG261]] +// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META262:![0-9]+]], !DIExpression(), [[META264:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG265:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG265]] +// CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX4]], i64 0, i64 1, !dbg [[DBG265]] +// CHECK1-NEXT: store ptr [[ARRAYIDX5]], ptr [[F]], align 8, !dbg [[META264]] +// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META266:![0-9]+]], !DIExpression(), [[META267:![0-9]+]]) +// CHECK1-NEXT: store ptr [[TMP5]], ptr [[G]], align 8, !dbg [[META267]] +// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META268:![0-9]+]], !DIExpression(), [[META269:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 1, !dbg [[DBG270:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX6]], i64 0, i64 1, !dbg [[DBG270]] +// CHECK1-NEXT: store ptr [[ARRAYIDX7]], ptr [[H]], align 8, !dbg [[META269]] +// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META271:![0-9]+]], !DIExpression(), [[META272:![0-9]+]]) +// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META272]] +// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4, !dbg [[DBG273:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG274:![0-9]+]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG275:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP12]] to i64, !dbg [[DBG274]] +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX8]], i64 0, i64 [[IDXPROM]], !dbg [[DBG274]] +// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX9]], align 4, !dbg [[DBG276:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG277:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX10]], i64 0, i64 0, !dbg [[DBG277]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG278:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM12:%.*]] = sext i32 [[TMP13]] to i64, !dbg [[DBG277]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX11]], i64 0, i64 [[IDXPROM12]], !dbg [[DBG277]] +// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX13]], align 4, !dbg [[DBG279:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG280:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX14]], i64 0, i64 0, !dbg [[DBG280]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG281:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM16:%.*]] = sext i32 [[TMP14]] to i64, !dbg [[DBG280]] +// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX15]], i64 0, i64 [[IDXPROM16]], !dbg [[DBG280]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX17]], align 4, !dbg [[DBG280]] +// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG282:![0-9]+]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG283:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP16]] to i64, !dbg [[DBG282]] +// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG282]] +// CHECK1-NEXT: store i32 [[TMP15]], ptr [[ARRAYIDX20]], align 4, !dbg [[DBG284:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG285:![0-9]+]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG286:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP17]] to i64, !dbg [[DBG285]] +// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[ARRAYIDX23]], align 4, !dbg [[DBG285]] +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP18]], 0, !dbg [[DBG285]] +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8, !dbg [[DBG287:![0-9]+]] +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[TMP11]], align 1, !dbg [[DBG287]] +// CHECK1-NEXT: ret void, !dbg [[DBG288:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l51_debug___omp_outlined -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG279:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG289:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -656,66 +691,31 @@ int main() { // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META282:![0-9]+]], !DIExpression(), [[META283:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META292:![0-9]+]], !DIExpression(), [[META293:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META284:![0-9]+]], !DIExpression(), [[META283]]) -// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META285:![0-9]+]], !DIExpression(), [[META283]]) -// CHECK1-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META286:![0-9]+]], !DIExpression(), [[META283]]) -// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META287:![0-9]+]], !DIExpression(), [[META283]]) -// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META288:![0-9]+]], !DIExpression(), [[META283]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG289:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG289]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG289]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG289]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG289]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG289]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG289]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG289]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG289]] -// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG289]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP6]] to ptr addrspace(1), !dbg [[DBG289]] -// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG289]] -// CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG289]] -// CHECK1-NEXT: [[TMP13:%.*]] = addrspacecast ptr [[TMP9]] to ptr addrspace(1), !dbg [[DBG289]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l51_debug___omp_outlined_debug__(ptr [[TMP4]], ptr [[TMP5]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]], ptr addrspace(1) [[TMP12]], ptr addrspace(1) [[TMP13]]) #[[ATTR3]], !dbg [[DBG289]] -// CHECK1-NEXT: ret void, !dbg [[DBG289]] -// -// -// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l51 -// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR5]] !dbg [[DBG290:![0-9]+]] { -// CHECK1-NEXT: entry: -// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META293:![0-9]+]], !DIExpression(), [[META294:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META294:![0-9]+]], !DIExpression(), [[META293]]) // CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META295:![0-9]+]], !DIExpression(), [[META294]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META295:![0-9]+]], !DIExpression(), [[META293]]) // CHECK1-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META296:![0-9]+]], !DIExpression(), [[META294]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META296:![0-9]+]], !DIExpression(), [[META293]]) // CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META297:![0-9]+]], !DIExpression(), [[META294]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META297:![0-9]+]], !DIExpression(), [[META293]]) // CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META298:![0-9]+]], !DIExpression(), [[META294]]) +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META298:![0-9]+]], !DIExpression(), [[META293]]) // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG299:![0-9]+]] // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG299]] // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG299]] // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG299]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG299]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG299]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG299]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG299]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG299]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG299]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG299]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG299]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG299]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG299]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG299]] +// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG299]] // CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP6]] to ptr addrspace(1), !dbg [[DBG299]] // CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG299]] // CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG299]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l51_debug__(ptr [[TMP4]], ptr addrspace(1) [[TMP9]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]], ptr addrspace(1) [[TMP12]]) #[[ATTR3]], !dbg [[DBG299]] +// CHECK1-NEXT: [[TMP13:%.*]] = addrspacecast ptr [[TMP9]] to ptr addrspace(1), !dbg [[DBG299]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l51_debug___omp_outlined_debug__(ptr [[TMP4]], ptr [[TMP5]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]], ptr addrspace(1) [[TMP12]], ptr addrspace(1) [[TMP13]]) #[[ATTR3]], !dbg [[DBG299]] // CHECK1-NEXT: ret void, !dbg [[DBG299]] // diff --git a/clang/test/OpenMP/target_parallel_defaultmap_messages.cpp b/clang/test/OpenMP/target_parallel_defaultmap_messages.cpp index 4c226e9ca2aef..3c628c4f3e172 100644 --- a/clang/test/OpenMP/target_parallel_defaultmap_messages.cpp +++ b/clang/test/OpenMP/target_parallel_defaultmap_messages.cpp @@ -1,5 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -verify=expected,omp51 -Wuninitialized -Wno-vla -DOMP51 -// RUN: %clang_cc1 -verify -fopenmp-simd %s -verify=expected,omp51 -Wuninitialized -Wno-vla -DOMP51 +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized + +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized -DOMP51 +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized -DOMP51 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -Wno-vla -DOMP5 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -Wno-vla -DOMP5 @@ -28,19 +31,19 @@ void foo() { template T tmain(T argc, S **argv) { -#pragma omp target parallel defaultmap( // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target parallel defaultmap( // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); -#pragma omp target parallel defaultmap() // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target parallel defaultmap() // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target parallel defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); - #pragma omp target parallel defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + #pragma omp target parallel defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target parallel defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target parallel defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); - #pragma omp target parallel defaultmap (scalar: // expected-error {{expected ')'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} + #pragma omp target parallel defaultmap (scalar: // expected-error {{expected ')'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target parallel defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); @@ -90,19 +93,19 @@ T tmain(T argc, S **argv) { } int main(int argc, char **argv) { -#pragma omp target parallel defaultmap( // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target parallel defaultmap( // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); -#pragma omp target parallel defaultmap() // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target parallel defaultmap() // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target parallel defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); - #pragma omp target parallel defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + #pragma omp target parallel defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target parallel defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target parallel defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); - #pragma omp target parallel defaultmap (scalar: // expected-error {{expected ')'}} omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} + #pragma omp target parallel defaultmap (scalar: // expected-error {{expected ')'}} omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target parallel defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); diff --git a/clang/test/OpenMP/target_parallel_for_debug_codegen.cpp b/clang/test/OpenMP/target_parallel_for_debug_codegen.cpp index e27cc0d536269..5addc4928918f 100644 --- a/clang/test/OpenMP/target_parallel_for_debug_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_for_debug_codegen.cpp @@ -78,8 +78,8 @@ int main() { // CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META46:![0-9]+]], !DIExpression(), [[META47:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[BB]], ptr [[BB_ADDR]], align 8 // CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META48:![0-9]+]], !DIExpression(), [[META49:![0-9]+]]) -// CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[DOTCAPTURE_EXPR_]] to i8 -// CHECK1-NEXT: store i8 [[FROMBOOL]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[DOTCAPTURE_EXPR_]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 // CHECK1-NEXT: #dbg_declare(ptr [[DOTCAPTURE_EXPR__ADDR]], [[META50:![0-9]+]], !DIExpression(), [[META51:![0-9]+]]) // CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG52:![0-9]+]] // CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG52]] @@ -110,8 +110,8 @@ int main() { // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[CAPTURED_VARS_ADDRS]], i64 0, i64 3, !dbg [[DBG55]] // CHECK1-NEXT: store ptr [[TMP7]], ptr [[TMP16]], align 8, !dbg [[DBG55]] // CHECK1-NEXT: [[TMP17:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !dbg [[DBG56:![0-9]+]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP17]] to i1, !dbg [[DBG56]] -// CHECK1-NEXT: [[TMP18:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG55]] +// CHECK1-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP17]] to i1, !dbg [[DBG56]] +// CHECK1-NEXT: [[TMP18:%.*]] = zext i1 [[LOADEDV]] to i32, !dbg [[DBG55]] // CHECK1-NEXT: call void @__kmpc_parallel_51(ptr @[[GLOB6]], i32 [[TMP9]], i32 [[TMP18]], i32 -1, i32 -1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug___omp_outlined, ptr null, ptr [[CAPTURED_VARS_ADDRS]], i64 4), !dbg [[DBG55]] // CHECK1-NEXT: call void @__kmpc_target_deinit(), !dbg [[DBG57:![0-9]+]] // CHECK1-NEXT: ret void, !dbg [[DBG58:![0-9]+]] @@ -119,8 +119,45 @@ int main() { // CHECK1-NEXT: ret void, !dbg [[DBG52]] // // +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1:[0-9]+]] !dbg [[DBG59:![0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META66:![0-9]+]], !DIExpression(), [[META67:![0-9]+]]) +// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META68:![0-9]+]], !DIExpression(), [[META67]]) +// CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META69:![0-9]+]], !DIExpression(), [[META67]]) +// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META70:![0-9]+]], !DIExpression(), [[META67]]) +// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META71:![0-9]+]], !DIExpression(), [[META67]]) +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[DOTCAPTURE_EXPR__ADDR]], [[META72:![0-9]+]], !DIExpression(), [[META67]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG73:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !dbg [[DBG73]] +// CHECK1-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP8]] to i1, !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(1), !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG73]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug__(ptr [[TMP3]], ptr addrspace(1) [[TMP9]], i32 [[TMP5]], ptr [[TMP6]], ptr addrspace(1) [[TMP10]], i1 [[LOADEDV]]) #[[ATTR3:[0-9]+]], !dbg [[DBG73]] +// CHECK1-NEXT: ret void, !dbg [[DBG73]] +// +// // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug___omp_outlined_debug__ -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], i32 noundef [[A:%.*]], ptr noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR1:[0-9]+]] !dbg [[DBG59:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], i32 noundef [[A:%.*]], ptr noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG74:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -144,149 +181,149 @@ int main() { // CHECK1-NEXT: [[H:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[D:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META66:![0-9]+]], !DIExpression(), [[META67:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META81:![0-9]+]], !DIExpression(), [[META82:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META68:![0-9]+]], !DIExpression(), [[META67]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META83:![0-9]+]], !DIExpression(), [[META82]]) // CHECK1-NEXT: store ptr addrspace(1) [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META69:![0-9]+]], !DIExpression(), [[META70:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META84:![0-9]+]], !DIExpression(), [[META85:![0-9]+]]) // CHECK1-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META71:![0-9]+]], !DIExpression(), [[META72:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META86:![0-9]+]], !DIExpression(), [[META87:![0-9]+]]) // CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META73:![0-9]+]], !DIExpression(), [[META74:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META88:![0-9]+]], !DIExpression(), [[META89:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META75:![0-9]+]], !DIExpression(), [[META76:![0-9]+]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG77:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG77]] -// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: store ptr [[TMP3]], ptr [[_TMP1]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast ptr addrspace(1) [[TMP5]] to ptr, !dbg [[DBG77]] -// CHECK1-NEXT: store ptr [[TMP6]], ptr [[_TMP2]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IV]], [[META78:![0-9]+]], !DIExpression(), [[META67]]) -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_LB]], [[META79:![0-9]+]], !DIExpression(), [[META67]]) -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG80:![0-9]+]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_UB]], [[META81:![0-9]+]], !DIExpression(), [[META67]]) -// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_STRIDE]], [[META82:![0-9]+]], !DIExpression(), [[META67]]) -// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IS_LAST]], [[META83:![0-9]+]], !DIExpression(), [[META67]]) -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: #dbg_declare(ptr [[B4]], [[META84:![0-9]+]], !DIExpression(), [[META67]]) -// CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[B4]], ptr align 4 [[TMP4]], i64 400, i1 false), !dbg [[DBG77]] -// CHECK1-NEXT: #dbg_declare(ptr [[I]], [[META85:![0-9]+]], !DIExpression(), [[META67]]) -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[TMP8]], align 4, !dbg [[DBG77]] -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3:[0-9]+]], i32 [[TMP9]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG86:![0-9]+]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG77]] +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META90:![0-9]+]], !DIExpression(), [[META91:![0-9]+]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG92:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG92]] +// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[_TMP1]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast ptr addrspace(1) [[TMP5]] to ptr, !dbg [[DBG92]] +// CHECK1-NEXT: store ptr [[TMP6]], ptr [[_TMP2]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IV]], [[META93:![0-9]+]], !DIExpression(), [[META82]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_LB]], [[META94:![0-9]+]], !DIExpression(), [[META82]]) +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG95:![0-9]+]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_UB]], [[META96:![0-9]+]], !DIExpression(), [[META82]]) +// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_STRIDE]], [[META97:![0-9]+]], !DIExpression(), [[META82]]) +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IS_LAST]], [[META98:![0-9]+]], !DIExpression(), [[META82]]) +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: #dbg_declare(ptr [[B4]], [[META99:![0-9]+]], !DIExpression(), [[META82]]) +// CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[B4]], ptr align 4 [[TMP4]], i64 400, i1 false), !dbg [[DBG92]] +// CHECK1-NEXT: #dbg_declare(ptr [[I]], [[META100:![0-9]+]], !DIExpression(), [[META82]]) +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[TMP8]], align 4, !dbg [[DBG92]] +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3:[0-9]+]], i32 [[TMP9]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG101:![0-9]+]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG92]] // CHECK1: omp.dispatch.cond: -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP10]], 9, !dbg [[DBG80]] -// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG80]] +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP10]], 9, !dbg [[DBG95]] +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG95]] // CHECK1: cond.true: -// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG80]] +// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG95]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG80]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG95]] // CHECK1: cond.end: -// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP11]], [[COND_FALSE]] ], !dbg [[DBG80]] -// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: store i32 [[TMP12]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]], !dbg [[DBG77]] -// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG77]] +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP11]], [[COND_FALSE]] ], !dbg [[DBG95]] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: store i32 [[TMP12]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]], !dbg [[DBG92]] +// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG92]] // CHECK1: omp.dispatch.body: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG77]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG92]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP15]], [[TMP16]], !dbg [[DBG77]] -// CHECK1-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG77]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP15]], [[TMP16]], !dbg [[DBG92]] +// CHECK1-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG92]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP17]], 1, !dbg [[DBG87:![0-9]+]] -// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG87]] -// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !dbg [[DBG87]] -// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META88:![0-9]+]], !DIExpression(), [[META91:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG92:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG92]] -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX7]], i64 0, i64 1, !dbg [[DBG92]] -// CHECK1-NEXT: store ptr [[ARRAYIDX8]], ptr [[F]], align 8, !dbg [[META91]] -// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META93:![0-9]+]], !DIExpression(), [[META94:![0-9]+]]) -// CHECK1-NEXT: store ptr [[A_ADDR]], ptr [[G]], align 8, !dbg [[META94]] -// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META95:![0-9]+]], !DIExpression(), [[META96:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B4]], i64 0, i64 1, !dbg [[DBG97:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX9]], i64 0, i64 1, !dbg [[DBG97]] -// CHECK1-NEXT: store ptr [[ARRAYIDX10]], ptr [[H]], align 8, !dbg [[META96]] -// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META98:![0-9]+]], !DIExpression(), [[META99:![0-9]+]]) -// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META99]] -// CHECK1-NEXT: store i32 5, ptr [[A_ADDR]], align 4, !dbg [[DBG100:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B4]], i64 0, i64 0, !dbg [[DBG101:![0-9]+]] -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG102:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP18]] to i64, !dbg [[DBG101]] -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX11]], i64 0, i64 [[IDXPROM]], !dbg [[DBG101]] -// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX12]], align 4, !dbg [[DBG103:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG104:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX13]], i64 0, i64 0, !dbg [[DBG104]] -// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG105:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP19]] to i64, !dbg [[DBG104]] -// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX14]], i64 0, i64 [[IDXPROM15]], !dbg [[DBG104]] -// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX16]], align 4, !dbg [[DBG106:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG107:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX17]], i64 0, i64 0, !dbg [[DBG107]] -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG108:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP20]] to i64, !dbg [[DBG107]] -// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG107]] -// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[ARRAYIDX20]], align 4, !dbg [[DBG107]] -// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B4]], i64 0, i64 0, !dbg [[DBG109:![0-9]+]] -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG110:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP22]] to i64, !dbg [[DBG109]] -// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG109]] -// CHECK1-NEXT: store i32 [[TMP21]], ptr [[ARRAYIDX23]], align 4, !dbg [[DBG111:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B4]], i64 0, i64 0, !dbg [[DBG112:![0-9]+]] -// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG113:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM25:%.*]] = sext i32 [[TMP23]] to i64, !dbg [[DBG112]] -// CHECK1-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX24]], i64 0, i64 [[IDXPROM25]], !dbg [[DBG112]] -// CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[ARRAYIDX26]], align 4, !dbg [[DBG112]] -// CHECK1-NEXT: [[TMP25:%.*]] = load i8, ptr [[TMP7]], align 1, !dbg [[DBG114:![0-9]+]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP25]] to i1, !dbg [[DBG114]] -// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG114]] -// CHECK1-NEXT: [[OR:%.*]] = or i32 [[CONV]], [[TMP24]], !dbg [[DBG114]] -// CHECK1-NEXT: [[TOBOOL27:%.*]] = icmp ne i32 [[OR]], 0, !dbg [[DBG114]] -// CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TOBOOL27]] to i8, !dbg [[DBG114]] -// CHECK1-NEXT: store i8 [[FROMBOOL]], ptr [[TMP7]], align 1, !dbg [[DBG114]] -// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG115:![0-9]+]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP17]], 1, !dbg [[DBG102:![0-9]+]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG102]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !dbg [[DBG102]] +// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META103:![0-9]+]], !DIExpression(), [[META106:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG107:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG107]] +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX7]], i64 0, i64 1, !dbg [[DBG107]] +// CHECK1-NEXT: store ptr [[ARRAYIDX8]], ptr [[F]], align 8, !dbg [[META106]] +// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META108:![0-9]+]], !DIExpression(), [[META109:![0-9]+]]) +// CHECK1-NEXT: store ptr [[A_ADDR]], ptr [[G]], align 8, !dbg [[META109]] +// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META110:![0-9]+]], !DIExpression(), [[META111:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B4]], i64 0, i64 1, !dbg [[DBG112:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX9]], i64 0, i64 1, !dbg [[DBG112]] +// CHECK1-NEXT: store ptr [[ARRAYIDX10]], ptr [[H]], align 8, !dbg [[META111]] +// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META113:![0-9]+]], !DIExpression(), [[META114:![0-9]+]]) +// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META114]] +// CHECK1-NEXT: store i32 5, ptr [[A_ADDR]], align 4, !dbg [[DBG115:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B4]], i64 0, i64 0, !dbg [[DBG116:![0-9]+]] +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG117:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP18]] to i64, !dbg [[DBG116]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX11]], i64 0, i64 [[IDXPROM]], !dbg [[DBG116]] +// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX12]], align 4, !dbg [[DBG118:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG119:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX13]], i64 0, i64 0, !dbg [[DBG119]] +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG120:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP19]] to i64, !dbg [[DBG119]] +// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX14]], i64 0, i64 [[IDXPROM15]], !dbg [[DBG119]] +// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX16]], align 4, !dbg [[DBG121:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG122:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX17]], i64 0, i64 0, !dbg [[DBG122]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG123:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP20]] to i64, !dbg [[DBG122]] +// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG122]] +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[ARRAYIDX20]], align 4, !dbg [[DBG122]] +// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B4]], i64 0, i64 0, !dbg [[DBG124:![0-9]+]] +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG125:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP22]] to i64, !dbg [[DBG124]] +// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG124]] +// CHECK1-NEXT: store i32 [[TMP21]], ptr [[ARRAYIDX23]], align 4, !dbg [[DBG126:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B4]], i64 0, i64 0, !dbg [[DBG127:![0-9]+]] +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG128:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM25:%.*]] = sext i32 [[TMP23]] to i64, !dbg [[DBG127]] +// CHECK1-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX24]], i64 0, i64 [[IDXPROM25]], !dbg [[DBG127]] +// CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[ARRAYIDX26]], align 4, !dbg [[DBG127]] +// CHECK1-NEXT: [[TMP25:%.*]] = load i8, ptr [[TMP7]], align 1, !dbg [[DBG129:![0-9]+]] +// CHECK1-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP25]] to i1, !dbg [[DBG129]] +// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[LOADEDV]] to i32, !dbg [[DBG129]] +// CHECK1-NEXT: [[OR:%.*]] = or i32 [[CONV]], [[TMP24]], !dbg [[DBG129]] +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[OR]], 0, !dbg [[DBG129]] +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8, !dbg [[DBG129]] +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[TMP7]], align 1, !dbg [[DBG129]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG130:![0-9]+]] // CHECK1: omp.body.continue: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG86]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG101]] // CHECK1: omp.inner.for.inc: -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP26]], 1, !dbg [[DBG77]] -// CHECK1-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG77]] -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG86]], !llvm.loop [[LOOP116:![0-9]+]] +// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP26]], 1, !dbg [[DBG92]] +// CHECK1-NEXT: store i32 [[ADD27]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG92]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG101]], !llvm.loop [[LOOP131:![0-9]+]] // CHECK1: omp.inner.for.end: -// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG86]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG101]] // CHECK1: omp.dispatch.inc: -// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP27]], [[TMP28]], !dbg [[DBG77]] -// CHECK1-NEXT: store i32 [[ADD29]], ptr [[DOTOMP_LB]], align 4, !dbg [[DBG77]] -// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP29]], [[TMP30]], !dbg [[DBG77]] -// CHECK1-NEXT: store i32 [[ADD30]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG77]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG86]], !llvm.loop [[LOOP118:![0-9]+]] +// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP27]], [[TMP28]], !dbg [[DBG92]] +// CHECK1-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_LB]], align 4, !dbg [[DBG92]] +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP29]], [[TMP30]], !dbg [[DBG92]] +// CHECK1-NEXT: store i32 [[ADD29]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG92]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG101]], !llvm.loop [[LOOP133:![0-9]+]] // CHECK1: omp.dispatch.end: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB5:[0-9]+]], i32 [[TMP9]]), !dbg [[DBG117:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG119:![0-9]+]] +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB5:[0-9]+]], i32 [[TMP9]]), !dbg [[DBG132:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG134:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug___omp_outlined -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG120:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG135:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -295,66 +332,29 @@ int main() { // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META127:![0-9]+]], !DIExpression(), [[META128:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META138:![0-9]+]], !DIExpression(), [[META139:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META129:![0-9]+]], !DIExpression(), [[META128]]) -// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META130:![0-9]+]], !DIExpression(), [[META128]]) -// CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META131:![0-9]+]], !DIExpression(), [[META128]]) -// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META132:![0-9]+]], !DIExpression(), [[META128]]) -// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META133:![0-9]+]], !DIExpression(), [[META128]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG134:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG134]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug___omp_outlined_debug__(ptr [[TMP3]], ptr [[TMP4]], ptr addrspace(1) [[TMP9]], i32 [[TMP6]], ptr [[TMP7]], ptr addrspace(1) [[TMP10]]) #[[ATTR3:[0-9]+]], !dbg [[DBG134]] -// CHECK1-NEXT: ret void, !dbg [[DBG134]] -// -// -// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13 -// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR5:[0-9]+]] !dbg [[DBG135:![0-9]+]] { -// CHECK1-NEXT: entry: -// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 -// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 -// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META138:![0-9]+]], !DIExpression(), [[META139:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META140:![0-9]+]], !DIExpression(), [[META139]]) // CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META140:![0-9]+]], !DIExpression(), [[META139]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META141:![0-9]+]], !DIExpression(), [[META139]]) // CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META141:![0-9]+]], !DIExpression(), [[META139]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META142:![0-9]+]], !DIExpression(), [[META139]]) // CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META142:![0-9]+]], !DIExpression(), [[META139]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META143:![0-9]+]], !DIExpression(), [[META139]]) // CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META143:![0-9]+]], !DIExpression(), [[META139]]) -// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTCAPTURE_EXPR__ADDR]], [[META144:![0-9]+]], !DIExpression(), [[META139]]) +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META144:![0-9]+]], !DIExpression(), [[META139]]) // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG145:![0-9]+]] // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG145]] // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG145]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG145]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG145]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG145]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG145]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG145]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !dbg [[DBG145]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP8]] to i1, !dbg [[DBG145]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(1), !dbg [[DBG145]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG145]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug__(ptr [[TMP3]], ptr addrspace(1) [[TMP9]], i32 [[TMP5]], ptr [[TMP6]], ptr addrspace(1) [[TMP10]], i1 [[TOBOOL]]) #[[ATTR3]], !dbg [[DBG145]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG145]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG145]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG145]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG145]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG145]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG145]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG145]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG145]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug___omp_outlined_debug__(ptr [[TMP3]], ptr [[TMP4]], ptr addrspace(1) [[TMP9]], i32 [[TMP6]], ptr [[TMP7]], ptr addrspace(1) [[TMP10]]) #[[ATTR3]], !dbg [[DBG145]] // CHECK1-NEXT: ret void, !dbg [[DBG145]] // // @@ -417,8 +417,41 @@ int main() { // CHECK1-NEXT: ret void, !dbg [[DBG161]] // // +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG167:![0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META170:![0-9]+]], !DIExpression(), [[META171:![0-9]+]]) +// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META172:![0-9]+]], !DIExpression(), [[META171]]) +// CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META173:![0-9]+]], !DIExpression(), [[META171]]) +// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META174:![0-9]+]], !DIExpression(), [[META171]]) +// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META175:![0-9]+]], !DIExpression(), [[META171]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG176:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(1), !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP6]] to ptr addrspace(1), !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG176]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27_debug__(ptr [[TMP3]], ptr addrspace(1) [[TMP8]], i32 [[TMP5]], ptr addrspace(1) [[TMP9]], ptr addrspace(1) [[TMP10]]) #[[ATTR3]], !dbg [[DBG176]] +// CHECK1-NEXT: ret void, !dbg [[DBG176]] +// +// // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27_debug___omp_outlined_debug__ -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], i32 noundef [[A:%.*]], ptr addrspace(1) noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG167:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], i32 noundef [[A:%.*]], ptr addrspace(1) noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG177:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -441,140 +474,140 @@ int main() { // CHECK1-NEXT: [[H:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[D:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META170:![0-9]+]], !DIExpression(), [[META171:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META180:![0-9]+]], !DIExpression(), [[META181:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META172:![0-9]+]], !DIExpression(), [[META171]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META182:![0-9]+]], !DIExpression(), [[META181]]) // CHECK1-NEXT: store ptr addrspace(1) [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META173:![0-9]+]], !DIExpression(), [[META174:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META183:![0-9]+]], !DIExpression(), [[META184:![0-9]+]]) // CHECK1-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META175:![0-9]+]], !DIExpression(), [[META176:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META185:![0-9]+]], !DIExpression(), [[META186:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META177:![0-9]+]], !DIExpression(), [[META178:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META187:![0-9]+]], !DIExpression(), [[META188:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META179:![0-9]+]], !DIExpression(), [[META180:![0-9]+]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG181:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG181]] -// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr addrspace(1), ptr [[B_ADDR]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[TMP3]] to ptr, !dbg [[DBG181]] -// CHECK1-NEXT: store ptr [[TMP4]], ptr [[_TMP1]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast ptr addrspace(1) [[TMP6]] to ptr, !dbg [[DBG181]] -// CHECK1-NEXT: store ptr [[TMP7]], ptr [[_TMP2]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IV]], [[META182:![0-9]+]], !DIExpression(), [[META171]]) -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_LB]], [[META183:![0-9]+]], !DIExpression(), [[META171]]) -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG184:![0-9]+]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_UB]], [[META185:![0-9]+]], !DIExpression(), [[META171]]) -// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_STRIDE]], [[META186:![0-9]+]], !DIExpression(), [[META171]]) -// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IS_LAST]], [[META187:![0-9]+]], !DIExpression(), [[META171]]) -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: #dbg_declare(ptr [[I]], [[META188:![0-9]+]], !DIExpression(), [[META171]]) -// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 4, !dbg [[DBG181]] -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB10:[0-9]+]], i32 [[TMP10]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG189:![0-9]+]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG181]] +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META189:![0-9]+]], !DIExpression(), [[META190:![0-9]+]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG191:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG191]] +// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr addrspace(1), ptr [[B_ADDR]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[TMP3]] to ptr, !dbg [[DBG191]] +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[_TMP1]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast ptr addrspace(1) [[TMP6]] to ptr, !dbg [[DBG191]] +// CHECK1-NEXT: store ptr [[TMP7]], ptr [[_TMP2]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IV]], [[META192:![0-9]+]], !DIExpression(), [[META181]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_LB]], [[META193:![0-9]+]], !DIExpression(), [[META181]]) +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG194:![0-9]+]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_UB]], [[META195:![0-9]+]], !DIExpression(), [[META181]]) +// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_STRIDE]], [[META196:![0-9]+]], !DIExpression(), [[META181]]) +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IS_LAST]], [[META197:![0-9]+]], !DIExpression(), [[META181]]) +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: #dbg_declare(ptr [[I]], [[META198:![0-9]+]], !DIExpression(), [[META181]]) +// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 4, !dbg [[DBG191]] +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB10:[0-9]+]], i32 [[TMP10]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG199:![0-9]+]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG191]] // CHECK1: omp.dispatch.cond: -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP11]], 9, !dbg [[DBG184]] -// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG184]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP11]], 9, !dbg [[DBG194]] +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG194]] // CHECK1: cond.true: -// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG184]] +// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG194]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG184]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG194]] // CHECK1: cond.end: -// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ], !dbg [[DBG184]] -// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[CMP4:%.*]] = icmp sle i32 [[TMP14]], [[TMP15]], !dbg [[DBG181]] -// CHECK1-NEXT: br i1 [[CMP4]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG181]] +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ], !dbg [[DBG194]] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[CMP4:%.*]] = icmp sle i32 [[TMP14]], [[TMP15]], !dbg [[DBG191]] +// CHECK1-NEXT: br i1 [[CMP4]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG191]] // CHECK1: omp.dispatch.body: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG181]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG191]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP16]], [[TMP17]], !dbg [[DBG181]] -// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG181]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP16]], [[TMP17]], !dbg [[DBG191]] +// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG191]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP18]], 1, !dbg [[DBG190:![0-9]+]] -// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG190]] -// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !dbg [[DBG190]] -// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META191:![0-9]+]], !DIExpression(), [[META193:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG194:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG194]] -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX6]], i64 0, i64 1, !dbg [[DBG194]] -// CHECK1-NEXT: store ptr [[ARRAYIDX7]], ptr [[F]], align 8, !dbg [[META193]] -// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META195:![0-9]+]], !DIExpression(), [[META196:![0-9]+]]) -// CHECK1-NEXT: store ptr [[A_ADDR]], ptr [[G]], align 8, !dbg [[META196]] -// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META197:![0-9]+]], !DIExpression(), [[META198:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 1, !dbg [[DBG199:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX8]], i64 0, i64 1, !dbg [[DBG199]] -// CHECK1-NEXT: store ptr [[ARRAYIDX9]], ptr [[H]], align 8, !dbg [[META198]] -// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META200:![0-9]+]], !DIExpression(), [[META201:![0-9]+]]) -// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META201]] -// CHECK1-NEXT: store i32 5, ptr [[A_ADDR]], align 4, !dbg [[DBG202:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 0, !dbg [[DBG203:![0-9]+]] -// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG204:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP19]] to i64, !dbg [[DBG203]] -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX10]], i64 0, i64 [[IDXPROM]], !dbg [[DBG203]] -// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX11]], align 4, !dbg [[DBG205:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG206:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX12]], i64 0, i64 0, !dbg [[DBG206]] -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG207:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM14:%.*]] = sext i32 [[TMP20]] to i64, !dbg [[DBG206]] -// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX13]], i64 0, i64 [[IDXPROM14]], !dbg [[DBG206]] -// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX15]], align 4, !dbg [[DBG208:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG209:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX16]], i64 0, i64 0, !dbg [[DBG209]] -// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG210:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM18:%.*]] = sext i32 [[TMP21]] to i64, !dbg [[DBG209]] -// CHECK1-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX17]], i64 0, i64 [[IDXPROM18]], !dbg [[DBG209]] -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[ARRAYIDX19]], align 4, !dbg [[DBG209]] -// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 0, !dbg [[DBG211:![0-9]+]] -// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG212:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM21:%.*]] = sext i32 [[TMP23]] to i64, !dbg [[DBG211]] -// CHECK1-NEXT: [[ARRAYIDX22:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX20]], i64 0, i64 [[IDXPROM21]], !dbg [[DBG211]] -// CHECK1-NEXT: store i32 [[TMP22]], ptr [[ARRAYIDX22]], align 4, !dbg [[DBG213:![0-9]+]] -// CHECK1-NEXT: [[TMP24:%.*]] = load i8, ptr [[TMP8]], align 1, !dbg [[DBG214:![0-9]+]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP24]] to i1, !dbg [[DBG214]] -// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG214]] -// CHECK1-NEXT: store i32 [[CONV]], ptr [[D]], align 4, !dbg [[DBG215:![0-9]+]] -// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG216:![0-9]+]] +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP18]], 1, !dbg [[DBG200:![0-9]+]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG200]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !dbg [[DBG200]] +// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META201:![0-9]+]], !DIExpression(), [[META203:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG204:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG204]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX6]], i64 0, i64 1, !dbg [[DBG204]] +// CHECK1-NEXT: store ptr [[ARRAYIDX7]], ptr [[F]], align 8, !dbg [[META203]] +// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META205:![0-9]+]], !DIExpression(), [[META206:![0-9]+]]) +// CHECK1-NEXT: store ptr [[A_ADDR]], ptr [[G]], align 8, !dbg [[META206]] +// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META207:![0-9]+]], !DIExpression(), [[META208:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 1, !dbg [[DBG209:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX8]], i64 0, i64 1, !dbg [[DBG209]] +// CHECK1-NEXT: store ptr [[ARRAYIDX9]], ptr [[H]], align 8, !dbg [[META208]] +// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META210:![0-9]+]], !DIExpression(), [[META211:![0-9]+]]) +// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META211]] +// CHECK1-NEXT: store i32 5, ptr [[A_ADDR]], align 4, !dbg [[DBG212:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 0, !dbg [[DBG213:![0-9]+]] +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG214:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP19]] to i64, !dbg [[DBG213]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX10]], i64 0, i64 [[IDXPROM]], !dbg [[DBG213]] +// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX11]], align 4, !dbg [[DBG215:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG216:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX12]], i64 0, i64 0, !dbg [[DBG216]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG217:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM14:%.*]] = sext i32 [[TMP20]] to i64, !dbg [[DBG216]] +// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX13]], i64 0, i64 [[IDXPROM14]], !dbg [[DBG216]] +// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX15]], align 4, !dbg [[DBG218:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG219:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX16]], i64 0, i64 0, !dbg [[DBG219]] +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG220:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM18:%.*]] = sext i32 [[TMP21]] to i64, !dbg [[DBG219]] +// CHECK1-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX17]], i64 0, i64 [[IDXPROM18]], !dbg [[DBG219]] +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[ARRAYIDX19]], align 4, !dbg [[DBG219]] +// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 0, !dbg [[DBG221:![0-9]+]] +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG222:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM21:%.*]] = sext i32 [[TMP23]] to i64, !dbg [[DBG221]] +// CHECK1-NEXT: [[ARRAYIDX22:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX20]], i64 0, i64 [[IDXPROM21]], !dbg [[DBG221]] +// CHECK1-NEXT: store i32 [[TMP22]], ptr [[ARRAYIDX22]], align 4, !dbg [[DBG223:![0-9]+]] +// CHECK1-NEXT: [[TMP24:%.*]] = load i8, ptr [[TMP8]], align 1, !dbg [[DBG224:![0-9]+]] +// CHECK1-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP24]] to i1, !dbg [[DBG224]] +// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[LOADEDV]] to i32, !dbg [[DBG224]] +// CHECK1-NEXT: store i32 [[CONV]], ptr [[D]], align 4, !dbg [[DBG225:![0-9]+]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG226:![0-9]+]] // CHECK1: omp.body.continue: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG189]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG199]] // CHECK1: omp.inner.for.inc: -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[ADD23:%.*]] = add nsw i32 [[TMP25]], 1, !dbg [[DBG181]] -// CHECK1-NEXT: store i32 [[ADD23]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG181]] -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG189]], !llvm.loop [[LOOP217:![0-9]+]] +// CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[ADD23:%.*]] = add nsw i32 [[TMP25]], 1, !dbg [[DBG191]] +// CHECK1-NEXT: store i32 [[ADD23]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG191]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG199]], !llvm.loop [[LOOP227:![0-9]+]] // CHECK1: omp.inner.for.end: -// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG189]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG199]] // CHECK1: omp.dispatch.inc: -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[ADD24:%.*]] = add nsw i32 [[TMP26]], [[TMP27]], !dbg [[DBG181]] -// CHECK1-NEXT: store i32 [[ADD24]], ptr [[DOTOMP_LB]], align 4, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[ADD25:%.*]] = add nsw i32 [[TMP28]], [[TMP29]], !dbg [[DBG181]] -// CHECK1-NEXT: store i32 [[ADD25]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG181]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG189]], !llvm.loop [[LOOP219:![0-9]+]] +// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[ADD24:%.*]] = add nsw i32 [[TMP26]], [[TMP27]], !dbg [[DBG191]] +// CHECK1-NEXT: store i32 [[ADD24]], ptr [[DOTOMP_LB]], align 4, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[ADD25:%.*]] = add nsw i32 [[TMP28]], [[TMP29]], !dbg [[DBG191]] +// CHECK1-NEXT: store i32 [[ADD25]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG191]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG199]], !llvm.loop [[LOOP229:![0-9]+]] // CHECK1: omp.dispatch.end: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB12:[0-9]+]], i32 [[TMP10]]), !dbg [[DBG218:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG220:![0-9]+]] +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB12:[0-9]+]], i32 [[TMP10]]), !dbg [[DBG228:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG230:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27_debug___omp_outlined -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG221:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG231:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -583,63 +616,30 @@ int main() { // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META222:![0-9]+]], !DIExpression(), [[META223:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META232:![0-9]+]], !DIExpression(), [[META233:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META224:![0-9]+]], !DIExpression(), [[META223]]) -// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META225:![0-9]+]], !DIExpression(), [[META223]]) -// CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META226:![0-9]+]], !DIExpression(), [[META223]]) -// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META227:![0-9]+]], !DIExpression(), [[META223]]) -// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META228:![0-9]+]], !DIExpression(), [[META223]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG229:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG229]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27_debug___omp_outlined_debug__(ptr [[TMP3]], ptr [[TMP4]], ptr addrspace(1) [[TMP9]], i32 [[TMP6]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]]) #[[ATTR3]], !dbg [[DBG229]] -// CHECK1-NEXT: ret void, !dbg [[DBG229]] -// -// -// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27 -// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR5]] !dbg [[DBG230:![0-9]+]] { -// CHECK1-NEXT: entry: -// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 -// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META233:![0-9]+]], !DIExpression(), [[META234:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META234:![0-9]+]], !DIExpression(), [[META233]]) // CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META235:![0-9]+]], !DIExpression(), [[META234]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META235:![0-9]+]], !DIExpression(), [[META233]]) // CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META236:![0-9]+]], !DIExpression(), [[META234]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META236:![0-9]+]], !DIExpression(), [[META233]]) // CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META237:![0-9]+]], !DIExpression(), [[META234]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META237:![0-9]+]], !DIExpression(), [[META233]]) // CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META238:![0-9]+]], !DIExpression(), [[META234]]) +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META238:![0-9]+]], !DIExpression(), [[META233]]) // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG239:![0-9]+]] // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG239]] // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG239]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG239]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG239]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG239]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG239]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG239]] -// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(1), !dbg [[DBG239]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP6]] to ptr addrspace(1), !dbg [[DBG239]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG239]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG239]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG239]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG239]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG239]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG239]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG239]] // CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG239]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27_debug__(ptr [[TMP3]], ptr addrspace(1) [[TMP8]], i32 [[TMP5]], ptr addrspace(1) [[TMP9]], ptr addrspace(1) [[TMP10]]) #[[ATTR3]], !dbg [[DBG239]] +// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG239]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27_debug___omp_outlined_debug__(ptr [[TMP3]], ptr [[TMP4]], ptr addrspace(1) [[TMP9]], i32 [[TMP6]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]]) #[[ATTR3]], !dbg [[DBG239]] // CHECK1-NEXT: ret void, !dbg [[DBG239]] // // @@ -702,8 +702,43 @@ int main() { // CHECK1-NEXT: ret void, !dbg [[DBG255]] // // +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG261:![0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META264:![0-9]+]], !DIExpression(), [[META265:![0-9]+]]) +// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META266:![0-9]+]], !DIExpression(), [[META265]]) +// CHECK1-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META267:![0-9]+]], !DIExpression(), [[META265]]) +// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META268:![0-9]+]], !DIExpression(), [[META265]]) +// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META269:![0-9]+]], !DIExpression(), [[META265]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG270:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP6]] to ptr addrspace(1), !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG270]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41_debug__(ptr [[TMP4]], ptr addrspace(1) [[TMP9]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]], ptr addrspace(1) [[TMP12]]) #[[ATTR3]], !dbg [[DBG270]] +// CHECK1-NEXT: ret void, !dbg [[DBG270]] +// +// // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41_debug___omp_outlined_debug__ -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], ptr addrspace(1) noalias noundef [[A:%.*]], ptr addrspace(1) noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG261:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], ptr addrspace(1) noalias noundef [[A:%.*]], ptr addrspace(1) noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG271:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -727,148 +762,148 @@ int main() { // CHECK1-NEXT: [[H:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[D:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META264:![0-9]+]], !DIExpression(), [[META265:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META274:![0-9]+]], !DIExpression(), [[META275:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META266:![0-9]+]], !DIExpression(), [[META265]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META276:![0-9]+]], !DIExpression(), [[META275]]) // CHECK1-NEXT: store ptr addrspace(1) [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META267:![0-9]+]], !DIExpression(), [[META268:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META277:![0-9]+]], !DIExpression(), [[META278:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META269:![0-9]+]], !DIExpression(), [[META270:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META279:![0-9]+]], !DIExpression(), [[META280:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META271:![0-9]+]], !DIExpression(), [[META272:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META281:![0-9]+]], !DIExpression(), [[META282:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META273:![0-9]+]], !DIExpression(), [[META274:![0-9]+]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG275:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG275]] -// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr addrspace(1), ptr [[A_ADDR]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[TMP3]] to ptr, !dbg [[DBG275]] -// CHECK1-NEXT: store ptr [[TMP4]], ptr [[_TMP1]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr addrspace(1), ptr [[B_ADDR]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast ptr addrspace(1) [[TMP6]] to ptr, !dbg [[DBG275]] -// CHECK1-NEXT: store ptr [[TMP7]], ptr [[_TMP2]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP9:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr addrspace(1) [[TMP9]] to ptr, !dbg [[DBG275]] -// CHECK1-NEXT: store ptr [[TMP10]], ptr [[_TMP3]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[_TMP3]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IV]], [[META276:![0-9]+]], !DIExpression(), [[META265]]) -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_LB]], [[META277:![0-9]+]], !DIExpression(), [[META265]]) -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG278:![0-9]+]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_UB]], [[META279:![0-9]+]], !DIExpression(), [[META265]]) -// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_STRIDE]], [[META280:![0-9]+]], !DIExpression(), [[META265]]) -// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IS_LAST]], [[META281:![0-9]+]], !DIExpression(), [[META265]]) -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: #dbg_declare(ptr [[I]], [[META282:![0-9]+]], !DIExpression(), [[META265]]) -// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4, !dbg [[DBG275]] -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB17:[0-9]+]], i32 [[TMP13]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG283:![0-9]+]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG275]] +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META283:![0-9]+]], !DIExpression(), [[META284:![0-9]+]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG285:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG285]] +// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr addrspace(1), ptr [[A_ADDR]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[TMP3]] to ptr, !dbg [[DBG285]] +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[_TMP1]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr addrspace(1), ptr [[B_ADDR]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast ptr addrspace(1) [[TMP6]] to ptr, !dbg [[DBG285]] +// CHECK1-NEXT: store ptr [[TMP7]], ptr [[_TMP2]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP9:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr addrspace(1) [[TMP9]] to ptr, !dbg [[DBG285]] +// CHECK1-NEXT: store ptr [[TMP10]], ptr [[_TMP3]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[_TMP3]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IV]], [[META286:![0-9]+]], !DIExpression(), [[META275]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_LB]], [[META287:![0-9]+]], !DIExpression(), [[META275]]) +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG288:![0-9]+]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_UB]], [[META289:![0-9]+]], !DIExpression(), [[META275]]) +// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_STRIDE]], [[META290:![0-9]+]], !DIExpression(), [[META275]]) +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IS_LAST]], [[META291:![0-9]+]], !DIExpression(), [[META275]]) +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: #dbg_declare(ptr [[I]], [[META292:![0-9]+]], !DIExpression(), [[META275]]) +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4, !dbg [[DBG285]] +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB17:[0-9]+]], i32 [[TMP13]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG293:![0-9]+]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG285]] // CHECK1: omp.dispatch.cond: -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP14]], 9, !dbg [[DBG278]] -// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG278]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP14]], 9, !dbg [[DBG288]] +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG288]] // CHECK1: cond.true: -// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG278]] +// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG288]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG278]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG288]] // CHECK1: cond.end: -// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP15]], [[COND_FALSE]] ], !dbg [[DBG278]] -// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]], !dbg [[DBG275]] -// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG275]] +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP15]], [[COND_FALSE]] ], !dbg [[DBG288]] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]], !dbg [[DBG285]] +// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG285]] // CHECK1: omp.dispatch.body: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG275]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG285]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP19]], [[TMP20]], !dbg [[DBG275]] -// CHECK1-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG275]] +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP19]], [[TMP20]], !dbg [[DBG285]] +// CHECK1-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG285]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP21]], 1, !dbg [[DBG284:![0-9]+]] -// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG284]] -// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !dbg [[DBG284]] -// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META285:![0-9]+]], !DIExpression(), [[META287:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG288:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG288]] -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX7]], i64 0, i64 1, !dbg [[DBG288]] -// CHECK1-NEXT: store ptr [[ARRAYIDX8]], ptr [[F]], align 8, !dbg [[META287]] -// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META289:![0-9]+]], !DIExpression(), [[META290:![0-9]+]]) -// CHECK1-NEXT: store ptr [[TMP5]], ptr [[G]], align 8, !dbg [[META290]] -// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META291:![0-9]+]], !DIExpression(), [[META292:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 1, !dbg [[DBG293:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX9]], i64 0, i64 1, !dbg [[DBG293]] -// CHECK1-NEXT: store ptr [[ARRAYIDX10]], ptr [[H]], align 8, !dbg [[META292]] -// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META294:![0-9]+]], !DIExpression(), [[META295:![0-9]+]]) -// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META295]] -// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4, !dbg [[DBG296:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG297:![0-9]+]] -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG298:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP22]] to i64, !dbg [[DBG297]] -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX11]], i64 0, i64 [[IDXPROM]], !dbg [[DBG297]] -// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX12]], align 4, !dbg [[DBG299:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG300:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX13]], i64 0, i64 0, !dbg [[DBG300]] -// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG301:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP23]] to i64, !dbg [[DBG300]] -// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX14]], i64 0, i64 [[IDXPROM15]], !dbg [[DBG300]] -// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX16]], align 4, !dbg [[DBG302:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG303:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX17]], i64 0, i64 0, !dbg [[DBG303]] -// CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG304:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP24]] to i64, !dbg [[DBG303]] -// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG303]] -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[ARRAYIDX20]], align 4, !dbg [[DBG303]] -// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG305:![0-9]+]] -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG306:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP26]] to i64, !dbg [[DBG305]] -// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG305]] -// CHECK1-NEXT: store i32 [[TMP25]], ptr [[ARRAYIDX23]], align 4, !dbg [[DBG307:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG308:![0-9]+]] -// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG309:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM25:%.*]] = sext i32 [[TMP27]] to i64, !dbg [[DBG308]] -// CHECK1-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX24]], i64 0, i64 [[IDXPROM25]], !dbg [[DBG308]] -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[ARRAYIDX26]], align 4, !dbg [[DBG308]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP28]], 0, !dbg [[DBG308]] -// CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TOBOOL]] to i8, !dbg [[DBG310:![0-9]+]] -// CHECK1-NEXT: store i8 [[FROMBOOL]], ptr [[TMP11]], align 1, !dbg [[DBG310]] -// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG311:![0-9]+]] +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP21]], 1, !dbg [[DBG294:![0-9]+]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG294]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !dbg [[DBG294]] +// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META295:![0-9]+]], !DIExpression(), [[META297:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG298:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG298]] +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX7]], i64 0, i64 1, !dbg [[DBG298]] +// CHECK1-NEXT: store ptr [[ARRAYIDX8]], ptr [[F]], align 8, !dbg [[META297]] +// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META299:![0-9]+]], !DIExpression(), [[META300:![0-9]+]]) +// CHECK1-NEXT: store ptr [[TMP5]], ptr [[G]], align 8, !dbg [[META300]] +// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META301:![0-9]+]], !DIExpression(), [[META302:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 1, !dbg [[DBG303:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX9]], i64 0, i64 1, !dbg [[DBG303]] +// CHECK1-NEXT: store ptr [[ARRAYIDX10]], ptr [[H]], align 8, !dbg [[META302]] +// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META304:![0-9]+]], !DIExpression(), [[META305:![0-9]+]]) +// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META305]] +// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4, !dbg [[DBG306:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG307:![0-9]+]] +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG308:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP22]] to i64, !dbg [[DBG307]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX11]], i64 0, i64 [[IDXPROM]], !dbg [[DBG307]] +// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX12]], align 4, !dbg [[DBG309:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG310:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX13]], i64 0, i64 0, !dbg [[DBG310]] +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG311:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP23]] to i64, !dbg [[DBG310]] +// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX14]], i64 0, i64 [[IDXPROM15]], !dbg [[DBG310]] +// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX16]], align 4, !dbg [[DBG312:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG313:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX17]], i64 0, i64 0, !dbg [[DBG313]] +// CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG314:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP24]] to i64, !dbg [[DBG313]] +// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG313]] +// CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[ARRAYIDX20]], align 4, !dbg [[DBG313]] +// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG315:![0-9]+]] +// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG316:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP26]] to i64, !dbg [[DBG315]] +// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG315]] +// CHECK1-NEXT: store i32 [[TMP25]], ptr [[ARRAYIDX23]], align 4, !dbg [[DBG317:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG318:![0-9]+]] +// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG319:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM25:%.*]] = sext i32 [[TMP27]] to i64, !dbg [[DBG318]] +// CHECK1-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX24]], i64 0, i64 [[IDXPROM25]], !dbg [[DBG318]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[ARRAYIDX26]], align 4, !dbg [[DBG318]] +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP28]], 0, !dbg [[DBG318]] +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8, !dbg [[DBG320:![0-9]+]] +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[TMP11]], align 1, !dbg [[DBG320]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG321:![0-9]+]] // CHECK1: omp.body.continue: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG283]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG293]] // CHECK1: omp.inner.for.inc: -// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP29]], 1, !dbg [[DBG275]] -// CHECK1-NEXT: store i32 [[ADD27]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG275]] -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG283]], !llvm.loop [[LOOP312:![0-9]+]] +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP29]], 1, !dbg [[DBG285]] +// CHECK1-NEXT: store i32 [[ADD27]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG285]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG293]], !llvm.loop [[LOOP322:![0-9]+]] // CHECK1: omp.inner.for.end: -// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG283]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG293]] // CHECK1: omp.dispatch.inc: -// CHECK1-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP30]], [[TMP31]], !dbg [[DBG275]] -// CHECK1-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_LB]], align 4, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP32:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP33:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP32]], [[TMP33]], !dbg [[DBG275]] -// CHECK1-NEXT: store i32 [[ADD29]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG275]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG283]], !llvm.loop [[LOOP314:![0-9]+]] +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP30]], [[TMP31]], !dbg [[DBG285]] +// CHECK1-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_LB]], align 4, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP32:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[TMP33:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP32]], [[TMP33]], !dbg [[DBG285]] +// CHECK1-NEXT: store i32 [[ADD29]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG285]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG293]], !llvm.loop [[LOOP324:![0-9]+]] // CHECK1: omp.dispatch.end: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB19:[0-9]+]], i32 [[TMP13]]), !dbg [[DBG313:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG315:![0-9]+]] +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB19:[0-9]+]], i32 [[TMP13]]), !dbg [[DBG323:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG325:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41_debug___omp_outlined -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG316:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG326:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -877,66 +912,31 @@ int main() { // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META319:![0-9]+]], !DIExpression(), [[META320:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META329:![0-9]+]], !DIExpression(), [[META330:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META321:![0-9]+]], !DIExpression(), [[META320]]) -// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META322:![0-9]+]], !DIExpression(), [[META320]]) -// CHECK1-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META323:![0-9]+]], !DIExpression(), [[META320]]) -// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META324:![0-9]+]], !DIExpression(), [[META320]]) -// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META325:![0-9]+]], !DIExpression(), [[META320]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG326:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP6]] to ptr addrspace(1), !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP13:%.*]] = addrspacecast ptr [[TMP9]] to ptr addrspace(1), !dbg [[DBG326]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41_debug___omp_outlined_debug__(ptr [[TMP4]], ptr [[TMP5]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]], ptr addrspace(1) [[TMP12]], ptr addrspace(1) [[TMP13]]) #[[ATTR3]], !dbg [[DBG326]] -// CHECK1-NEXT: ret void, !dbg [[DBG326]] -// -// -// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41 -// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR5]] !dbg [[DBG327:![0-9]+]] { -// CHECK1-NEXT: entry: -// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META330:![0-9]+]], !DIExpression(), [[META331:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META331:![0-9]+]], !DIExpression(), [[META330]]) // CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META332:![0-9]+]], !DIExpression(), [[META331]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META332:![0-9]+]], !DIExpression(), [[META330]]) // CHECK1-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META333:![0-9]+]], !DIExpression(), [[META331]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META333:![0-9]+]], !DIExpression(), [[META330]]) // CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META334:![0-9]+]], !DIExpression(), [[META331]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META334:![0-9]+]], !DIExpression(), [[META330]]) // CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META335:![0-9]+]], !DIExpression(), [[META331]]) +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META335:![0-9]+]], !DIExpression(), [[META330]]) // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG336:![0-9]+]] // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG336]] // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG336]] // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG336]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG336]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG336]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG336]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG336]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG336]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG336]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG336]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG336]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG336]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG336]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG336]] +// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG336]] // CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP6]] to ptr addrspace(1), !dbg [[DBG336]] // CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG336]] // CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG336]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41_debug__(ptr [[TMP4]], ptr addrspace(1) [[TMP9]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]], ptr addrspace(1) [[TMP12]]) #[[ATTR3]], !dbg [[DBG336]] +// CHECK1-NEXT: [[TMP13:%.*]] = addrspacecast ptr [[TMP9]] to ptr addrspace(1), !dbg [[DBG336]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41_debug___omp_outlined_debug__(ptr [[TMP4]], ptr [[TMP5]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]], ptr addrspace(1) [[TMP12]], ptr addrspace(1) [[TMP13]]) #[[ATTR3]], !dbg [[DBG336]] // CHECK1-NEXT: ret void, !dbg [[DBG336]] // diff --git a/clang/test/OpenMP/target_parallel_for_defaultmap_messages.cpp b/clang/test/OpenMP/target_parallel_for_defaultmap_messages.cpp index 8b58bb9111c81..b142ae1733a3c 100644 --- a/clang/test/OpenMP/target_parallel_for_defaultmap_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_defaultmap_messages.cpp @@ -1,5 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -verify=expected,omp51 -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd %s -verify=expected,omp51 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -DOMP5 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -DOMP5 @@ -15,21 +18,21 @@ T tmain(T argc, S **argv) { int i; #pragma omp target parallel for defaultmap // expected-error {{expected '(' after 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for defaultmap( // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target parallel for defaultmap( // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for defaultmap() // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target parallel for defaultmap() // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + #pragma omp target parallel for defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp51-error {{expected ')'}} omp5-note {{to match this '('}} omp51-note {{to match this '('}} +#pragma omp target parallel for defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5x-error {{expected ')'}} omp5-note {{to match this '('}} omp5x-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for defaultmap (scalar: // expected-error {{expected ')'}} omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} + #pragma omp target parallel for defaultmap (scalar: // expected-error {{expected ')'}} omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); @@ -41,21 +44,21 @@ int main(int argc, char **argv) { int i; #pragma omp target parallel for defaultmap // expected-error {{expected '(' after 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for defaultmap( // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target parallel for defaultmap( // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for defaultmap() // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target parallel for defaultmap() // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + #pragma omp target parallel for defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp51-error {{expected ')'}} omp5-note {{to match this '('}} omp51-note {{to match this '('}} +#pragma omp target parallel for defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5x-error {{expected ')'}} omp5-note {{to match this '('}} omp5x-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for defaultmap (scalar: // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} + #pragma omp target parallel for defaultmap (scalar: // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_parallel_for_simd_defaultmap_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_defaultmap_messages.cpp index 7d72547d24e1e..46f78290cba4b 100644 --- a/clang/test/OpenMP/target_parallel_for_simd_defaultmap_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_simd_defaultmap_messages.cpp @@ -1,5 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -verify=expected,omp51 -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd %s -verify=expected,omp51 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -DOMP5 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -DOMP5 @@ -15,21 +18,21 @@ T tmain(T argc, S **argv) { int i; #pragma omp target parallel for simd defaultmap // expected-error {{expected '(' after 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd defaultmap( // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target parallel for simd defaultmap( // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd defaultmap() // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target parallel for simd defaultmap() // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + #pragma omp target parallel for simd defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} +#pragma omp target parallel for simd defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp5x-error {{expected ')'}} omp5x-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd defaultmap (scalar: // expected-error {{expected ')'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} + #pragma omp target parallel for simd defaultmap (scalar: // expected-error {{expected ')'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); @@ -41,21 +44,21 @@ int main(int argc, char **argv) { int i; #pragma omp target parallel for simd defaultmap // expected-error {{expected '(' after 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd defaultmap( // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target parallel for simd defaultmap( // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd defaultmap() // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target parallel for simd defaultmap() // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + #pragma omp target parallel for simd defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} +#pragma omp target parallel for simd defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp5x-error {{expected ')'}} omp5x-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd defaultmap (scalar: // expected-error {{expected ')'}} omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} + #pragma omp target parallel for simd defaultmap (scalar: // expected-error {{expected ')'}} omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_parallel_generic_loop_codegen-3.cpp b/clang/test/OpenMP/target_parallel_generic_loop_codegen-3.cpp index ea0ef01f8161c..26a01c75f951f 100644 --- a/clang/test/OpenMP/target_parallel_generic_loop_codegen-3.cpp +++ b/clang/test/OpenMP/target_parallel_generic_loop_codegen-3.cpp @@ -78,8 +78,8 @@ int main() { // CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META46:![0-9]+]], !DIExpression(), [[META47:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[BB]], ptr [[BB_ADDR]], align 8 // CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META48:![0-9]+]], !DIExpression(), [[META49:![0-9]+]]) -// CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[DOTCAPTURE_EXPR_]] to i8 -// CHECK1-NEXT: store i8 [[FROMBOOL]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[DOTCAPTURE_EXPR_]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 // CHECK1-NEXT: #dbg_declare(ptr [[DOTCAPTURE_EXPR__ADDR]], [[META50:![0-9]+]], !DIExpression(), [[META51:![0-9]+]]) // CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG52:![0-9]+]] // CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG52]] @@ -110,8 +110,8 @@ int main() { // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[CAPTURED_VARS_ADDRS]], i64 0, i64 3, !dbg [[DBG55]] // CHECK1-NEXT: store ptr [[TMP7]], ptr [[TMP16]], align 8, !dbg [[DBG55]] // CHECK1-NEXT: [[TMP17:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !dbg [[DBG56:![0-9]+]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP17]] to i1, !dbg [[DBG56]] -// CHECK1-NEXT: [[TMP18:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG55]] +// CHECK1-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP17]] to i1, !dbg [[DBG56]] +// CHECK1-NEXT: [[TMP18:%.*]] = zext i1 [[LOADEDV]] to i32, !dbg [[DBG55]] // CHECK1-NEXT: call void @__kmpc_parallel_51(ptr @[[GLOB6]], i32 [[TMP9]], i32 [[TMP18]], i32 -1, i32 -1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug___omp_outlined, ptr null, ptr [[CAPTURED_VARS_ADDRS]], i64 4), !dbg [[DBG55]] // CHECK1-NEXT: call void @__kmpc_target_deinit(), !dbg [[DBG57:![0-9]+]] // CHECK1-NEXT: ret void, !dbg [[DBG58:![0-9]+]] @@ -119,8 +119,45 @@ int main() { // CHECK1-NEXT: ret void, !dbg [[DBG52]] // // +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1:[0-9]+]] !dbg [[DBG59:![0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META66:![0-9]+]], !DIExpression(), [[META67:![0-9]+]]) +// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META68:![0-9]+]], !DIExpression(), [[META67]]) +// CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META69:![0-9]+]], !DIExpression(), [[META67]]) +// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META70:![0-9]+]], !DIExpression(), [[META67]]) +// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META71:![0-9]+]], !DIExpression(), [[META67]]) +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[DOTCAPTURE_EXPR__ADDR]], [[META72:![0-9]+]], !DIExpression(), [[META67]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG73:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !dbg [[DBG73]] +// CHECK1-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP8]] to i1, !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(1), !dbg [[DBG73]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG73]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug__(ptr [[TMP3]], ptr addrspace(1) [[TMP9]], i32 [[TMP5]], ptr [[TMP6]], ptr addrspace(1) [[TMP10]], i1 [[LOADEDV]]) #[[ATTR3:[0-9]+]], !dbg [[DBG73]] +// CHECK1-NEXT: ret void, !dbg [[DBG73]] +// +// // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug___omp_outlined_debug__ -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], i32 noundef [[A:%.*]], ptr noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR1:[0-9]+]] !dbg [[DBG59:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], i32 noundef [[A:%.*]], ptr noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG74:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -144,149 +181,149 @@ int main() { // CHECK1-NEXT: [[H:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[D:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META66:![0-9]+]], !DIExpression(), [[META67:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META81:![0-9]+]], !DIExpression(), [[META82:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META68:![0-9]+]], !DIExpression(), [[META67]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META83:![0-9]+]], !DIExpression(), [[META82]]) // CHECK1-NEXT: store ptr addrspace(1) [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META69:![0-9]+]], !DIExpression(), [[META70:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META84:![0-9]+]], !DIExpression(), [[META85:![0-9]+]]) // CHECK1-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META71:![0-9]+]], !DIExpression(), [[META72:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META86:![0-9]+]], !DIExpression(), [[META87:![0-9]+]]) // CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META73:![0-9]+]], !DIExpression(), [[META74:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META88:![0-9]+]], !DIExpression(), [[META89:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META75:![0-9]+]], !DIExpression(), [[META76:![0-9]+]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG77:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG77]] -// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: store ptr [[TMP3]], ptr [[_TMP1]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast ptr addrspace(1) [[TMP5]] to ptr, !dbg [[DBG77]] -// CHECK1-NEXT: store ptr [[TMP6]], ptr [[_TMP2]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IV]], [[META78:![0-9]+]], !DIExpression(), [[META67]]) -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_LB]], [[META79:![0-9]+]], !DIExpression(), [[META67]]) -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG80:![0-9]+]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_UB]], [[META81:![0-9]+]], !DIExpression(), [[META67]]) -// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_STRIDE]], [[META82:![0-9]+]], !DIExpression(), [[META67]]) -// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IS_LAST]], [[META83:![0-9]+]], !DIExpression(), [[META67]]) -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: #dbg_declare(ptr [[B4]], [[META84:![0-9]+]], !DIExpression(), [[META67]]) -// CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[B4]], ptr align 4 [[TMP4]], i64 400, i1 false), !dbg [[DBG77]] -// CHECK1-NEXT: #dbg_declare(ptr [[I]], [[META85:![0-9]+]], !DIExpression(), [[META67]]) -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG77]] -// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[TMP8]], align 4, !dbg [[DBG77]] -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3:[0-9]+]], i32 [[TMP9]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG86:![0-9]+]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG77]] +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META90:![0-9]+]], !DIExpression(), [[META91:![0-9]+]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG92:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG92]] +// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[_TMP1]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast ptr addrspace(1) [[TMP5]] to ptr, !dbg [[DBG92]] +// CHECK1-NEXT: store ptr [[TMP6]], ptr [[_TMP2]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IV]], [[META93:![0-9]+]], !DIExpression(), [[META82]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_LB]], [[META94:![0-9]+]], !DIExpression(), [[META82]]) +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG95:![0-9]+]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_UB]], [[META96:![0-9]+]], !DIExpression(), [[META82]]) +// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_STRIDE]], [[META97:![0-9]+]], !DIExpression(), [[META82]]) +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IS_LAST]], [[META98:![0-9]+]], !DIExpression(), [[META82]]) +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: #dbg_declare(ptr [[B4]], [[META99:![0-9]+]], !DIExpression(), [[META82]]) +// CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[B4]], ptr align 4 [[TMP4]], i64 400, i1 false), !dbg [[DBG92]] +// CHECK1-NEXT: #dbg_declare(ptr [[I]], [[META100:![0-9]+]], !DIExpression(), [[META82]]) +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG92]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[TMP8]], align 4, !dbg [[DBG92]] +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3:[0-9]+]], i32 [[TMP9]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG101:![0-9]+]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG92]] // CHECK1: omp.dispatch.cond: -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP10]], 9, !dbg [[DBG80]] -// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG80]] +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP10]], 9, !dbg [[DBG95]] +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG95]] // CHECK1: cond.true: -// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG80]] +// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG95]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG80]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG95]] // CHECK1: cond.end: -// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP11]], [[COND_FALSE]] ], !dbg [[DBG80]] -// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: store i32 [[TMP12]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]], !dbg [[DBG77]] -// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG77]] +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP11]], [[COND_FALSE]] ], !dbg [[DBG95]] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: store i32 [[TMP12]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]], !dbg [[DBG92]] +// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG92]] // CHECK1: omp.dispatch.body: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG77]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG92]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP15]], [[TMP16]], !dbg [[DBG77]] -// CHECK1-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG77]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP15]], [[TMP16]], !dbg [[DBG92]] +// CHECK1-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG92]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP17]], 1, !dbg [[DBG87:![0-9]+]] -// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG87]] -// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !dbg [[DBG87]] -// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META88:![0-9]+]], !DIExpression(), [[META91:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG92:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG92]] -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX7]], i64 0, i64 1, !dbg [[DBG92]] -// CHECK1-NEXT: store ptr [[ARRAYIDX8]], ptr [[F]], align 8, !dbg [[META91]] -// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META93:![0-9]+]], !DIExpression(), [[META94:![0-9]+]]) -// CHECK1-NEXT: store ptr [[A_ADDR]], ptr [[G]], align 8, !dbg [[META94]] -// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META95:![0-9]+]], !DIExpression(), [[META96:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B4]], i64 0, i64 1, !dbg [[DBG97:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX9]], i64 0, i64 1, !dbg [[DBG97]] -// CHECK1-NEXT: store ptr [[ARRAYIDX10]], ptr [[H]], align 8, !dbg [[META96]] -// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META98:![0-9]+]], !DIExpression(), [[META99:![0-9]+]]) -// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META99]] -// CHECK1-NEXT: store i32 5, ptr [[A_ADDR]], align 4, !dbg [[DBG100:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B4]], i64 0, i64 0, !dbg [[DBG101:![0-9]+]] -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG102:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP18]] to i64, !dbg [[DBG101]] -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX11]], i64 0, i64 [[IDXPROM]], !dbg [[DBG101]] -// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX12]], align 4, !dbg [[DBG103:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG104:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX13]], i64 0, i64 0, !dbg [[DBG104]] -// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG105:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP19]] to i64, !dbg [[DBG104]] -// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX14]], i64 0, i64 [[IDXPROM15]], !dbg [[DBG104]] -// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX16]], align 4, !dbg [[DBG106:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG107:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX17]], i64 0, i64 0, !dbg [[DBG107]] -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG108:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP20]] to i64, !dbg [[DBG107]] -// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG107]] -// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[ARRAYIDX20]], align 4, !dbg [[DBG107]] -// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B4]], i64 0, i64 0, !dbg [[DBG109:![0-9]+]] -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG110:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP22]] to i64, !dbg [[DBG109]] -// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG109]] -// CHECK1-NEXT: store i32 [[TMP21]], ptr [[ARRAYIDX23]], align 4, !dbg [[DBG111:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B4]], i64 0, i64 0, !dbg [[DBG112:![0-9]+]] -// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG113:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM25:%.*]] = sext i32 [[TMP23]] to i64, !dbg [[DBG112]] -// CHECK1-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX24]], i64 0, i64 [[IDXPROM25]], !dbg [[DBG112]] -// CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[ARRAYIDX26]], align 4, !dbg [[DBG112]] -// CHECK1-NEXT: [[TMP25:%.*]] = load i8, ptr [[TMP7]], align 1, !dbg [[DBG114:![0-9]+]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP25]] to i1, !dbg [[DBG114]] -// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG114]] -// CHECK1-NEXT: [[OR:%.*]] = or i32 [[CONV]], [[TMP24]], !dbg [[DBG114]] -// CHECK1-NEXT: [[TOBOOL27:%.*]] = icmp ne i32 [[OR]], 0, !dbg [[DBG114]] -// CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TOBOOL27]] to i8, !dbg [[DBG114]] -// CHECK1-NEXT: store i8 [[FROMBOOL]], ptr [[TMP7]], align 1, !dbg [[DBG114]] -// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG115:![0-9]+]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP17]], 1, !dbg [[DBG102:![0-9]+]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG102]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !dbg [[DBG102]] +// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META103:![0-9]+]], !DIExpression(), [[META106:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG107:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG107]] +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX7]], i64 0, i64 1, !dbg [[DBG107]] +// CHECK1-NEXT: store ptr [[ARRAYIDX8]], ptr [[F]], align 8, !dbg [[META106]] +// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META108:![0-9]+]], !DIExpression(), [[META109:![0-9]+]]) +// CHECK1-NEXT: store ptr [[A_ADDR]], ptr [[G]], align 8, !dbg [[META109]] +// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META110:![0-9]+]], !DIExpression(), [[META111:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B4]], i64 0, i64 1, !dbg [[DBG112:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX9]], i64 0, i64 1, !dbg [[DBG112]] +// CHECK1-NEXT: store ptr [[ARRAYIDX10]], ptr [[H]], align 8, !dbg [[META111]] +// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META113:![0-9]+]], !DIExpression(), [[META114:![0-9]+]]) +// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META114]] +// CHECK1-NEXT: store i32 5, ptr [[A_ADDR]], align 4, !dbg [[DBG115:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B4]], i64 0, i64 0, !dbg [[DBG116:![0-9]+]] +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG117:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP18]] to i64, !dbg [[DBG116]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX11]], i64 0, i64 [[IDXPROM]], !dbg [[DBG116]] +// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX12]], align 4, !dbg [[DBG118:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG119:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX13]], i64 0, i64 0, !dbg [[DBG119]] +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG120:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP19]] to i64, !dbg [[DBG119]] +// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX14]], i64 0, i64 [[IDXPROM15]], !dbg [[DBG119]] +// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX16]], align 4, !dbg [[DBG121:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG122:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX17]], i64 0, i64 0, !dbg [[DBG122]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG123:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP20]] to i64, !dbg [[DBG122]] +// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG122]] +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[ARRAYIDX20]], align 4, !dbg [[DBG122]] +// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B4]], i64 0, i64 0, !dbg [[DBG124:![0-9]+]] +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG125:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP22]] to i64, !dbg [[DBG124]] +// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG124]] +// CHECK1-NEXT: store i32 [[TMP21]], ptr [[ARRAYIDX23]], align 4, !dbg [[DBG126:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[B4]], i64 0, i64 0, !dbg [[DBG127:![0-9]+]] +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG128:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM25:%.*]] = sext i32 [[TMP23]] to i64, !dbg [[DBG127]] +// CHECK1-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX24]], i64 0, i64 [[IDXPROM25]], !dbg [[DBG127]] +// CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[ARRAYIDX26]], align 4, !dbg [[DBG127]] +// CHECK1-NEXT: [[TMP25:%.*]] = load i8, ptr [[TMP7]], align 1, !dbg [[DBG129:![0-9]+]] +// CHECK1-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP25]] to i1, !dbg [[DBG129]] +// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[LOADEDV]] to i32, !dbg [[DBG129]] +// CHECK1-NEXT: [[OR:%.*]] = or i32 [[CONV]], [[TMP24]], !dbg [[DBG129]] +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[OR]], 0, !dbg [[DBG129]] +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8, !dbg [[DBG129]] +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[TMP7]], align 1, !dbg [[DBG129]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG130:![0-9]+]] // CHECK1: omp.body.continue: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG86]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG101]] // CHECK1: omp.inner.for.inc: -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP26]], 1, !dbg [[DBG77]] -// CHECK1-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG77]] -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG86]], !llvm.loop [[LOOP116:![0-9]+]] +// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP26]], 1, !dbg [[DBG92]] +// CHECK1-NEXT: store i32 [[ADD27]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG92]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG101]], !llvm.loop [[LOOP131:![0-9]+]] // CHECK1: omp.inner.for.end: -// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG86]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG101]] // CHECK1: omp.dispatch.inc: -// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP27]], [[TMP28]], !dbg [[DBG77]] -// CHECK1-NEXT: store i32 [[ADD29]], ptr [[DOTOMP_LB]], align 4, !dbg [[DBG77]] -// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG80]] -// CHECK1-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP29]], [[TMP30]], !dbg [[DBG77]] -// CHECK1-NEXT: store i32 [[ADD30]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG77]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG86]], !llvm.loop [[LOOP118:![0-9]+]] +// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP27]], [[TMP28]], !dbg [[DBG92]] +// CHECK1-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_LB]], align 4, !dbg [[DBG92]] +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG95]] +// CHECK1-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP29]], [[TMP30]], !dbg [[DBG92]] +// CHECK1-NEXT: store i32 [[ADD29]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG92]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG101]], !llvm.loop [[LOOP133:![0-9]+]] // CHECK1: omp.dispatch.end: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB5:[0-9]+]], i32 [[TMP9]]), !dbg [[DBG117:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG119:![0-9]+]] +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB5:[0-9]+]], i32 [[TMP9]]), !dbg [[DBG132:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG134:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug___omp_outlined -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG120:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG135:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -295,66 +332,29 @@ int main() { // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META127:![0-9]+]], !DIExpression(), [[META128:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META138:![0-9]+]], !DIExpression(), [[META139:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META129:![0-9]+]], !DIExpression(), [[META128]]) -// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META130:![0-9]+]], !DIExpression(), [[META128]]) -// CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META131:![0-9]+]], !DIExpression(), [[META128]]) -// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META132:![0-9]+]], !DIExpression(), [[META128]]) -// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META133:![0-9]+]], !DIExpression(), [[META128]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG134:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG134]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG134]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug___omp_outlined_debug__(ptr [[TMP3]], ptr [[TMP4]], ptr addrspace(1) [[TMP9]], i32 [[TMP6]], ptr [[TMP7]], ptr addrspace(1) [[TMP10]]) #[[ATTR3:[0-9]+]], !dbg [[DBG134]] -// CHECK1-NEXT: ret void, !dbg [[DBG134]] -// -// -// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13 -// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR5:[0-9]+]] !dbg [[DBG135:![0-9]+]] { -// CHECK1-NEXT: entry: -// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 -// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 -// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META138:![0-9]+]], !DIExpression(), [[META139:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META140:![0-9]+]], !DIExpression(), [[META139]]) // CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META140:![0-9]+]], !DIExpression(), [[META139]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META141:![0-9]+]], !DIExpression(), [[META139]]) // CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META141:![0-9]+]], !DIExpression(), [[META139]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META142:![0-9]+]], !DIExpression(), [[META139]]) // CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META142:![0-9]+]], !DIExpression(), [[META139]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META143:![0-9]+]], !DIExpression(), [[META139]]) // CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META143:![0-9]+]], !DIExpression(), [[META139]]) -// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTCAPTURE_EXPR__ADDR]], [[META144:![0-9]+]], !DIExpression(), [[META139]]) +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META144:![0-9]+]], !DIExpression(), [[META139]]) // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG145:![0-9]+]] // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG145]] // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG145]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG145]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG145]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG145]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG145]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG145]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !dbg [[DBG145]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP8]] to i1, !dbg [[DBG145]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(1), !dbg [[DBG145]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG145]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug__(ptr [[TMP3]], ptr addrspace(1) [[TMP9]], i32 [[TMP5]], ptr [[TMP6]], ptr addrspace(1) [[TMP10]], i1 [[TOBOOL]]) #[[ATTR3]], !dbg [[DBG145]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG145]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG145]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG145]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG145]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG145]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG145]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG145]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG145]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug___omp_outlined_debug__(ptr [[TMP3]], ptr [[TMP4]], ptr addrspace(1) [[TMP9]], i32 [[TMP6]], ptr [[TMP7]], ptr addrspace(1) [[TMP10]]) #[[ATTR3]], !dbg [[DBG145]] // CHECK1-NEXT: ret void, !dbg [[DBG145]] // // @@ -417,8 +417,41 @@ int main() { // CHECK1-NEXT: ret void, !dbg [[DBG161]] // // +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG167:![0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META170:![0-9]+]], !DIExpression(), [[META171:![0-9]+]]) +// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META172:![0-9]+]], !DIExpression(), [[META171]]) +// CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META173:![0-9]+]], !DIExpression(), [[META171]]) +// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META174:![0-9]+]], !DIExpression(), [[META171]]) +// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META175:![0-9]+]], !DIExpression(), [[META171]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG176:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(1), !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP6]] to ptr addrspace(1), !dbg [[DBG176]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG176]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27_debug__(ptr [[TMP3]], ptr addrspace(1) [[TMP8]], i32 [[TMP5]], ptr addrspace(1) [[TMP9]], ptr addrspace(1) [[TMP10]]) #[[ATTR3]], !dbg [[DBG176]] +// CHECK1-NEXT: ret void, !dbg [[DBG176]] +// +// // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27_debug___omp_outlined_debug__ -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], i32 noundef [[A:%.*]], ptr addrspace(1) noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG167:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], i32 noundef [[A:%.*]], ptr addrspace(1) noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG177:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -441,140 +474,140 @@ int main() { // CHECK1-NEXT: [[H:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[D:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META170:![0-9]+]], !DIExpression(), [[META171:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META180:![0-9]+]], !DIExpression(), [[META181:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META172:![0-9]+]], !DIExpression(), [[META171]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META182:![0-9]+]], !DIExpression(), [[META181]]) // CHECK1-NEXT: store ptr addrspace(1) [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META173:![0-9]+]], !DIExpression(), [[META174:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META183:![0-9]+]], !DIExpression(), [[META184:![0-9]+]]) // CHECK1-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META175:![0-9]+]], !DIExpression(), [[META176:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META185:![0-9]+]], !DIExpression(), [[META186:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META177:![0-9]+]], !DIExpression(), [[META178:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META187:![0-9]+]], !DIExpression(), [[META188:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META179:![0-9]+]], !DIExpression(), [[META180:![0-9]+]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG181:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG181]] -// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr addrspace(1), ptr [[B_ADDR]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[TMP3]] to ptr, !dbg [[DBG181]] -// CHECK1-NEXT: store ptr [[TMP4]], ptr [[_TMP1]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast ptr addrspace(1) [[TMP6]] to ptr, !dbg [[DBG181]] -// CHECK1-NEXT: store ptr [[TMP7]], ptr [[_TMP2]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IV]], [[META182:![0-9]+]], !DIExpression(), [[META171]]) -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_LB]], [[META183:![0-9]+]], !DIExpression(), [[META171]]) -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG184:![0-9]+]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_UB]], [[META185:![0-9]+]], !DIExpression(), [[META171]]) -// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_STRIDE]], [[META186:![0-9]+]], !DIExpression(), [[META171]]) -// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IS_LAST]], [[META187:![0-9]+]], !DIExpression(), [[META171]]) -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: #dbg_declare(ptr [[I]], [[META188:![0-9]+]], !DIExpression(), [[META171]]) -// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 4, !dbg [[DBG181]] -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB10:[0-9]+]], i32 [[TMP10]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG189:![0-9]+]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG181]] +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META189:![0-9]+]], !DIExpression(), [[META190:![0-9]+]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG191:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG191]] +// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr addrspace(1), ptr [[B_ADDR]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[TMP3]] to ptr, !dbg [[DBG191]] +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[_TMP1]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast ptr addrspace(1) [[TMP6]] to ptr, !dbg [[DBG191]] +// CHECK1-NEXT: store ptr [[TMP7]], ptr [[_TMP2]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IV]], [[META192:![0-9]+]], !DIExpression(), [[META181]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_LB]], [[META193:![0-9]+]], !DIExpression(), [[META181]]) +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG194:![0-9]+]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_UB]], [[META195:![0-9]+]], !DIExpression(), [[META181]]) +// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_STRIDE]], [[META196:![0-9]+]], !DIExpression(), [[META181]]) +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IS_LAST]], [[META197:![0-9]+]], !DIExpression(), [[META181]]) +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: #dbg_declare(ptr [[I]], [[META198:![0-9]+]], !DIExpression(), [[META181]]) +// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 4, !dbg [[DBG191]] +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB10:[0-9]+]], i32 [[TMP10]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG199:![0-9]+]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG191]] // CHECK1: omp.dispatch.cond: -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP11]], 9, !dbg [[DBG184]] -// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG184]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP11]], 9, !dbg [[DBG194]] +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG194]] // CHECK1: cond.true: -// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG184]] +// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG194]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG184]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG194]] // CHECK1: cond.end: -// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ], !dbg [[DBG184]] -// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[CMP4:%.*]] = icmp sle i32 [[TMP14]], [[TMP15]], !dbg [[DBG181]] -// CHECK1-NEXT: br i1 [[CMP4]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG181]] +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ], !dbg [[DBG194]] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[CMP4:%.*]] = icmp sle i32 [[TMP14]], [[TMP15]], !dbg [[DBG191]] +// CHECK1-NEXT: br i1 [[CMP4]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG191]] // CHECK1: omp.dispatch.body: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG181]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG191]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP16]], [[TMP17]], !dbg [[DBG181]] -// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG181]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP16]], [[TMP17]], !dbg [[DBG191]] +// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG191]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP18]], 1, !dbg [[DBG190:![0-9]+]] -// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG190]] -// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !dbg [[DBG190]] -// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META191:![0-9]+]], !DIExpression(), [[META193:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG194:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG194]] -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX6]], i64 0, i64 1, !dbg [[DBG194]] -// CHECK1-NEXT: store ptr [[ARRAYIDX7]], ptr [[F]], align 8, !dbg [[META193]] -// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META195:![0-9]+]], !DIExpression(), [[META196:![0-9]+]]) -// CHECK1-NEXT: store ptr [[A_ADDR]], ptr [[G]], align 8, !dbg [[META196]] -// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META197:![0-9]+]], !DIExpression(), [[META198:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 1, !dbg [[DBG199:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX8]], i64 0, i64 1, !dbg [[DBG199]] -// CHECK1-NEXT: store ptr [[ARRAYIDX9]], ptr [[H]], align 8, !dbg [[META198]] -// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META200:![0-9]+]], !DIExpression(), [[META201:![0-9]+]]) -// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META201]] -// CHECK1-NEXT: store i32 5, ptr [[A_ADDR]], align 4, !dbg [[DBG202:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 0, !dbg [[DBG203:![0-9]+]] -// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG204:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP19]] to i64, !dbg [[DBG203]] -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX10]], i64 0, i64 [[IDXPROM]], !dbg [[DBG203]] -// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX11]], align 4, !dbg [[DBG205:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG206:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX12]], i64 0, i64 0, !dbg [[DBG206]] -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG207:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM14:%.*]] = sext i32 [[TMP20]] to i64, !dbg [[DBG206]] -// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX13]], i64 0, i64 [[IDXPROM14]], !dbg [[DBG206]] -// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX15]], align 4, !dbg [[DBG208:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG209:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX16]], i64 0, i64 0, !dbg [[DBG209]] -// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG210:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM18:%.*]] = sext i32 [[TMP21]] to i64, !dbg [[DBG209]] -// CHECK1-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX17]], i64 0, i64 [[IDXPROM18]], !dbg [[DBG209]] -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[ARRAYIDX19]], align 4, !dbg [[DBG209]] -// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 0, !dbg [[DBG211:![0-9]+]] -// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG212:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM21:%.*]] = sext i32 [[TMP23]] to i64, !dbg [[DBG211]] -// CHECK1-NEXT: [[ARRAYIDX22:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX20]], i64 0, i64 [[IDXPROM21]], !dbg [[DBG211]] -// CHECK1-NEXT: store i32 [[TMP22]], ptr [[ARRAYIDX22]], align 4, !dbg [[DBG213:![0-9]+]] -// CHECK1-NEXT: [[TMP24:%.*]] = load i8, ptr [[TMP8]], align 1, !dbg [[DBG214:![0-9]+]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP24]] to i1, !dbg [[DBG214]] -// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG214]] -// CHECK1-NEXT: store i32 [[CONV]], ptr [[D]], align 4, !dbg [[DBG215:![0-9]+]] -// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG216:![0-9]+]] +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP18]], 1, !dbg [[DBG200:![0-9]+]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG200]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !dbg [[DBG200]] +// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META201:![0-9]+]], !DIExpression(), [[META203:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG204:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG204]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX6]], i64 0, i64 1, !dbg [[DBG204]] +// CHECK1-NEXT: store ptr [[ARRAYIDX7]], ptr [[F]], align 8, !dbg [[META203]] +// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META205:![0-9]+]], !DIExpression(), [[META206:![0-9]+]]) +// CHECK1-NEXT: store ptr [[A_ADDR]], ptr [[G]], align 8, !dbg [[META206]] +// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META207:![0-9]+]], !DIExpression(), [[META208:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 1, !dbg [[DBG209:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX8]], i64 0, i64 1, !dbg [[DBG209]] +// CHECK1-NEXT: store ptr [[ARRAYIDX9]], ptr [[H]], align 8, !dbg [[META208]] +// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META210:![0-9]+]], !DIExpression(), [[META211:![0-9]+]]) +// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META211]] +// CHECK1-NEXT: store i32 5, ptr [[A_ADDR]], align 4, !dbg [[DBG212:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 0, !dbg [[DBG213:![0-9]+]] +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG214:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP19]] to i64, !dbg [[DBG213]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX10]], i64 0, i64 [[IDXPROM]], !dbg [[DBG213]] +// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX11]], align 4, !dbg [[DBG215:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG216:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX12]], i64 0, i64 0, !dbg [[DBG216]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG217:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM14:%.*]] = sext i32 [[TMP20]] to i64, !dbg [[DBG216]] +// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX13]], i64 0, i64 [[IDXPROM14]], !dbg [[DBG216]] +// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX15]], align 4, !dbg [[DBG218:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG219:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX16]], i64 0, i64 0, !dbg [[DBG219]] +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG220:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM18:%.*]] = sext i32 [[TMP21]] to i64, !dbg [[DBG219]] +// CHECK1-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX17]], i64 0, i64 [[IDXPROM18]], !dbg [[DBG219]] +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[ARRAYIDX19]], align 4, !dbg [[DBG219]] +// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP5]], i64 0, i64 0, !dbg [[DBG221:![0-9]+]] +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG222:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM21:%.*]] = sext i32 [[TMP23]] to i64, !dbg [[DBG221]] +// CHECK1-NEXT: [[ARRAYIDX22:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX20]], i64 0, i64 [[IDXPROM21]], !dbg [[DBG221]] +// CHECK1-NEXT: store i32 [[TMP22]], ptr [[ARRAYIDX22]], align 4, !dbg [[DBG223:![0-9]+]] +// CHECK1-NEXT: [[TMP24:%.*]] = load i8, ptr [[TMP8]], align 1, !dbg [[DBG224:![0-9]+]] +// CHECK1-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP24]] to i1, !dbg [[DBG224]] +// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[LOADEDV]] to i32, !dbg [[DBG224]] +// CHECK1-NEXT: store i32 [[CONV]], ptr [[D]], align 4, !dbg [[DBG225:![0-9]+]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG226:![0-9]+]] // CHECK1: omp.body.continue: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG189]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG199]] // CHECK1: omp.inner.for.inc: -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[ADD23:%.*]] = add nsw i32 [[TMP25]], 1, !dbg [[DBG181]] -// CHECK1-NEXT: store i32 [[ADD23]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG181]] -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG189]], !llvm.loop [[LOOP217:![0-9]+]] +// CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[ADD23:%.*]] = add nsw i32 [[TMP25]], 1, !dbg [[DBG191]] +// CHECK1-NEXT: store i32 [[ADD23]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG191]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG199]], !llvm.loop [[LOOP227:![0-9]+]] // CHECK1: omp.inner.for.end: -// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG189]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG199]] // CHECK1: omp.dispatch.inc: -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[ADD24:%.*]] = add nsw i32 [[TMP26]], [[TMP27]], !dbg [[DBG181]] -// CHECK1-NEXT: store i32 [[ADD24]], ptr [[DOTOMP_LB]], align 4, !dbg [[DBG181]] -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG184]] -// CHECK1-NEXT: [[ADD25:%.*]] = add nsw i32 [[TMP28]], [[TMP29]], !dbg [[DBG181]] -// CHECK1-NEXT: store i32 [[ADD25]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG181]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG189]], !llvm.loop [[LOOP219:![0-9]+]] +// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[ADD24:%.*]] = add nsw i32 [[TMP26]], [[TMP27]], !dbg [[DBG191]] +// CHECK1-NEXT: store i32 [[ADD24]], ptr [[DOTOMP_LB]], align 4, !dbg [[DBG191]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG194]] +// CHECK1-NEXT: [[ADD25:%.*]] = add nsw i32 [[TMP28]], [[TMP29]], !dbg [[DBG191]] +// CHECK1-NEXT: store i32 [[ADD25]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG191]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG199]], !llvm.loop [[LOOP229:![0-9]+]] // CHECK1: omp.dispatch.end: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB12:[0-9]+]], i32 [[TMP10]]), !dbg [[DBG218:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG220:![0-9]+]] +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB12:[0-9]+]], i32 [[TMP10]]), !dbg [[DBG228:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG230:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27_debug___omp_outlined -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG221:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG231:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -583,63 +616,30 @@ int main() { // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META222:![0-9]+]], !DIExpression(), [[META223:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META232:![0-9]+]], !DIExpression(), [[META233:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META224:![0-9]+]], !DIExpression(), [[META223]]) -// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META225:![0-9]+]], !DIExpression(), [[META223]]) -// CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META226:![0-9]+]], !DIExpression(), [[META223]]) -// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META227:![0-9]+]], !DIExpression(), [[META223]]) -// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META228:![0-9]+]], !DIExpression(), [[META223]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG229:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG229]] -// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG229]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27_debug___omp_outlined_debug__(ptr [[TMP3]], ptr [[TMP4]], ptr addrspace(1) [[TMP9]], i32 [[TMP6]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]]) #[[ATTR3]], !dbg [[DBG229]] -// CHECK1-NEXT: ret void, !dbg [[DBG229]] -// -// -// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27 -// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR5]] !dbg [[DBG230:![0-9]+]] { -// CHECK1-NEXT: entry: -// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 -// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META233:![0-9]+]], !DIExpression(), [[META234:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META234:![0-9]+]], !DIExpression(), [[META233]]) // CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META235:![0-9]+]], !DIExpression(), [[META234]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META235:![0-9]+]], !DIExpression(), [[META233]]) // CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META236:![0-9]+]], !DIExpression(), [[META234]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META236:![0-9]+]], !DIExpression(), [[META233]]) // CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META237:![0-9]+]], !DIExpression(), [[META234]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META237:![0-9]+]], !DIExpression(), [[META233]]) // CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META238:![0-9]+]], !DIExpression(), [[META234]]) +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META238:![0-9]+]], !DIExpression(), [[META233]]) // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG239:![0-9]+]] // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG239]] // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG239]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG239]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG239]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG239]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG239]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG239]] -// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(1), !dbg [[DBG239]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP6]] to ptr addrspace(1), !dbg [[DBG239]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG239]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG239]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG239]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG239]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG239]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG239]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG239]] // CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG239]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27_debug__(ptr [[TMP3]], ptr addrspace(1) [[TMP8]], i32 [[TMP5]], ptr addrspace(1) [[TMP9]], ptr addrspace(1) [[TMP10]]) #[[ATTR3]], !dbg [[DBG239]] +// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG239]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27_debug___omp_outlined_debug__(ptr [[TMP3]], ptr [[TMP4]], ptr addrspace(1) [[TMP9]], i32 [[TMP6]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]]) #[[ATTR3]], !dbg [[DBG239]] // CHECK1-NEXT: ret void, !dbg [[DBG239]] // // @@ -702,8 +702,43 @@ int main() { // CHECK1-NEXT: ret void, !dbg [[DBG255]] // // +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG261:![0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META264:![0-9]+]], !DIExpression(), [[META265:![0-9]+]]) +// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META266:![0-9]+]], !DIExpression(), [[META265]]) +// CHECK1-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META267:![0-9]+]], !DIExpression(), [[META265]]) +// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META268:![0-9]+]], !DIExpression(), [[META265]]) +// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META269:![0-9]+]], !DIExpression(), [[META265]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG270:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP6]] to ptr addrspace(1), !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG270]] +// CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG270]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41_debug__(ptr [[TMP4]], ptr addrspace(1) [[TMP9]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]], ptr addrspace(1) [[TMP12]]) #[[ATTR3]], !dbg [[DBG270]] +// CHECK1-NEXT: ret void, !dbg [[DBG270]] +// +// // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41_debug___omp_outlined_debug__ -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], ptr addrspace(1) noalias noundef [[A:%.*]], ptr addrspace(1) noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG261:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr addrspace(1) noalias noundef [[C:%.*]], ptr addrspace(1) noalias noundef [[A:%.*]], ptr addrspace(1) noalias noundef [[B:%.*]], ptr addrspace(1) noalias noundef [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG271:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -727,148 +762,148 @@ int main() { // CHECK1-NEXT: [[H:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[D:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META264:![0-9]+]], !DIExpression(), [[META265:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META274:![0-9]+]], !DIExpression(), [[META275:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META266:![0-9]+]], !DIExpression(), [[META265]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META276:![0-9]+]], !DIExpression(), [[META275]]) // CHECK1-NEXT: store ptr addrspace(1) [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META267:![0-9]+]], !DIExpression(), [[META268:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META277:![0-9]+]], !DIExpression(), [[META278:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META269:![0-9]+]], !DIExpression(), [[META270:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META279:![0-9]+]], !DIExpression(), [[META280:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META271:![0-9]+]], !DIExpression(), [[META272:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META281:![0-9]+]], !DIExpression(), [[META282:![0-9]+]]) // CHECK1-NEXT: store ptr addrspace(1) [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META273:![0-9]+]], !DIExpression(), [[META274:![0-9]+]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG275:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG275]] -// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr addrspace(1), ptr [[A_ADDR]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[TMP3]] to ptr, !dbg [[DBG275]] -// CHECK1-NEXT: store ptr [[TMP4]], ptr [[_TMP1]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr addrspace(1), ptr [[B_ADDR]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast ptr addrspace(1) [[TMP6]] to ptr, !dbg [[DBG275]] -// CHECK1-NEXT: store ptr [[TMP7]], ptr [[_TMP2]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP9:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr addrspace(1) [[TMP9]] to ptr, !dbg [[DBG275]] -// CHECK1-NEXT: store ptr [[TMP10]], ptr [[_TMP3]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[_TMP3]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IV]], [[META276:![0-9]+]], !DIExpression(), [[META265]]) -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_LB]], [[META277:![0-9]+]], !DIExpression(), [[META265]]) -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG278:![0-9]+]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_UB]], [[META279:![0-9]+]], !DIExpression(), [[META265]]) -// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_STRIDE]], [[META280:![0-9]+]], !DIExpression(), [[META265]]) -// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IS_LAST]], [[META281:![0-9]+]], !DIExpression(), [[META265]]) -// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: #dbg_declare(ptr [[I]], [[META282:![0-9]+]], !DIExpression(), [[META265]]) -// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4, !dbg [[DBG275]] -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB17:[0-9]+]], i32 [[TMP13]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG283:![0-9]+]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG275]] +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META283:![0-9]+]], !DIExpression(), [[META284:![0-9]+]]) +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr [[C_ADDR]], align 8, !dbg [[DBG285:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[TMP0]] to ptr, !dbg [[DBG285]] +// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr addrspace(1), ptr [[A_ADDR]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[TMP3]] to ptr, !dbg [[DBG285]] +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[_TMP1]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[_TMP1]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr addrspace(1), ptr [[B_ADDR]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast ptr addrspace(1) [[TMP6]] to ptr, !dbg [[DBG285]] +// CHECK1-NEXT: store ptr [[TMP7]], ptr [[_TMP2]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[_TMP2]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP9:%.*]] = load ptr addrspace(1), ptr [[BB_ADDR]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr addrspace(1) [[TMP9]] to ptr, !dbg [[DBG285]] +// CHECK1-NEXT: store ptr [[TMP10]], ptr [[_TMP3]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[_TMP3]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IV]], [[META286:![0-9]+]], !DIExpression(), [[META275]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_LB]], [[META287:![0-9]+]], !DIExpression(), [[META275]]) +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG288:![0-9]+]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_UB]], [[META289:![0-9]+]], !DIExpression(), [[META275]]) +// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_STRIDE]], [[META290:![0-9]+]], !DIExpression(), [[META275]]) +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: #dbg_declare(ptr [[DOTOMP_IS_LAST]], [[META291:![0-9]+]], !DIExpression(), [[META275]]) +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: #dbg_declare(ptr [[I]], [[META292:![0-9]+]], !DIExpression(), [[META275]]) +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4, !dbg [[DBG285]] +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB17:[0-9]+]], i32 [[TMP13]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG293:![0-9]+]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG285]] // CHECK1: omp.dispatch.cond: -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP14]], 9, !dbg [[DBG278]] -// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG278]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP14]], 9, !dbg [[DBG288]] +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG288]] // CHECK1: cond.true: -// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG278]] +// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG288]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG278]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG288]] // CHECK1: cond.end: -// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP15]], [[COND_FALSE]] ], !dbg [[DBG278]] -// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]], !dbg [[DBG275]] -// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG275]] +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP15]], [[COND_FALSE]] ], !dbg [[DBG288]] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]], !dbg [[DBG285]] +// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG285]] // CHECK1: omp.dispatch.body: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG275]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG285]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP19]], [[TMP20]], !dbg [[DBG275]] -// CHECK1-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG275]] +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP19]], [[TMP20]], !dbg [[DBG285]] +// CHECK1-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG285]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP21]], 1, !dbg [[DBG284:![0-9]+]] -// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG284]] -// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !dbg [[DBG284]] -// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META285:![0-9]+]], !DIExpression(), [[META287:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG288:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG288]] -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX7]], i64 0, i64 1, !dbg [[DBG288]] -// CHECK1-NEXT: store ptr [[ARRAYIDX8]], ptr [[F]], align 8, !dbg [[META287]] -// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META289:![0-9]+]], !DIExpression(), [[META290:![0-9]+]]) -// CHECK1-NEXT: store ptr [[TMP5]], ptr [[G]], align 8, !dbg [[META290]] -// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META291:![0-9]+]], !DIExpression(), [[META292:![0-9]+]]) -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 1, !dbg [[DBG293:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX9]], i64 0, i64 1, !dbg [[DBG293]] -// CHECK1-NEXT: store ptr [[ARRAYIDX10]], ptr [[H]], align 8, !dbg [[META292]] -// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META294:![0-9]+]], !DIExpression(), [[META295:![0-9]+]]) -// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META295]] -// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4, !dbg [[DBG296:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG297:![0-9]+]] -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG298:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP22]] to i64, !dbg [[DBG297]] -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX11]], i64 0, i64 [[IDXPROM]], !dbg [[DBG297]] -// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX12]], align 4, !dbg [[DBG299:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG300:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX13]], i64 0, i64 0, !dbg [[DBG300]] -// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG301:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP23]] to i64, !dbg [[DBG300]] -// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX14]], i64 0, i64 [[IDXPROM15]], !dbg [[DBG300]] -// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX16]], align 4, !dbg [[DBG302:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG303:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX17]], i64 0, i64 0, !dbg [[DBG303]] -// CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG304:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP24]] to i64, !dbg [[DBG303]] -// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG303]] -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[ARRAYIDX20]], align 4, !dbg [[DBG303]] -// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG305:![0-9]+]] -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG306:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP26]] to i64, !dbg [[DBG305]] -// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG305]] -// CHECK1-NEXT: store i32 [[TMP25]], ptr [[ARRAYIDX23]], align 4, !dbg [[DBG307:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG308:![0-9]+]] -// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG309:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM25:%.*]] = sext i32 [[TMP27]] to i64, !dbg [[DBG308]] -// CHECK1-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX24]], i64 0, i64 [[IDXPROM25]], !dbg [[DBG308]] -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[ARRAYIDX26]], align 4, !dbg [[DBG308]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP28]], 0, !dbg [[DBG308]] -// CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TOBOOL]] to i8, !dbg [[DBG310:![0-9]+]] -// CHECK1-NEXT: store i8 [[FROMBOOL]], ptr [[TMP11]], align 1, !dbg [[DBG310]] -// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG311:![0-9]+]] +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP21]], 1, !dbg [[DBG294:![0-9]+]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG294]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !dbg [[DBG294]] +// CHECK1-NEXT: #dbg_declare(ptr [[F]], [[META295:![0-9]+]], !DIExpression(), [[META297:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 1, !dbg [[DBG298:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG298]] +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX7]], i64 0, i64 1, !dbg [[DBG298]] +// CHECK1-NEXT: store ptr [[ARRAYIDX8]], ptr [[F]], align 8, !dbg [[META297]] +// CHECK1-NEXT: #dbg_declare(ptr [[G]], [[META299:![0-9]+]], !DIExpression(), [[META300:![0-9]+]]) +// CHECK1-NEXT: store ptr [[TMP5]], ptr [[G]], align 8, !dbg [[META300]] +// CHECK1-NEXT: #dbg_declare(ptr [[H]], [[META301:![0-9]+]], !DIExpression(), [[META302:![0-9]+]]) +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 1, !dbg [[DBG303:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX9]], i64 0, i64 1, !dbg [[DBG303]] +// CHECK1-NEXT: store ptr [[ARRAYIDX10]], ptr [[H]], align 8, !dbg [[META302]] +// CHECK1-NEXT: #dbg_declare(ptr [[D]], [[META304:![0-9]+]], !DIExpression(), [[META305:![0-9]+]]) +// CHECK1-NEXT: store i32 15, ptr [[D]], align 4, !dbg [[META305]] +// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4, !dbg [[DBG306:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG307:![0-9]+]] +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG308:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP22]] to i64, !dbg [[DBG307]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX11]], i64 0, i64 [[IDXPROM]], !dbg [[DBG307]] +// CHECK1-NEXT: store i32 10, ptr [[ARRAYIDX12]], align 4, !dbg [[DBG309:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG310:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX13]], i64 0, i64 0, !dbg [[DBG310]] +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG311:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP23]] to i64, !dbg [[DBG310]] +// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX14]], i64 0, i64 [[IDXPROM15]], !dbg [[DBG310]] +// CHECK1-NEXT: store i32 11, ptr [[ARRAYIDX16]], align 4, !dbg [[DBG312:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr [[TMP2]], i64 0, i64 0, !dbg [[DBG313:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[ARRAYIDX17]], i64 0, i64 0, !dbg [[DBG313]] +// CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG314:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP24]] to i64, !dbg [[DBG313]] +// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG313]] +// CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[ARRAYIDX20]], align 4, !dbg [[DBG313]] +// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG315:![0-9]+]] +// CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG316:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP26]] to i64, !dbg [[DBG315]] +// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG315]] +// CHECK1-NEXT: store i32 [[TMP25]], ptr [[ARRAYIDX23]], align 4, !dbg [[DBG317:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[TMP8]], i64 0, i64 0, !dbg [[DBG318:![0-9]+]] +// CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP5]], align 4, !dbg [[DBG319:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM25:%.*]] = sext i32 [[TMP27]] to i64, !dbg [[DBG318]] +// CHECK1-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARRAYIDX24]], i64 0, i64 [[IDXPROM25]], !dbg [[DBG318]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[ARRAYIDX26]], align 4, !dbg [[DBG318]] +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP28]], 0, !dbg [[DBG318]] +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8, !dbg [[DBG320:![0-9]+]] +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[TMP11]], align 1, !dbg [[DBG320]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG321:![0-9]+]] // CHECK1: omp.body.continue: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG283]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG293]] // CHECK1: omp.inner.for.inc: -// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP29]], 1, !dbg [[DBG275]] -// CHECK1-NEXT: store i32 [[ADD27]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG275]] -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG283]], !llvm.loop [[LOOP312:![0-9]+]] +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP29]], 1, !dbg [[DBG285]] +// CHECK1-NEXT: store i32 [[ADD27]], ptr [[DOTOMP_IV]], align 4, !dbg [[DBG285]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG293]], !llvm.loop [[LOOP322:![0-9]+]] // CHECK1: omp.inner.for.end: -// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG283]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG293]] // CHECK1: omp.dispatch.inc: -// CHECK1-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP30]], [[TMP31]], !dbg [[DBG275]] -// CHECK1-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_LB]], align 4, !dbg [[DBG275]] -// CHECK1-NEXT: [[TMP32:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP33:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG278]] -// CHECK1-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP32]], [[TMP33]], !dbg [[DBG275]] -// CHECK1-NEXT: store i32 [[ADD29]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG275]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG283]], !llvm.loop [[LOOP314:![0-9]+]] +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP30]], [[TMP31]], !dbg [[DBG285]] +// CHECK1-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_LB]], align 4, !dbg [[DBG285]] +// CHECK1-NEXT: [[TMP32:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[TMP33:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP32]], [[TMP33]], !dbg [[DBG285]] +// CHECK1-NEXT: store i32 [[ADD29]], ptr [[DOTOMP_UB]], align 4, !dbg [[DBG285]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG293]], !llvm.loop [[LOOP324:![0-9]+]] // CHECK1: omp.dispatch.end: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB19:[0-9]+]], i32 [[TMP13]]), !dbg [[DBG313:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG315:![0-9]+]] +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB19:[0-9]+]], i32 [[TMP13]]), !dbg [[DBG323:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG325:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41_debug___omp_outlined -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR1]] !dbg [[DBG316:![0-9]+]] { +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG326:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -877,66 +912,31 @@ int main() { // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META319:![0-9]+]], !DIExpression(), [[META320:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTGLOBAL_TID__ADDR]], [[META329:![0-9]+]], !DIExpression(), [[META330:![0-9]+]]) // CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META321:![0-9]+]], !DIExpression(), [[META320]]) -// CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META322:![0-9]+]], !DIExpression(), [[META320]]) -// CHECK1-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META323:![0-9]+]], !DIExpression(), [[META320]]) -// CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META324:![0-9]+]], !DIExpression(), [[META320]]) -// CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META325:![0-9]+]], !DIExpression(), [[META320]]) -// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG326:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP6]] to ptr addrspace(1), !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG326]] -// CHECK1-NEXT: [[TMP13:%.*]] = addrspacecast ptr [[TMP9]] to ptr addrspace(1), !dbg [[DBG326]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41_debug___omp_outlined_debug__(ptr [[TMP4]], ptr [[TMP5]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]], ptr addrspace(1) [[TMP12]], ptr addrspace(1) [[TMP13]]) #[[ATTR3]], !dbg [[DBG326]] -// CHECK1-NEXT: ret void, !dbg [[DBG326]] -// -// -// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41 -// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]], ptr noundef nonnull align 4 dereferenceable(4000) [[C:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(400) [[B:%.*]], ptr noundef nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR5]] !dbg [[DBG327:![0-9]+]] { -// CHECK1-NEXT: entry: -// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[DYN_PTR_ADDR]], [[META330:![0-9]+]], !DIExpression(), [[META331:![0-9]+]]) +// CHECK1-NEXT: #dbg_declare(ptr [[DOTBOUND_TID__ADDR]], [[META331:![0-9]+]], !DIExpression(), [[META330]]) // CHECK1-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META332:![0-9]+]], !DIExpression(), [[META331]]) +// CHECK1-NEXT: #dbg_declare(ptr [[C_ADDR]], [[META332:![0-9]+]], !DIExpression(), [[META330]]) // CHECK1-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META333:![0-9]+]], !DIExpression(), [[META331]]) +// CHECK1-NEXT: #dbg_declare(ptr [[A_ADDR]], [[META333:![0-9]+]], !DIExpression(), [[META330]]) // CHECK1-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META334:![0-9]+]], !DIExpression(), [[META331]]) +// CHECK1-NEXT: #dbg_declare(ptr [[B_ADDR]], [[META334:![0-9]+]], !DIExpression(), [[META330]]) // CHECK1-NEXT: store ptr [[BB]], ptr [[BB_ADDR]], align 8 -// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META335:![0-9]+]], !DIExpression(), [[META331]]) +// CHECK1-NEXT: #dbg_declare(ptr [[BB_ADDR]], [[META335:![0-9]+]], !DIExpression(), [[META330]]) // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG336:![0-9]+]] // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG336]] // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG336]] // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG336]] -// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DYN_PTR_ADDR]], align 8, !dbg [[DBG336]] -// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG336]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG336]] -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG336]] -// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG336]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast ptr [[TMP5]] to ptr addrspace(1), !dbg [[DBG336]] +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG336]] +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG336]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[C_ADDR]], align 8, !dbg [[DBG336]] +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG336]] +// CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !dbg [[DBG336]] +// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[BB_ADDR]], align 8, !dbg [[DBG336]] // CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast ptr [[TMP6]] to ptr addrspace(1), !dbg [[DBG336]] // CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast ptr [[TMP7]] to ptr addrspace(1), !dbg [[DBG336]] // CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast ptr [[TMP8]] to ptr addrspace(1), !dbg [[DBG336]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41_debug__(ptr [[TMP4]], ptr addrspace(1) [[TMP9]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]], ptr addrspace(1) [[TMP12]]) #[[ATTR3]], !dbg [[DBG336]] +// CHECK1-NEXT: [[TMP13:%.*]] = addrspacecast ptr [[TMP9]] to ptr addrspace(1), !dbg [[DBG336]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41_debug___omp_outlined_debug__(ptr [[TMP4]], ptr [[TMP5]], ptr addrspace(1) [[TMP10]], ptr addrspace(1) [[TMP11]], ptr addrspace(1) [[TMP12]], ptr addrspace(1) [[TMP13]]) #[[ATTR3]], !dbg [[DBG336]] // CHECK1-NEXT: ret void, !dbg [[DBG336]] // diff --git a/clang/test/OpenMP/target_simd_defaultmap_messages.cpp b/clang/test/OpenMP/target_simd_defaultmap_messages.cpp index 0fa86cc7279ad..2169681e05749 100644 --- a/clang/test/OpenMP/target_simd_defaultmap_messages.cpp +++ b/clang/test/OpenMP/target_simd_defaultmap_messages.cpp @@ -1,5 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -verify=expected,omp51 -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd %s -verify=expected,omp51 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -DOMP5 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -DOMP5 @@ -15,24 +18,24 @@ T tmain(T argc, S **argv) { int i; #pragma omp target simd defaultmap // expected-error {{expected '(' after 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target simd defaultmap( // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target simd defaultmap( // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target simd defaultmap() // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target simd defaultmap() // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target simd defaultmap(tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} +#pragma omp target simd defaultmap(tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target simd defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} +#pragma omp target simd defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp5x-error {{expected ')'}} omp5x-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target simd defaultmap (scalar: // expected-error {{expected ')'}} omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} + #pragma omp target simd defaultmap (scalar: // expected-error {{expected ')'}} omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} @@ -46,28 +49,28 @@ int main(int argc, char **argv) { #pragma omp target simd defaultmap // expected-error {{expected '(' after 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target simd defaultmap( // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target simd defaultmap( // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target simd defaultmap() // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target simd defaultmap() // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target simd defaultmap(tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} +#pragma omp target simd defaultmap(tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target simd defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} +#pragma omp target simd defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp5x-error {{expected ')'}} omp5x-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target simd defaultmap(scalar: // expected-error {{expected ')'}} omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} +#pragma omp target simd defaultmap(scalar: // expected-error {{expected ')'}} omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} diff --git a/clang/test/OpenMP/target_teams_defaultmap_messages.cpp b/clang/test/OpenMP/target_teams_defaultmap_messages.cpp index 206a1e4f18af2..97ed5315c4c8e 100644 --- a/clang/test/OpenMP/target_teams_defaultmap_messages.cpp +++ b/clang/test/OpenMP/target_teams_defaultmap_messages.cpp @@ -1,5 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -verify=expected,omp51 -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd %s -verify=expected,omp51 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -DOMP5 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -DOMP5 @@ -14,21 +17,21 @@ template T tmain(T argc, S **argv) { #pragma omp target teams defaultmap // expected-error {{expected '(' after 'defaultmap'}} foo(); -#pragma omp target teams defaultmap( // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams defaultmap( // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); -#pragma omp target teams defaultmap() // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams defaultmap() // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target teams defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); - #pragma omp target teams defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + #pragma omp target teams defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target teams defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); -#pragma omp target teams defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} +#pragma omp target teams defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp5x-error {{expected ')'}} omp5x-note {{to match this '('}} foo(); #pragma omp target teams defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); - #pragma omp target teams defaultmap (scalar: // expected-error {{expected ')'}} omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} + #pragma omp target teams defaultmap (scalar: // expected-error {{expected ')'}} omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target teams defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); @@ -39,21 +42,21 @@ T tmain(T argc, S **argv) { int main(int argc, char **argv) { #pragma omp target teams defaultmap // expected-error {{expected '(' after 'defaultmap'}} foo(); -#pragma omp target teams defaultmap( // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams defaultmap( // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); -#pragma omp target teams defaultmap() // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams defaultmap() // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target teams defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); - #pragma omp target teams defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + #pragma omp target teams defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target teams defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); -#pragma omp target teams defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} +#pragma omp target teams defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp5x-error {{expected ')'}} omp5x-note {{to match this '('}} foo(); #pragma omp target teams defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); - #pragma omp target teams defaultmap (scalar: // expected-error {{expected ')'}} omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} + #pragma omp target teams defaultmap (scalar: // expected-error {{expected ')'}} omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} foo(); #pragma omp target teams defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} foo(); diff --git a/clang/test/OpenMP/target_teams_distribute_defaultmap_messages.cpp b/clang/test/OpenMP/target_teams_distribute_defaultmap_messages.cpp index 84d5b198c2878..3e3392d94af98 100644 --- a/clang/test/OpenMP/target_teams_distribute_defaultmap_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_defaultmap_messages.cpp @@ -1,5 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -verify=expected,omp51 -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd %s -verify=expected,omp51 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -DOMP5 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -DOMP5 @@ -15,21 +18,21 @@ T tmain(T argc, S **argv) { int i; #pragma omp target teams distribute defaultmap // expected-error {{expected '(' after 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute defaultmap( // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute defaultmap( // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute defaultmap() // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute defaultmap() // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} +#pragma omp target teams distribute defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp5x-error {{expected ')'}} omp5x-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute defaultmap (scalar: // expected-error {{expected ')'}} omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute defaultmap (scalar: // expected-error {{expected ')'}} omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); @@ -41,21 +44,21 @@ int main(int argc, char **argv) { int i; #pragma omp target teams distribute defaultmap // expected-error {{expected '(' after 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute defaultmap( // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute defaultmap( // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute defaultmap() // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute defaultmap() // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} +#pragma omp target teams distribute defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp5x-error {{expected ')'}} omp5x-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute defaultmap (scalar: // expected-error {{expected ')'}} omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute defaultmap (scalar: // expected-error {{expected ')'}} omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_defaultmap_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_defaultmap_messages.cpp index 0bb519be21740..b789c39dfad6b 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_defaultmap_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_defaultmap_messages.cpp @@ -1,5 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -verify=expected,omp51 -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd %s -verify=expected,omp51 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -DOMP5 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -DOMP5 @@ -15,21 +18,21 @@ T tmain(T argc, S **argv) { int i; #pragma omp target teams distribute parallel for defaultmap // expected-error {{expected '(' after 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for defaultmap( // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute parallel for defaultmap( // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for defaultmap() // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute parallel for defaultmap() // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute parallel for defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} +#pragma omp target teams distribute parallel for defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp5x-error {{expected ')'}} omp5x-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for defaultmap (scalar: // expected-error {{expected ')'}} omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute parallel for defaultmap (scalar: // expected-error {{expected ')'}} omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); @@ -41,21 +44,21 @@ int main(int argc, char **argv) { int i; #pragma omp target teams distribute parallel for defaultmap // expected-error {{expected '(' after 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for defaultmap( // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute parallel for defaultmap( // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for defaultmap() // omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute parallel for defaultmap() // omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute parallel for defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} +#pragma omp target teams distribute parallel for defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp5x-error {{expected ')'}} omp5x-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for defaultmap (scalar: // expected-error {{expected ')'}} omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute parallel for defaultmap (scalar: // expected-error {{expected ')'}} omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_defaultmap_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_defaultmap_messages.cpp index 0eeca55a9dcd2..ab3ea1b283d3b 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_defaultmap_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_defaultmap_messages.cpp @@ -1,5 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -verify=expected,omp51 -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd %s -verify=expected,omp51 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -fopenmp-version=52 -verify=expected,omp5x,omp52 -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -fopenmp-version=51 -verify=expected,omp5x,omp51 -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -DOMP5 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 %s -verify=expected,omp5 -Wuninitialized -DOMP5 @@ -15,22 +18,22 @@ T tmain(T argc, S **argv) { int i; #pragma omp target teams distribute parallel for simd defaultmap // expected-error {{expected '(' after 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd defaultmap( // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute parallel for simd defaultmap( // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd defaultmap() // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute parallel for simd defaultmap() // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute parallel for simd defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} +#pragma omp target teams distribute parallel for simd defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp5x-error {{expected ')'}} omp5x-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd defaultmap (scalar: // expected-error {{expected ')'}} omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute parallel for simd defaultmap (scalar: // expected-error {{expected ')'}} omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} @@ -44,27 +47,27 @@ int main(int argc, char **argv) { #pragma omp target teams distribute parallel for simd defaultmap // expected-error {{expected '(' after 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd defaultmap( // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute parallel for simd defaultmap( // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd defaultmap() // omp51-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute parallel for simd defaultmap() // omp5x-error {{'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd defaultmap(tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute parallel for simd defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd defaultmap(tofrom) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} +#pragma omp target teams distribute parallel for simd defaultmap(tofrom scalar) // omp45-warning {{missing ':' after defaultmap modifier - ignoring}} omp5-error {{expected ')'}} omp5-note {{to match this '('}} omp5x-error {{expected ')'}} omp5x-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd defaultmap(tofrom, // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd defaultmap (scalar: // expected-error {{expected ')'}} omp51-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} +#pragma omp target teams distribute parallel for simd defaultmap (scalar: // expected-error {{expected ')'}} omp5x-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default', 'present' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'alloc', 'from', 'to', 'tofrom', 'firstprivate', 'none', 'default' in OpenMP clause 'defaultmap'}} omp52-error {{expected 'scalar', 'aggregate', 'pointer', 'all' in OpenMP clause 'defaultmap'}} omp51-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} omp5-error {{expected 'scalar', 'aggregate', 'pointer' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} omp45-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd defaultmap(tofrom, scalar // expected-error {{expected ')'}} omp45-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} omp45-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} diff --git a/clang/test/PCH/aarch64-sve-types.c b/clang/test/PCH/aarch64-sve-types.c index 4c4549af0b6d6..249618c3a9708 100644 --- a/clang/test/PCH/aarch64-sve-types.c +++ b/clang/test/PCH/aarch64-sve-types.c @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-pch -o %t %s // RUN: %clang_cc1 -triple aarch64-linux-gnu -include-pch %t \ // RUN: -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -aux-triple aarch64-linux-gnu \ +// RUN: -x hip-cpp-output -emit-pch -o %t %s // expected-no-diagnostics diff --git a/clang/test/PCH/pragma-loop.cpp b/clang/test/PCH/pragma-loop.cpp index a3c6871041c0e..b02383c1485d5 100644 --- a/clang/test/PCH/pragma-loop.cpp +++ b/clang/test/PCH/pragma-loop.cpp @@ -18,9 +18,9 @@ // CHECK: #pragma nounroll{{$}} // CHECK: #pragma clang loop vectorize_width(V) // CHECK: #pragma clang loop interleave_count(I) -// CHECK: #pragma omp simd -// CHECK: #pragma omp for -// CHECK: #pragma omp distribute +// CHECK: #pragma omp loop bind(thread) +// CHECK: #pragma omp loop bind(parallel) +// CHECK: #pragma omp loop bind(teams) #ifndef HEADER #define HEADER diff --git a/clang/test/Parser/cxx-template-decl.cpp b/clang/test/Parser/cxx-template-decl.cpp index 734438069b9ae..476341686a64b 100644 --- a/clang/test/Parser/cxx-template-decl.cpp +++ b/clang/test/Parser/cxx-template-decl.cpp @@ -297,3 +297,7 @@ namespace PR46231 { template<> int; // expected-error {{declaration does not declare anything}} template int; // expected-error {{declaration does not declare anything}} } + +namespace PR99933 { + void foo() { template int i; } // expected-error {{templates can only be declared in namespace or class scope}} +} diff --git a/clang/test/Parser/namelookup-anonymous-struct.c b/clang/test/Parser/namelookup-anonymous-struct.c new file mode 100644 index 0000000000000..cb691c22f97ff --- /dev/null +++ b/clang/test/Parser/namelookup-anonymous-struct.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -std=c11 -verify %s + +struct GH31295 { + struct { int x; }; + int arr[sizeof(x)]; // expected-error{{use of undeclared identifier 'x'}} +}; diff --git a/clang/test/Preprocessor/Inputs/big_char.txt b/clang/test/Preprocessor/Inputs/big_char.txt new file mode 100644 index 0000000000000..ce542efaa5124 --- /dev/null +++ b/clang/test/Preprocessor/Inputs/big_char.txt @@ -0,0 +1 @@ +ÿ \ No newline at end of file diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c index 71cc36acf3f0e..87bd3e142d2c4 100644 --- a/clang/test/Preprocessor/aarch64-target-features.c +++ b/clang/test/Preprocessor/aarch64-target-features.c @@ -236,6 +236,15 @@ // RUN: %clang -target aarch64-none-linux-gnu -march=armv9-a+sve2-bitperm -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2BITPERM %s // CHECK-SVE2BITPERM: __ARM_FEATURE_SVE2_BITPERM 1 +// RUN: %clang -target aarch64-none-linux-gnu -march=armv9-a+sve2p1 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2p1 %s +// CHECK-SVE2p1: __ARM_FEATURE_FP16_SCALAR_ARITHMETIC 1 +// CHECK-SVE2p1: __ARM_FEATURE_FP16_VECTOR_ARITHMETIC 1 +// CHECK-SVE2p1: __ARM_FEATURE_SVE2 1 +// CHECK-SVE2p1: __ARM_FEATURE_SVE2p1 1 +// CHECK-SVE2p1: __ARM_NEON 1 +// CHECK-SVE2p1: __ARM_NEON_FP 0xE +// CHECK-SVE2p1: __ARM_NEON_SVE_BRIDGE 1 + // RUN: %clang -target aarch64-none-linux-gnu -march=armv8.2a+dotprod -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-DOTPROD %s // RUN: %clang -target aarch64-none-linux-gnu -march=armv8.4a -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-DOTPROD %s // CHECK-DOTPROD: __ARM_FEATURE_DOTPROD 1 @@ -694,3 +703,9 @@ // CHECK-SME2: __ARM_FEATURE_LOCALLY_STREAMING 1 // CHECK-SME2: __ARM_FEATURE_SME 1 // CHECK-SME2: __ARM_FEATURE_SME2 1 + +// RUN: %clang --target=aarch64 -march=armv9-a+sme2p1 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SME2p1 %s +// CHECK-SME2p1: __ARM_FEATURE_LOCALLY_STREAMING 1 +// CHECK-SME2p1: __ARM_FEATURE_SME 1 +// CHECK-SME2p1: __ARM_FEATURE_SME2 1 +// CHECK-SME2p1: __ARM_FEATURE_SME2p1 1 diff --git a/clang/test/Preprocessor/embed_codegen.cpp b/clang/test/Preprocessor/embed_codegen.cpp index 2cf14d8d6a15d..5baab9b59a9c1 100644 --- a/clang/test/Preprocessor/embed_codegen.cpp +++ b/clang/test/Preprocessor/embed_codegen.cpp @@ -14,9 +14,9 @@ int ca[] = { }; // CHECK: %arrayinit.element = getelementptr inbounds i32, ptr %notca, i64 1 -// CHECK: store i8 106, ptr %arrayinit.element, align 4 +// CHECK: store i32 106, ptr %arrayinit.element, align 4 // CHECK: %arrayinit.element1 = getelementptr inbounds i32, ptr %notca, i64 2 -// CHECK: store i8 107, ptr %arrayinit.element1, align 4 +// CHECK: store i32 107, ptr %arrayinit.element1, align 4 int notca[] = { a #embed prefix(,) @@ -75,9 +75,9 @@ constexpr struct T t[] = { // CHECK: %arrayinit.element7 = getelementptr inbounds %struct.T, ptr %tnonc, i64 1 // CHECK: call void @llvm.memset.p0.i64(ptr align 4 %arrayinit.element7, i8 0, i64 20, i1 false) // CHECK: %arr8 = getelementptr inbounds %struct.T, ptr %arrayinit.element7, i32 0, i32 0 -// CHECK: store i8 106, ptr %arr8, align 4 +// CHECK: store i32 106, ptr %arr8, align 4 // CHECK: %arrayinit.element9 = getelementptr inbounds i32, ptr %arr8, i64 1 -// CHECK: store i8 107, ptr %arrayinit.element9, align 4 +// CHECK: store i32 107, ptr %arrayinit.element9, align 4 struct T tnonc[] = { a, 300, 1, 2, 3 #embed prefix(,) diff --git a/clang/test/Preprocessor/embed_search_paths.c b/clang/test/Preprocessor/embed_search_paths.c new file mode 100644 index 0000000000000..5cc1bbf9f87a9 --- /dev/null +++ b/clang/test/Preprocessor/embed_search_paths.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -std=c23 %s -E -verify --embed-dir=%S --embed-dir=%S/Inputs +// expected-no-diagnostics + +#embed diff --git a/clang/test/Preprocessor/embed_weird.cpp b/clang/test/Preprocessor/embed_weird.cpp index cc73a88e5a657..9a984e40d4aa2 100644 --- a/clang/test/Preprocessor/embed_weird.cpp +++ b/clang/test/Preprocessor/embed_weird.cpp @@ -4,6 +4,8 @@ // RUN: printf "\0" > %t/null_byte.bin // RUN: %clang_cc1 %s -fsyntax-only --embed-dir=%t -verify=expected,cxx -Wno-c23-extensions // RUN: %clang_cc1 -x c -std=c23 %s -fsyntax-only --embed-dir=%t -verify=expected,c +// RUN: %clang_cc1 %s -fsyntax-only -fexperimental-new-constant-interpreter --embed-dir=%t -verify=expected,cxx -Wno-c23-extensions +// RUN: %clang_cc1 -x c -std=c23 %s -fsyntax-only -fexperimental-new-constant-interpreter --embed-dir=%t -verify=expected,c #embed ; @@ -115,3 +117,22 @@ void f1() { }; } #endif + +static_assert(_Generic( +#embed __FILE__ limit(1) + , int : 1, default : 0)); + +static_assert(alignof(typeof( +#embed __FILE__ limit(1) +)) == alignof(int)); + +struct HasChar { + signed char ch; +}; + +constexpr struct HasChar c = { +#embed "Inputs/big_char.txt" // cxx-error {{constant expression evaluates to 255 which cannot be narrowed to type 'signed char'}} \ + cxx-note {{insert an explicit cast to silence this issue}} \ + c-error {{constexpr initializer evaluates to 255 which is not exactly representable in type 'signed char'}} + +}; diff --git a/clang/test/Preprocessor/has_builtin_cpuid.c b/clang/test/Preprocessor/has_builtin_cpuid.c index 35ef65ecdd9b9..e69f912ce688d 100644 --- a/clang/test/Preprocessor/has_builtin_cpuid.c +++ b/clang/test/Preprocessor/has_builtin_cpuid.c @@ -2,14 +2,29 @@ // RUN: %clang_cc1 -fsyntax-only -triple x86_64-- -DX86 -verify %s // RUN: %clang_cc1 -fsyntax-only -triple powerpc64-unknown-linux-gnu -DPPC \ // RUN: -verify %s +// RUN: %clang_cc1 -fsyntax-only -triple riscv32-unknown-linux-gnu -DRISCV \ +// RUN: -verify %s +// RUN: %clang_cc1 -fsyntax-only -triple riscv64-unknown-linux-gnu -DRISCV \ +// RUN: -verify %s // expected-no-diagnostics #if __has_builtin(__builtin_cpu_is) -# ifdef ARM -# error "ARM shouldn't have __builtin_cpu_is" +# if defined(ARM) || defined(RISCV) +# error "ARM/RISCV shouldn't have __builtin_cpu_is" # endif #endif + #if __has_builtin(__builtin_cpu_init) # if defined(ARM) || defined(PPC) # error "ARM/PPC shouldn't have __builtin_cpu_init" # endif +#else +# ifdef RISCV +# error "RISCV should have __builtin_cpu_init" +# endif +#endif + +#if !__has_builtin(__builtin_cpu_supports) +# if defined(ARM) || defined(X86) || defined(RISCV) +# error "ARM/X86/RISCV should have __builtin_cpu_supports" +# endif #endif diff --git a/clang/test/Preprocessor/init-loongarch.c b/clang/test/Preprocessor/init-loongarch.c index 182f904b76592..771d56ffb1c1b 100644 --- a/clang/test/Preprocessor/init-loongarch.c +++ b/clang/test/Preprocessor/init-loongarch.c @@ -798,24 +798,51 @@ // LA64-FPU0-LP64S-NOT: #define __loongarch_single_float // LA64-FPU0-LP64S: #define __loongarch_soft_float 1 -/// Check __loongarch_arch and __loongarch_tune. +/// Check __loongarch_arch{_tune/_frecipe}. // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - | \ -// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=loongarch64 %s +// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la64v1.0 -DTUNE=loongarch64 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 | \ // RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=loongarch64 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la464 | \ // RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la464 -DTUNE=la464 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -mtune=loongarch64 | \ -// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=loongarch64 %s +// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la64v1.0 -DTUNE=loongarch64 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -mtune=la464 | \ -// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=la464 %s +// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la64v1.0 -DTUNE=la464 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -mtune=la464 | \ // RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=la464 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la464 -mtune=loongarch64 | \ // RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la464 -DTUNE=loongarch64 %s +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.0 | \ +// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la64v1.0 -DTUNE=loongarch64 %s +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.0 -Xclang -target-feature -Xclang -lsx | \ +// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=loongarch64 %s +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.0 -Xclang -target-feature -Xclang +frecipe | \ +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE -DARCH=la64v1.1 -DTUNE=loongarch64 %s +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +lsx | \ +// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la64v1.0 -DTUNE=loongarch64 %s +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.1 | \ +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE -DARCH=la64v1.1 -DTUNE=loongarch64 %s +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.1 -Xclang -target-feature -Xclang -frecipe | \ +// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la64v1.0 -DTUNE=loongarch64 %s +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.1 -Xclang -target-feature -Xclang -lsx | \ +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE -DARCH=loongarch64 -DTUNE=loongarch64 %s +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +frecipe | \ +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE -DARCH=loongarch64 -DTUNE=loongarch64 %s +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +lsx -Xclang -target-feature -Xclang +frecipe | \ +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE -DARCH=la64v1.1 -DTUNE=loongarch64 %s +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la664 | \ +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE -DARCH=la664 -DTUNE=la664 %s +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -mtune=la664 | \ +// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la64v1.0 -DTUNE=la664 %s +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -mtune=la664 | \ +// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=la664 %s +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la664 -mtune=loongarch64 | \ +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE -DARCH=la664 -DTUNE=loongarch64 %s // ARCH-TUNE: #define __loongarch_arch "[[ARCH]]" +// FRECIPE: #define __loongarch_frecipe 1 // ARCH-TUNE: #define __loongarch_tune "[[TUNE]]" // RUN: %clang --target=loongarch64 -mlsx -x c -E -dM %s -o - \ @@ -824,6 +851,8 @@ // RUN: | FileCheck --match-full-lines --check-prefix=MLSX %s // RUN: %clang --target=loongarch64 -mlsx -mno-lasx -x c -E -dM %s -o - \ // RUN: | FileCheck --match-full-lines --check-prefix=MLSX %s +// RUN: %clang --target=loongarch64 -mno-lasx -x c -E -dM %s -o - \ +// RUN: | FileCheck --match-full-lines --check-prefix=MLSX %s // RUN: %clang --target=loongarch64 -mno-lasx -mlsx -x c -E -dM %s -o - \ // RUN: | FileCheck --match-full-lines --check-prefix=MLSX %s // MLSX-NOT: #define __loongarch_asx @@ -832,12 +861,12 @@ // RUN: %clang --target=loongarch64 -mlasx -x c -E -dM %s -o - \ // RUN: | FileCheck --match-full-lines --check-prefix=MLASX %s -// RUN: %clang --target=loongarch64 -mno-lasx -mlasx -x c -E -dM %s -o - \ -// RUN: | FileCheck --match-full-lines --check-prefix=MLASX %s // RUN: %clang --target=loongarch64 -mlsx -mlasx -x c -E -dM %s -o - \ // RUN: | FileCheck --match-full-lines --check-prefix=MLASX %s // RUN: %clang --target=loongarch64 -mlasx -mlsx -x c -E -dM %s -o - \ // RUN: | FileCheck --match-full-lines --check-prefix=MLASX %s +// RUN: %clang --target=loongarch64 -mno-lasx -mlasx -x c -E -dM %s -o - \ +// RUN: | FileCheck --match-full-lines --check-prefix=MLASX %s // MLASX: #define __loongarch_asx 1 // MLASX: #define __loongarch_simd_width 256 // MLASX: #define __loongarch_sx 1 @@ -850,8 +879,6 @@ // RUN: | FileCheck --match-full-lines --check-prefix=MNO-LSX %s // RUN: %clang --target=loongarch64 -mno-lasx -mno-lsx -x c -E -dM %s -o - \ // RUN: | FileCheck --match-full-lines --check-prefix=MNO-LSX %s -// RUN: %clang --target=loongarch64 -mno-lasx -x c -E -dM %s -o - \ -// RUN: | FileCheck --match-full-lines --check-prefix=MNO-LSX %s // MNO-LSX-NOT: #define __loongarch_asx // MNO-LSX-NOT: #define __loongarch_simd_width // MNO-LSX-NOT: #define __loongarch_sx diff --git a/clang/test/Preprocessor/init-ppc64.c b/clang/test/Preprocessor/init-ppc64.c index 42e5232824de7..56164beb913d5 100644 --- a/clang/test/Preprocessor/init-ppc64.c +++ b/clang/test/Preprocessor/init-ppc64.c @@ -632,6 +632,27 @@ // PPCPOWER10:#define __PCREL__ 1 // PPCPOWER10-NOT:#define __ROP_PROTECT__ 1 // +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu pwr11 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPOWER11 %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu power11 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPOWER11 %s +// +// PPCPOWER11:#define _ARCH_PPC 1 +// PPCPOWER11:#define _ARCH_PPC64 1 +// PPCPOWER11:#define _ARCH_PPCGR 1 +// PPCPOWER11:#define _ARCH_PPCSQ 1 +// PPCPOWER11:#define _ARCH_PWR10 1 +// PPCPOWER11:#define _ARCH_PWR11 1 +// PPCPOWER11:#define _ARCH_PWR4 1 +// PPCPOWER11:#define _ARCH_PWR5 1 +// PPCPOWER11:#define _ARCH_PWR5X 1 +// PPCPOWER11:#define _ARCH_PWR6 1 +// PPCPOWER11-NOT:#define _ARCH_PWR6X 1 +// PPCPOWER11:#define _ARCH_PWR7 1 +// PPCPOWER11:#define _ARCH_PWR8 1 +// PPCPOWER11:#define _ARCH_PWR9 1 +// PPCPOWER11:#define __MMA__ 1 +// PPCPOWER11:#define __PCREL__ 1 +// PPCPOWER11-NOT:#define __ROP_PROTECT__ 1 +// // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu future -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCFUTURE %s // // PPCFUTURE:#define _ARCH_PPC 1 @@ -639,6 +660,7 @@ // PPCFUTURE:#define _ARCH_PPCGR 1 // PPCFUTURE:#define _ARCH_PPCSQ 1 // PPCFUTURE:#define _ARCH_PWR10 1 +// PPCFUTURE:#define _ARCH_PWR11 1 // PPCFUTURE:#define _ARCH_PWR4 1 // PPCFUTURE:#define _ARCH_PWR5 1 // PPCFUTURE:#define _ARCH_PWR5X 1 diff --git a/clang/test/Preprocessor/pragma_mc_func.c b/clang/test/Preprocessor/pragma_mc_func.c new file mode 100644 index 0000000000000..bf12f7107ff5c --- /dev/null +++ b/clang/test/Preprocessor/pragma_mc_func.c @@ -0,0 +1,25 @@ +// RUN: not %clang --target=powerpc64-ibm-aix -fsyntax-only %s 2>&1 | FileCheck %s +// RUN: not %clang --target=powerpc64-ibm-aix -ferr-pragma-mc-func-aix -fsyntax-only \ +// RUN: %s 2>&1 | FileCheck %s +// RUN: not %clang --target=powerpc64-ibm-aix -fno-err-pragma-mc-func-aix \ +// RUN: -ferr-pragma-mc-func-aix -fsyntax-only %s 2>&1 | FileCheck %s +#pragma mc_func asm_barrier {"60000000"} + +// CHECK: error: #pragma mc_func is not supported + +// Cases where no errors occur. +// RUN: %clang --target=powerpc64-ibm-aix -fno-err-pragma-mc-func-aix -fsyntax-only %s +// RUN: %clang --target=powerpc64-ibm-aix -ferr-pragma-mc-func-aix -fsyntax-only \ +// RUN: -fno-err-pragma-mc-func-aix %s +// RUN: %clang --target=powerpc64-ibm-aix -Werror=unknown-pragmas \ +// RUN: -fno-err-pragma-mc-func-aix -fsyntax-only %s + +// Cases on a non-AIX target. +// RUN: not %clang --target=powerpc64le-unknown-linux-gnu \ +// RUN: -Werror=unknown-pragmas -fno-err-pragma-mc-func-aix -fsyntax-only %s 2>&1 | \ +// RUN: FileCheck --check-prefix=UNUSED %s +// RUN: %clang --target=powerpc64le-unknown-linux-gnu \ +// RUN: -fno-err-pragma-mc-func-aix -fsyntax-only %s 2>&1 | \ +// RUN: FileCheck --check-prefix=UNUSED %s + +// UNUSED: clang: warning: argument unused during compilation: '-fno-err-pragma-mc-func-aix' [-Wunused-command-line-argument] diff --git a/clang/test/Preprocessor/predefined-macros.c b/clang/test/Preprocessor/predefined-macros.c index ebe192ecf2549..317bb7c0dc01c 100644 --- a/clang/test/Preprocessor/predefined-macros.c +++ b/clang/test/Preprocessor/predefined-macros.c @@ -70,7 +70,7 @@ // RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-NO-MATH-ERRNO // CHECK-NO-MATH-ERRNO: #define __NO_MATH_ERRNO__ 1 // -// RUN: %clang_cc1 %s -E -dM -ffinite-math-only -o - \ +// RUN: %clang_cc1 %s -E -dM -menable-no-nans -menable-no-infs -o - \ // RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-FINITE-MATH-ONLY // CHECK-FINITE-MATH-ONLY: #define __FINITE_MATH_ONLY__ 1 // diff --git a/clang/test/Preprocessor/ptrauth_feature.c b/clang/test/Preprocessor/ptrauth_feature.c index 1330ad10b4b47..14059f827b94c 100644 --- a/clang/test/Preprocessor/ptrauth_feature.c +++ b/clang/test/Preprocessor/ptrauth_feature.c @@ -2,25 +2,31 @@ //// For example, -fptrauth-init-fini will not affect codegen without -fptrauth-calls, but the preprocessor feature would be set anyway. // RUN: %clang_cc1 -E %s -triple=aarch64 -fptrauth-intrinsics | \ -// RUN: FileCheck %s --check-prefixes=INTRIN,NOCALLS,NORETS,NOVPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,NOFUNC,NOINITFINI +// RUN: FileCheck %s --check-prefixes=INTRIN,NOCALLS,NORETS,NOVPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,NOTYPE_INFO_DISCR,NOFUNC,NOINITFINI,NOGOTOS // RUN: %clang_cc1 -E %s -triple=aarch64 -fptrauth-calls | \ -// RUN: FileCheck %s --check-prefixes=NOINTRIN,CALLS,NORETS,NOVPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,NOFUNC,NOINITFINI +// RUN: FileCheck %s --check-prefixes=NOINTRIN,CALLS,NORETS,NOVPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,NOTYPE_INFO_DISCR,NOFUNC,NOINITFINI,NOGOTOS // RUN: %clang_cc1 -E %s -triple=aarch64 -fptrauth-returns | \ -// RUN: FileCheck %s --check-prefixes=NOINTRIN,NOCALLS,RETS,NOVPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,NOFUNC,NOINITFINI +// RUN: FileCheck %s --check-prefixes=NOINTRIN,NOCALLS,RETS,NOVPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,NOTYPE_INFO_DISCR,NOFUNC,NOINITFINI,NOGOTOS // RUN: %clang_cc1 -E %s -triple=aarch64 -fptrauth-vtable-pointer-address-discrimination | \ -// RUN: FileCheck %s --check-prefixes=NOINTRIN,NOCALLS,NORETS,VPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,NOFUNC,NOINITFINI +// RUN: FileCheck %s --check-prefixes=NOINTRIN,NOCALLS,NORETS,VPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,NOTYPE_INFO_DISCR,NOFUNC,NOINITFINI,NOGOTOS // RUN: %clang_cc1 -E %s -triple=aarch64 -fptrauth-vtable-pointer-type-discrimination | \ -// RUN: FileCheck %s --check-prefixes=NOINTRIN,NOCALLS,NORETS,NOVPTR_ADDR_DISCR,VPTR_TYPE_DISCR,NOFUNC,NOINITFINI +// RUN: FileCheck %s --check-prefixes=NOINTRIN,NOCALLS,NORETS,NOVPTR_ADDR_DISCR,VPTR_TYPE_DISCR,NOTYPE_INFO_DISCR,NOFUNC,NOINITFINI,NOGOTOS + +// RUN: %clang_cc1 -E %s -triple=aarch64 -fptrauth-type-info-vtable-pointer-discrimination | \ +// RUN: FileCheck %s --check-prefixes=NOINTRIN,NOCALLS,NORETS,NOVPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,TYPE_INFO_DISCR,NOFUNC,NOINITFINI,NOGOTOS // RUN: %clang_cc1 -E %s -triple=aarch64 -fptrauth-function-pointer-type-discrimination | \ -// RUN: FileCheck %s --check-prefixes=NOINTRIN,NOCALLS,NORETS,NOVPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,FUNC,NOINITFINI +// RUN: FileCheck %s --check-prefixes=NOINTRIN,NOCALLS,NORETS,NOVPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,NOTYPE_INFO_DISCR,FUNC,NOINITFINI,NOGOTOS // RUN: %clang_cc1 -E %s -triple=aarch64 -fptrauth-init-fini | \ -// RUN: FileCheck %s --check-prefixes=NOINTRIN,NOCALLS,NORETS,NOVPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,NOFUNC,INITFINI +// RUN: FileCheck %s --check-prefixes=NOINTRIN,NOCALLS,NORETS,NOVPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,NOTYPE_INFO_DISCR,NOFUNC,INITFINI,NOGOTOS + +// RUN: %clang_cc1 -E %s -triple=aarch64 -fptrauth-indirect-gotos | \ +// RUN: FileCheck %s --check-prefixes=NOINTRIN,NOCALLS,NORETS,NOVPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,NOTYPE_INFO_DISCR,NOFUNC,NOINITFINI,GOTOS #if __has_feature(ptrauth_intrinsics) // INTRIN: has_ptrauth_intrinsics @@ -71,6 +77,14 @@ void has_ptrauth_vtable_pointer_type_discrimination() {} void no_ptrauth_vtable_pointer_type_discrimination() {} #endif +#if __has_feature(ptrauth_type_info_vtable_pointer_discrimination) +// TYPE_INFO_DISCR: has_ptrauth_type_info_vtable_pointer_discrimination +void has_ptrauth_type_info_vtable_pointer_discrimination() {} +#else +// NOTYPE_INFO_DISCR: no_ptrauth_type_info_vtable_pointer_discrimination +void no_ptrauth_type_info_vtable_pointer_discrimination() {} +#endif + #if __has_feature(ptrauth_function_pointer_type_discrimination) // FUNC: has_ptrauth_function_pointer_type_discrimination void has_ptrauth_function_pointer_type_discrimination() {} @@ -86,3 +100,11 @@ void has_ptrauth_init_fini() {} // NOINITFINI: no_ptrauth_init_fini void no_ptrauth_init_fini() {} #endif + +#if __has_feature(ptrauth_indirect_gotos) +// GOTOS: has_ptrauth_indirect_gotos +void has_ptrauth_indirect_gotos() {} +#else +// NOGOTOS: no_ptrauth_indirect_gotos +void no_ptrauth_indirect_gotos() {} +#endif diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c index fd718a126aaa7..72131108cb5f6 100644 --- a/clang/test/Preprocessor/riscv-target-features.c +++ b/clang/test/Preprocessor/riscv-target-features.c @@ -86,7 +86,6 @@ // CHECK-NOT: __riscv_za64rs {{.*$}} // CHECK-NOT: __riscv_zaamo {{.*$}} // CHECK-NOT: __riscv_zabha {{.*$}} -// CHECK-NOT: __riscv_zacas {{.*$}} // CHECK-NOT: __riscv_zalrsc {{.*$}} // CHECK-NOT: __riscv_zama16b {{.*$}} // CHECK-NOT: __riscv_zawrs {{.*$}} @@ -182,6 +181,7 @@ // CHECK-NOT: __riscv_sspm{{.*$}} // CHECK-NOT: __riscv_ssqosid{{.*$}} // CHECK-NOT: __riscv_supm{{.*$}} +// CHECK-NOT: __riscv_zacas {{.*$}} // CHECK-NOT: __riscv_zalasr {{.*$}} // CHECK-NOT: __riscv_zfbfmin {{.*$}} // CHECK-NOT: __riscv_zicfilp {{.*$}} @@ -747,14 +747,6 @@ // RUN: -o - | FileCheck --check-prefix=CHECK-ZABHA-EXT %s // CHECK-ZABHA-EXT: __riscv_zabha 1000000{{$}} -// RUN: %clang --target=riscv32 \ -// RUN: -march=rv32ia_zacas1p0 -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s -// RUN: %clang --target=riscv64 \ -// RUN: -march=rv64ia_zacas1p0 -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s -// CHECK-ZACAS-EXT: __riscv_zacas 1000000{{$}} - // RUN: %clang --target=riscv32 \ // RUN: -march=rv32i_zalrsc1p0 -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZALRSC-EXT %s @@ -1626,6 +1618,14 @@ // CHECK-ZVKT-EXT: __riscv_zvkt 1000000{{$}} // Experimental extensions +// RUN: %clang --target=riscv32 -menable-experimental-extensions \ +// RUN: -march=rv32ia_zacas1p0 -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s +// RUN: %clang --target=riscv64 -menable-experimental-extensions \ +// RUN: -march=rv64ia_zacas1p0 -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s +// CHECK-ZACAS-EXT: __riscv_zacas 1000000{{$}} + // RUN: %clang --target=riscv32 -menable-experimental-extensions \ // RUN: -march=rv32i_zalasr0p1 -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZALASR-EXT %s diff --git a/clang/test/Preprocessor/x86_target_features.c b/clang/test/Preprocessor/x86_target_features.c index 5c0b815c8ae6f..5d510cb4667f4 100644 --- a/clang/test/Preprocessor/x86_target_features.c +++ b/clang/test/Preprocessor/x86_target_features.c @@ -512,11 +512,11 @@ // NOHRESET-NOT: #define __HRESET__ 1 -// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -muintr -x c -E -dM -o - %s | FileCheck -check-prefix=UINTR %s +// RUN: %clang -target x86_64-unknown-linux-gnu -march=x86-64 -muintr -x c -E -dM -o - %s | FileCheck -check-prefix=UINTR %s // UINTR: #define __UINTR__ 1 -// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-uintr -x c -E -dM -o - %s | FileCheck -check-prefix=NOUINTR %s +// RUN: %clang -target x86_64-unknown-linux-gnu -march=x86-64 -mno-uintr -x c -E -dM -o - %s | FileCheck -check-prefix=NOUINTR %s // NOUINTR-NOT: #define __UINTR__ 1 @@ -755,7 +755,7 @@ // RUN: %clang -target x86_64-unknown-unknown -march=x86-64 -mapx-features=nf -x c -E -dM -o - %s | FileCheck --check-prefix=NF %s // RUN: %clang -target x86_64-unknown-unknown -march=x86-64 -mapx-features=cf -x c -E -dM -o - %s | FileCheck --check-prefix=CF %s // RUN: %clang -target x86_64-unknown-unknown -march=x86-64 -mapx-features=zu -x c -E -dM -o - %s | FileCheck --check-prefix=ZU %s -// RUN: %clang -target x86_64-unknown-unknown -march=x86-64 -mapxf -x c -E -dM -o - %s | FileCheck --check-prefixes=EGPR,PUSH2POP2,PPX,NDD,CCMP,NF,CF,APXF %s +// RUN: %clang -target x86_64-unknown-unknown -march=x86-64 -mapxf -x c -E -dM -o - %s | FileCheck --check-prefixes=EGPR,PUSH2POP2,PPX,NDD,CCMP,NF,CF,ZU,APXF %s // APXF: #define __APX_F__ 1 // CCMP: #define __CCMP__ 1 // CF: #define __CF__ 1 diff --git a/clang/test/Sema/aarch64-fmv-streaming.c b/clang/test/Sema/aarch64-fmv-streaming.c new file mode 100644 index 0000000000000..93b7656216c0c --- /dev/null +++ b/clang/test/Sema/aarch64-fmv-streaming.c @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -Waarch64-sme-attributes -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -Waarch64-sme-attributes -fsyntax-only -verify=expected-cpp -x c++ %s + +__attribute__((target_clones("sve", "simd"))) void ok_arm_streaming(void) __arm_streaming {} +__arm_locally_streaming __attribute__((target_version("sme2"))) void ok_arm_streaming(void) __arm_streaming {} +__attribute__((target_version("default"))) void ok_arm_streaming(void) __arm_streaming {} + +__attribute__((target_clones("sve", "simd"))) void ok_arm_streaming_compatible(void) __arm_streaming_compatible {} +__arm_locally_streaming __attribute__((target_version("sme2"))) void ok_arm_streaming_compatible(void) __arm_streaming_compatible {} +__attribute__((target_version("default"))) void ok_arm_streaming_compatible(void) __arm_streaming_compatible {} + +__arm_locally_streaming __attribute__((target_clones("sve", "simd"))) void ok_no_streaming(void) {} +__attribute__((target_version("sme2"))) void ok_no_streaming(void) {} +__attribute__((target_version("default"))) void ok_no_streaming(void) {} + +__attribute__((target_clones("sve", "simd"))) void bad_mixed_streaming(void) {} +// expected-cpp-error@+2 {{multiversioned function declaration has a different calling convention}} +// expected-error@+1 {{multiversioned function declaration has a different calling convention}} +__attribute__((target_version("sme2"))) void bad_mixed_streaming(void) __arm_streaming {} +// expected-cpp-error@+2 {{multiversioned function declaration has a different calling convention}} +// expected-error@+1 {{multiversioned function declaration has a different calling convention}} +__attribute__((target_version("default"))) void bad_mixed_streaming(void) __arm_streaming_compatible {} +// expected-cpp-error@+2 {{multiversioned function declaration has a different calling convention}} +// expected-error@+1 {{multiversioned function declaration has a different calling convention}} +__arm_locally_streaming __attribute__((target_version("dotprod"))) void bad_mixed_streaming(void) __arm_streaming {} + +void n_caller(void) { + ok_arm_streaming(); + ok_arm_streaming_compatible(); + ok_no_streaming(); + bad_mixed_streaming(); +} + +void s_caller(void) __arm_streaming { + ok_arm_streaming(); + ok_arm_streaming_compatible(); + ok_no_streaming(); + bad_mixed_streaming(); +} + +void sc_caller(void) __arm_streaming_compatible { + ok_arm_streaming(); + ok_arm_streaming_compatible(); + ok_no_streaming(); + bad_mixed_streaming(); +} diff --git a/clang/test/Sema/aarch64-neon-without-target-feature.cpp b/clang/test/Sema/aarch64-neon-without-target-feature.cpp new file mode 100644 index 0000000000000..0831eb7c754a7 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-without-target-feature.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +dotprod -target-feature +fullfp16 -target-feature +fp16fml -target-feature +i8mm -target-feature +bf16 -verify -emit-llvm -o - %s + +// REQUIRES: aarch64-registered-target + +// This test is testing the diagnostics that Clang emits when compiling without '+neon'. + +#include + +void undefined(uint32x2_t v2i32, uint32x4_t v4i32, uint16x8_t v8i16, uint8x16_t v16i8, uint8x8_t v8i8, float32x2_t v2f32, float32x4_t v4f32, float16x4_t v4f16, float64x2_t v2f64, bfloat16x4_t v4bf16, __bf16 bf16, poly64_t poly64, poly64x2_t poly64x2) { + // dotprod + vdot_u32(v2i32, v8i8, v8i8); // expected-error {{always_inline function 'vdot_u32' requires target feature 'neon'}} + vdot_laneq_u32(v2i32, v8i8, v16i8, 1); // expected-error {{always_inline function 'vdot_u32' requires target feature 'neon'}} expected-error {{'__builtin_neon_splat_laneq_v' needs target feature neon}} + // fp16 + vceqz_f16(v4f16); // expected-error {{always_inline function 'vceqz_f16' requires target feature 'neon'}} + vrnd_f16(v4f16); // expected-error {{always_inline function 'vrnd_f16' requires target feature 'neon'}} + vmaxnm_f16(v4f16, v4f16); // expected-error {{always_inline function 'vmaxnm_f16' requires target feature 'neon'}} + vrndi_f16(v4f16); // expected-error {{always_inline function 'vrndi_f16' requires target feature 'neon'}} + // fp16fml depends on fp-armv8 + vfmlal_low_f16(v2f32, v4f16, v4f16); // expected-error {{always_inline function 'vfmlal_low_f16' requires target feature 'neon'}} + // i8mm + vmmlaq_s32(v4i32, v8i16, v8i16); // expected-error {{always_inline function 'vmmlaq_s32' requires target feature 'neon'}} + vusdot_laneq_s32(v2i32, v8i8, v8i16, 0); // expected-error {{always_inline function 'vusdot_s32' requires target feature 'neon'}} expected-error {{'__builtin_neon_splat_laneq_v' needs target feature neon}} + // bf16 + vbfdot_f32(v2f32, v4bf16, v4bf16); // expected-error {{always_inline function 'vbfdot_f32' requires target feature 'neon'}} + vcreate_bf16(10); + vdup_lane_bf16(v4bf16, 2); // expected-error {{'__builtin_neon_splat_lane_bf16' needs target feature bf16,neon}} + vdup_n_bf16(bf16); // expected-error {{always_inline function 'vdup_n_bf16' requires target feature 'neon'}} + vld1_bf16(0); // expected-error {{'__builtin_neon_vld1_bf16' needs target feature bf16,neon}} + vcvt_f32_bf16(v4bf16); // expected-error {{always_inline function 'vcvt_f32_bf16' requires target feature 'neon'}} + vcvt_bf16_f32(v4f32); // expected-error {{always_inline function 'vcvt_bf16_f32' requires target feature 'neon'}} + vmull_p64(poly64, poly64); // expected-error {{always_inline function 'vmull_p64' requires target feature 'neon'}} + vmull_high_p64(poly64x2, poly64x2); // expected-error {{always_inline function 'vmull_high_p64' requires target feature 'neon'}} + vtrn1_s8(v8i8, v8i8); // expected-error {{always_inline function 'vtrn1_s8' requires target feature 'neon'}} + vqabsq_s16(v8i16); // expected-error {{always_inline function 'vqabsq_s16' requires target feature 'neon'}} + vbslq_s16(v8i16, v8i16, v8i16);// expected-error {{always_inline function 'vbslq_s16' requires target feature 'neon'}} +} diff --git a/clang/test/Sema/aarch64-sme-func-attrs.c b/clang/test/Sema/aarch64-sme-func-attrs.c index 6db39d6a71e36..0c263eb2610cf 100644 --- a/clang/test/Sema/aarch64-sme-func-attrs.c +++ b/clang/test/Sema/aarch64-sme-func-attrs.c @@ -455,48 +455,6 @@ void unimplemented_spill_fill_za(void (*share_zt0_only)(void) __arm_inout("zt0") share_zt0_only(); } -// expected-cpp-error@+2 {{streaming function cannot be multi-versioned}} -// expected-error@+1 {{streaming function cannot be multi-versioned}} -__attribute__((target_version("sme2"))) -void cannot_work_version(void) __arm_streaming {} -// expected-cpp-error@+5 {{function declared 'void ()' was previously declared 'void () __arm_streaming', which has different SME function attributes}} -// expected-cpp-note@-2 {{previous declaration is here}} -// expected-error@+3 {{function declared 'void (void)' was previously declared 'void (void) __arm_streaming', which has different SME function attributes}} -// expected-note@-4 {{previous declaration is here}} -__attribute__((target_version("default"))) -void cannot_work_version(void) {} - - -// expected-cpp-error@+2 {{streaming function cannot be multi-versioned}} -// expected-error@+1 {{streaming function cannot be multi-versioned}} -__attribute__((target_clones("sme2"))) -void cannot_work_clones(void) __arm_streaming {} - - -__attribute__((target("sme2"))) -void just_fine_streaming(void) __arm_streaming {} -__attribute__((target_version("sme2"))) -void just_fine(void) { just_fine_streaming(); } -__attribute__((target_version("default"))) -void just_fine(void) {} - - -__arm_locally_streaming -__attribute__((target_version("sme2"))) -void incompatible_locally_streaming(void) {} -// expected-error@-1 {{attribute 'target_version' multiversioning cannot be combined with attribute '__arm_locally_streaming'}} -// expected-cpp-error@-2 {{attribute 'target_version' multiversioning cannot be combined with attribute '__arm_locally_streaming'}} -__attribute__((target_version("default"))) -void incompatible_locally_streaming(void) {} - - -void fmv_caller() { - cannot_work_version(); - cannot_work_clones(); - just_fine(); - incompatible_locally_streaming(); -} - void sme_streaming_with_vl_arg(__SVInt8_t a) __arm_streaming { } __SVInt8_t sme_streaming_returns_vl(void) __arm_streaming { __SVInt8_t r; return r; } diff --git a/clang/test/Sema/alignas.c b/clang/test/Sema/alignas.c index 020eff6a141c0..391553bc540ec 100644 --- a/clang/test/Sema/alignas.c +++ b/clang/test/Sema/alignas.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -Dalignof=__alignof %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -Dalignof=_Alignof -DUSING_C11_SYNTAX %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c23 -DUSING_C11_SYNTAX %s _Alignas(3) int align_illegal; //expected-error {{requested alignment is not a power of 2}} _Alignas(int) char align_big; @@ -18,12 +19,24 @@ void f(_Alignas(1) char c) { // expected-error {{'_Alignas' attribute cannot be } #ifdef USING_C11_SYNTAX -// expected-warning@+4{{'_Alignof' applied to an expression is a GNU extension}} -// expected-warning@+4{{'_Alignof' applied to an expression is a GNU extension}} -// expected-warning@+4{{'_Alignof' applied to an expression is a GNU extension}} +// expected-warning-re@+4{{'{{(_A|a)}}lignof' applied to an expression is a GNU extension}} +// expected-warning-re@+4{{'{{(_A|a)}}lignof' applied to an expression is a GNU extension}} +// expected-warning-re@+4{{'{{(_A|a)}}lignof' applied to an expression is a GNU extension}} #endif _Static_assert(alignof(align_big) == alignof(int), "k's alignment is wrong"); _Static_assert(alignof(align_small) == 1, "j's alignment is wrong"); _Static_assert(alignof(align_multiple) == 8, "l's alignment is wrong"); _Static_assert(alignof(struct align_member) == 8, "quuux's alignment is wrong"); _Static_assert(sizeof(struct align_member) == 8, "quuux's size is wrong"); + +struct GH95032_1 { + _Alignas(16) char bytes[16]; +}; +_Static_assert(_Alignof(struct GH95032_1) == 16, ""); + +#if __STDC_VERSION__ >= 202311L +struct GH95032_2 { + alignas(16) char bytes[16]; +}; +static_assert(alignof(struct GH95032_2) == 16); +#endif diff --git a/clang/test/Sema/atomic-ops.c b/clang/test/Sema/atomic-ops.c index 9b82d82ff8269..2405f804d0da5 100644 --- a/clang/test/Sema/atomic-ops.c +++ b/clang/test/Sema/atomic-ops.c @@ -124,6 +124,31 @@ _Static_assert(__atomic_always_lock_free(4, &i64), ""); _Static_assert(!__atomic_always_lock_free(8, &i32), ""); _Static_assert(__atomic_always_lock_free(8, &i64), ""); +// Validate use with fake pointers constants. This mechanism is used to allow +// validating atomicity of a given size and alignment. +_Static_assert(__atomic_is_lock_free(1, (void*)1), ""); +_Static_assert(__atomic_is_lock_free(1, (void*)-1), ""); +_Static_assert(__atomic_is_lock_free(4, (void*)2), ""); // expected-error {{not an integral constant expression}} +_Static_assert(__atomic_is_lock_free(4, (void*)-2), ""); // expected-error {{not an integral constant expression}} +_Static_assert(__atomic_is_lock_free(4, (void*)4), ""); +_Static_assert(__atomic_is_lock_free(4, (void*)-4), ""); + +_Static_assert(__atomic_always_lock_free(1, (void*)1), ""); +_Static_assert(__atomic_always_lock_free(1, (void*)-1), ""); +_Static_assert(!__atomic_always_lock_free(4, (void*)2), ""); +_Static_assert(!__atomic_always_lock_free(4, (void*)-2), ""); +_Static_assert(__atomic_always_lock_free(4, (void*)4), ""); +_Static_assert(__atomic_always_lock_free(4, (void*)-4), ""); + +// Ensure that "weird" constants don't cause trouble. +_Static_assert(__atomic_always_lock_free(1, "string"), ""); +_Static_assert(!__atomic_always_lock_free(2, "string"), ""); +_Static_assert(__atomic_always_lock_free(2, (int[2]){}), ""); +void dummyfn(); +_Static_assert(__atomic_always_lock_free(2, dummyfn) || 1, ""); + + + #define _AS1 __attribute__((address_space(1))) #define _AS2 __attribute__((address_space(2))) diff --git a/clang/test/Sema/attr-counted-by-bounds-safety-vlas.c b/clang/test/Sema/attr-counted-by-bounds-safety-vlas.c new file mode 100644 index 0000000000000..7d9c9a90880ff --- /dev/null +++ b/clang/test/Sema/attr-counted-by-bounds-safety-vlas.c @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -fexperimental-bounds-safety -verify %s +// +// This is a portion of the `attr-counted-by-vla.c` test but is checked +// under the semantics of `-fexperimental-bounds-safety` which has different +// behavior. + +#define __counted_by(f) __attribute__((counted_by(f))) + +struct has_unannotated_VLA { + int count; + char buffer[]; +}; + +struct has_annotated_VLA { + int count; + char buffer[] __counted_by(count); +}; + +struct buffer_of_structs_with_unnannotated_vla { + int count; + // expected-error@+1{{'counted_by' cannot be applied to an array with element of unknown size because 'struct has_unannotated_VLA' is a struct type with a flexible array member}} + struct has_unannotated_VLA Arr[] __counted_by(count); +}; + + +struct buffer_of_structs_with_annotated_vla { + int count; + // expected-error@+1{{'counted_by' cannot be applied to an array with element of unknown size because 'struct has_annotated_VLA' is a struct type with a flexible array member}} + struct has_annotated_VLA Arr[] __counted_by(count); +}; + +struct buffer_of_const_structs_with_annotated_vla { + int count; + // Make sure the `const` qualifier is printed when printing the element type. + // expected-error@+1{{'counted_by' cannot be applied to an array with element of unknown size because 'const struct has_annotated_VLA' is a struct type with a flexible array member}} + const struct has_annotated_VLA Arr[] __counted_by(count); +}; diff --git a/clang/test/Sema/attr-format.c b/clang/test/Sema/attr-format.c index 1f4c864d4f78b..5a8b1ac9eca5c 100644 --- a/clang/test/Sema/attr-format.c +++ b/clang/test/Sema/attr-format.c @@ -99,3 +99,10 @@ void forward_fixed(const char *fmt, _Bool b, char i, short j, int k, float l, do a(fmt, b, i, j, k, l, m); } +// OpenBSD +// same as format(printf(...))... +void a2(const char *a, ...) __attribute__((format(syslog, 1, 2))); // no-error +void b2(const char *a, ...) __attribute__((format(syslog, 1, 1))); // expected-error {{'format' attribute parameter 3 is out of bounds}} +void c2(const char *a, ...) __attribute__((format(syslog, 0, 2))); // expected-error {{'format' attribute parameter 2 is out of bounds}} +void d2(const char *a, int c) __attribute__((format(syslog, 1, 2))); // expected-warning {{GCC requires a function with the 'format' attribute to be variadic}} +void e2(char *str, int c, ...) __attribute__((format(syslog, 2, 3))); // expected-error {{format argument not a string type}} diff --git a/clang/test/Sema/attr-ownership.c b/clang/test/Sema/attr-ownership.c index 8157ba7145a24..d2e40538a40f0 100644 --- a/clang/test/Sema/attr-ownership.c +++ b/clang/test/Sema/attr-ownership.c @@ -18,9 +18,16 @@ void *f12(float i, int k, int f, int *j) __attribute__((ownership_returns(foo, 4 void f13(int *i, int *j) __attribute__((ownership_holds(foo, 1))) __attribute__((ownership_takes(foo, 2))); void f14(int i, int j, int *k) __attribute__((ownership_holds(foo, 3))) __attribute__((ownership_takes(foo, 3))); // expected-error {{'ownership_takes' and 'ownership_holds' attributes are not compatible}} -void f15(int, int) +void *f15(int, int) __attribute__((ownership_returns(foo, 1))) // expected-error {{'ownership_returns' attribute index does not match; here it is 1}} __attribute__((ownership_returns(foo, 2))); // expected-note {{declared with index 2 here}} void f16(int *i, int *j) __attribute__((ownership_holds(foo, 1))) __attribute__((ownership_holds(foo, 1))); // OK, same index void f17(void*) __attribute__((ownership_takes(__, 1))); void f18() __attribute__((ownership_takes(foo, 1))); // expected-warning {{'ownership_takes' attribute only applies to non-K&R-style functions}} + +int f19(void *) + __attribute__((ownership_takes(foo, 1))) // expected-error {{'ownership_takes' attribute class does not match; here it is 'foo'}} + __attribute__((ownership_takes(foo1, 1))); // expected-note {{declared with class 'foo1' here}} + +void f20(void) __attribute__((ownership_returns(foo))); // expected-error {{'ownership_returns' attribute only applies to functions that return a pointer}} +int f21(void) __attribute__((ownership_returns(foo))); // expected-error {{'ownership_returns' attribute only applies to functions that return a pointer}} diff --git a/clang/test/Sema/attr-ownership.cpp b/clang/test/Sema/attr-ownership.cpp index 7381285e2da48..0626efa5aaf9a 100644 --- a/clang/test/Sema/attr-ownership.cpp +++ b/clang/test/Sema/attr-ownership.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only class C { - void f(int, int) - __attribute__((ownership_returns(foo, 2))) // expected-error {{'ownership_returns' attribute index does not match; here it is 2}} - __attribute__((ownership_returns(foo, 3))); // expected-note {{declared with index 3 here}} + void *f(int, int) + __attribute__((ownership_returns(foo, 2))) // expected-error {{'ownership_returns' attribute index does not match; here it is 2}} + __attribute__((ownership_returns(foo, 3))); // expected-note {{declared with index 3 here}} }; diff --git a/clang/test/Sema/builtin-cpu-supports.c b/clang/test/Sema/builtin-cpu-supports.c index 51ee9661807f8..4dace25b42a97 100644 --- a/clang/test/Sema/builtin-cpu-supports.c +++ b/clang/test/Sema/builtin-cpu-supports.c @@ -1,5 +1,10 @@ // RUN: %clang_cc1 -fsyntax-only -triple x86_64-pc-linux-gnu -verify %s // RUN: %clang_cc1 -fsyntax-only -triple aarch64-linux-gnu -verify %s +// RUN: %clang_cc1 -fsyntax-only -triple riscv32-linux-gnu -verify %s +// RUN: %clang_cc1 -fsyntax-only -triple riscv64-linux-gnu -verify %s +// RUN: %clang_cc1 -fsyntax-only -triple powerpc64le-unknown-linux -verify %s +// RUN: %clang_cc1 -fsyntax-only -triple powerpc64-unknown-aix7.2.0.0 -verify %s +// RUN: %clang_cc1 -fsyntax-only -triple powerpc-unknown-aix7.2.0.0 -verify %s extern void a(const char *); @@ -26,7 +31,9 @@ int main(void) { (void)__builtin_cpu_supports("x86-64-v3"); (void)__builtin_cpu_supports("x86-64-v4"); (void)__builtin_cpu_supports("x86-64-v5"); // expected-warning {{invalid cpu feature string for builtin}} -#else +#endif + +#ifdef __aarch64__ if (__builtin_cpu_supports("neon")) // expected-warning {{invalid cpu feature string for builtin}} a("vsx"); @@ -36,5 +43,21 @@ int main(void) { __builtin_cpu_init(); // expected-error {{builtin is not supported on this target}} #endif +#ifdef __riscv + if (__builtin_cpu_supports("garbage")) // expected-warning {{invalid cpu feature string for builtin}} + a("vsx"); +#endif + +#ifdef __powerpc__ + if (__builtin_cpu_is("garbage")) // expected-error {{invalid cpu name for builtin}} + a("vsx"); + + if (__builtin_cpu_is("power3")) // expected-error {{invalid cpu name for builtin}} + a("vsx"); + + if (__builtin_cpu_supports("garbage")) // expected-warning {{invalid cpu feature string for builtin}} + a("vsx"); +#endif + return 0; } diff --git a/clang/test/Sema/constant-builtins-2.c b/clang/test/Sema/constant-builtins-2.c index 00767267cd6c2..37b63cf4f6b32 100644 --- a/clang/test/Sema/constant-builtins-2.c +++ b/clang/test/Sema/constant-builtins-2.c @@ -265,10 +265,8 @@ char clz52[__builtin_clzg((unsigned __int128)0x1) == BITSIZE(__int128) - 1 ? 1 : char clz53[__builtin_clzg((unsigned __int128)0x1, 42) == BITSIZE(__int128) - 1 ? 1 : -1]; char clz54[__builtin_clzg((unsigned __int128)0xf) == BITSIZE(__int128) - 4 ? 1 : -1]; char clz55[__builtin_clzg((unsigned __int128)0xf, 42) == BITSIZE(__int128) - 4 ? 1 : -1]; -char clz56[__builtin_clzg((unsigned __int128)(1 << (BITSIZE(__int128) - 1))) == 0 ? 1 : -1]; // expected-warning {{variable length array folded to constant array as an extension}} - // expected-note@-1 {{shift count 127 >= width of type 'int' (32 bits)}} -char clz57[__builtin_clzg((unsigned __int128)(1 << (BITSIZE(__int128) - 1)), 42) == 0 ? 1 : -1]; // expected-warning {{variable length array folded to constant array as an extension}} - // expected-note@-1 {{shift count 127 >= width of type 'int' (32 bits)}} +char clz56[__builtin_clzg((unsigned __int128)(1 << (BITSIZE(__int128) - 1))) == 0 ? 1 : -1]; // expected-error {{variable length array declaration not allowed at file scope}} +char clz57[__builtin_clzg((unsigned __int128)(1 << (BITSIZE(__int128) - 1)), 42) == 0 ? 1 : -1]; // expected-error {{variable length array declaration not allowed at file scope}} #endif int clz58 = __builtin_clzg((unsigned _BitInt(128))0); // expected-error {{not a compile-time constant}} char clz59[__builtin_clzg((unsigned _BitInt(128))0, 42) == 42 ? 1 : -1]; @@ -276,10 +274,8 @@ char clz60[__builtin_clzg((unsigned _BitInt(128))0x1) == BITSIZE(_BitInt(128)) - char clz61[__builtin_clzg((unsigned _BitInt(128))0x1, 42) == BITSIZE(_BitInt(128)) - 1 ? 1 : -1]; char clz62[__builtin_clzg((unsigned _BitInt(128))0xf) == BITSIZE(_BitInt(128)) - 4 ? 1 : -1]; char clz63[__builtin_clzg((unsigned _BitInt(128))0xf, 42) == BITSIZE(_BitInt(128)) - 4 ? 1 : -1]; -char clz64[__builtin_clzg((unsigned _BitInt(128))(1 << (BITSIZE(_BitInt(128)) - 1))) == 0 ? 1 : -1]; // expected-warning {{variable length array folded to constant array as an extension}} - // expected-note@-1 {{shift count 127 >= width of type 'int' (32 bits)}} -char clz65[__builtin_clzg((unsigned _BitInt(128))(1 << (BITSIZE(_BitInt(128)) - 1)), 42) == 0 ? 1 : -1]; // expected-warning {{variable length array folded to constant array as an extension}} - // expected-note@-1 {{shift count 127 >= width of type 'int' (32 bits)}} +char clz64[__builtin_clzg((unsigned _BitInt(128))(1 << (BITSIZE(_BitInt(128)) - 1))) == 0 ? 1 : -1]; // expected-error {{variable length array declaration not allowed at file scope}} +char clz65[__builtin_clzg((unsigned _BitInt(128))(1 << (BITSIZE(_BitInt(128)) - 1)), 42) == 0 ? 1 : -1]; // expected-error {{variable length array declaration not allowed at file scope}} char ctz1[__builtin_ctz(1) == 0 ? 1 : -1]; char ctz2[__builtin_ctz(8) == 3 ? 1 : -1]; diff --git a/clang/test/Sema/patchable-function-entry-attr.cpp b/clang/test/Sema/patchable-function-entry-attr.cpp index 9134c851da588..bd4d57a7e3093 100644 --- a/clang/test/Sema/patchable-function-entry-attr.cpp +++ b/clang/test/Sema/patchable-function-entry-attr.cpp @@ -6,9 +6,14 @@ // RUN: %clang_cc1 -triple loongarch64 -fsyntax-only -verify=silence %s // RUN: %clang_cc1 -triple riscv32 -fsyntax-only -verify=silence %s // RUN: %clang_cc1 -triple riscv64 -fsyntax-only -verify=silence %s +// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fsyntax-only -verify=silence %s +// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -fsyntax-only -verify=silence %s // RUN: %clang_cc1 -triple ppc64le -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -fsyntax-only -verify=AIX %s +// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -fsyntax-only -verify=AIX %s // silence-no-diagnostics +// AIX-error@+2 {{'patchable_function_entry' attribute is not yet supported on AIX}} // expected-warning@+1 {{unknown attribute 'patchable_function_entry' ignored}} [[gnu::patchable_function_entry(0)]] void f(); diff --git a/clang/test/Sema/ptrauth-indirect-goto.c b/clang/test/Sema/ptrauth-indirect-goto.c new file mode 100644 index 0000000000000..7304f5c30a117 --- /dev/null +++ b/clang/test/Sema/ptrauth-indirect-goto.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple arm64e-apple-darwin -fsyntax-only -verify %s -fptrauth-indirect-gotos +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fsyntax-only -verify %s -fptrauth-indirect-gotos + +int f() { + static void *addrs[] = { &&l1, &&l2 }; + + static int diffs[] = { + &&l1 - &&l1, // expected-error{{subtraction of address-of-label expressions is not supported with ptrauth indirect gotos}} + &&l1 - &&l2 // expected-error{{subtraction of address-of-label expressions is not supported with ptrauth indirect gotos}} + }; + + int diff_32 = &&l1 - &&l2; // expected-error{{subtraction of address-of-label expressions is not supported with ptrauth indirect gotos}} + goto *(&&l1 + diff_32); // expected-error{{addition of address-of-label expressions is not supported with ptrauth indirect gotos}} + +l1: + return 0; +l2: + return 1; +} diff --git a/clang/test/Sema/ptrauth-intrinsics-macro.c b/clang/test/Sema/ptrauth-intrinsics-macro.c index f76f677315dd3..adbb71a9d6e50 100644 --- a/clang/test/Sema/ptrauth-intrinsics-macro.c +++ b/clang/test/Sema/ptrauth-intrinsics-macro.c @@ -38,6 +38,11 @@ void test_string_discriminator(int *dp) { (void)t0; } +void test_type_discriminator(int *dp) { + ptrauth_extra_data_t t0 = ptrauth_type_discriminator(int (*)(int)); + (void)t0; +} + void test_sign_constant(int *dp) { dp = ptrauth_sign_constant(&dv, VALID_DATA_KEY, 0); } diff --git a/clang/test/Sema/switch.c b/clang/test/Sema/switch.c index 69b34f96820d3..6e912d02d6cc7 100644 --- a/clang/test/Sema/switch.c +++ b/clang/test/Sema/switch.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wswitch-enum -Wcovered-switch-default -triple x86_64-linux-gnu %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wswitch-enum -Wcovered-switch-default -triple x86_64-linux-gnu %s -fexperimental-new-constant-interpreter void f (int z) { while (z) { default: z--; // expected-error {{statement not in switch}} diff --git a/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp b/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp index 03a432e05851d..357c9e5b64107 100644 --- a/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp +++ b/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp @@ -1,10 +1,11 @@ // RUN: %clang_cc1 -x c++ -verify=no-inf-no-nan \ -// RUN: -triple powerpc64le-unknown-unknown %s -menable-no-infs \ -// RUN: -menable-no-nans -std=c++23 +// RUN: -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-infs -menable-no-nans -std=c++23 // RUN: %clang_cc1 -x c++ -verify=no-inf-no-nan \ -// RUN: -triple powerpc64le-unknown-unknown %s -menable-no-infs \ -// RUN: -menable-no-nans -funsafe-math-optimizations -std=c++23 +// RUN: -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-infs -menable-no-nans -funsafe-math-optimizations \ +// RUN: -std=c++23 // RUN: %clang_cc1 -x c++ -verify=no-fast -triple powerpc64le-unknown-unknown \ // RUN: %s -std=c++23 @@ -87,11 +88,15 @@ class numeric_limits { int compareit(float a, float b) { volatile int i, j, k, l, m, n, o, p; -// no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+4 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+3 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} // no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} i = a == INFINITY; -// no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+4 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+3 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} // no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} j = INFINITY == a; @@ -107,11 +112,15 @@ int compareit(float a, float b) { // no-nan-warning@+1 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} j = NAN == a; -// no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+4 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+3 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} // no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} j = INFINITY <= a; -// no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+4 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+3 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} // no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} j = INFINITY < a; @@ -192,7 +201,9 @@ int compareit(float a, float b) { // no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} j = isunorderedf(a, NAN); -// no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+4 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+3 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} // no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} j = isunorderedf(a, INFINITY); @@ -204,9 +215,11 @@ int compareit(float a, float b) { // no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} i = std::isunordered(a, NAN); -// no-inf-no-nan-warning@+4 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} -// no-inf-no-nan-warning@+3 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} -// no-inf-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+6 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+5 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+4 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+3 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} // no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} i = std::isunordered(a, INFINITY); diff --git a/clang/test/Sema/warn-infinity-nan-disabled-win.cpp b/clang/test/Sema/warn-infinity-nan-disabled-win.cpp index 51f9d325619ba..ee4eb33a16e44 100644 --- a/clang/test/Sema/warn-infinity-nan-disabled-win.cpp +++ b/clang/test/Sema/warn-infinity-nan-disabled-win.cpp @@ -6,8 +6,9 @@ // RUN: -menable-no-nans -std=c++23 // RUN: %clang_cc1 -x c++ -verify=no-inf-no-nan \ -// RUN: -triple powerpc64le-unknown-unknown %s -menable-no-infs \ -// RUN: -menable-no-nans -funsafe-math-optimizations -std=c++23 +// RUN: -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-infs -menable-no-nans -funsafe-math-optimizations \ +// RUN: -std=c++23 // RUN: %clang_cc1 -x c++ -verify=no-fast -triple powerpc64le-unknown-unknown \ // RUN: %s -std=c++23 diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg-disabled.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg-disabled.cpp index 60b8f3ddedcd1..d1266027bdd34 100644 --- a/clang/test/Sema/warn-lifetime-analysis-nocfg-disabled.cpp +++ b/clang/test/Sema/warn-lifetime-analysis-nocfg-disabled.cpp @@ -21,3 +21,7 @@ MyIntPointer g() { MyIntOwner o; return o; // No warning, it is disabled. } + +void h(MyIntPointer p) { + p = MyIntOwner(); // No warning, it is disabled. +} diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp index b3ca173c1fdbc..09dfb2b5d96a8 100644 --- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp +++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp @@ -120,11 +120,13 @@ MyLongPointerFromConversion global2; void initLocalGslPtrWithTempOwner() { MyIntPointer p = MyIntOwner{}; // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} - p = MyIntOwner{}; // TODO ? - global = MyIntOwner{}; // TODO ? + MyIntPointer pp = p = MyIntOwner{}; // expected-warning {{object backing the pointer p will be}} + p = MyIntOwner{}; // expected-warning {{object backing the pointer p }} + pp = p; // no warning + global = MyIntOwner{}; // expected-warning {{object backing the pointer global }} MyLongPointerFromConversion p2 = MyLongOwnerWithConversion{}; // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} - p2 = MyLongOwnerWithConversion{}; // TODO ? - global2 = MyLongOwnerWithConversion{}; // TODO ? + p2 = MyLongOwnerWithConversion{}; // expected-warning {{object backing the pointer p2 }} + global2 = MyLongOwnerWithConversion{}; // expected-warning {{object backing the pointer global2 }} } namespace __gnu_cxx { @@ -170,6 +172,7 @@ struct basic_string_view { basic_string_view(const T *); const T *begin() const; }; +using string_view = basic_string_view; template struct iter { iter& operator-=(int); @@ -188,7 +191,7 @@ struct basic_string { operator basic_string_view () const; using const_iterator = iter; }; - +using string = basic_string; template struct unique_ptr { @@ -346,6 +349,12 @@ void handleTernaryOperator(bool cond) { std::basic_string_view v = cond ? def : ""; // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} } +std::string operator+(std::string_view s1, std::string_view s2); +void danglingStringviewAssignment(std::string_view a1, std::string_view a2) { + a1 = std::string(); // expected-warning {{object backing}} + a2 = a1 + a1; // expected-warning {{object backing}} +} + std::reference_wrapper danglingPtrFromNonOwnerLocal() { int i = 5; return i; // TODO diff --git a/clang/test/Sema/x86-builtin-palignr.c b/clang/test/Sema/x86-builtin-palignr.c index e055cbb70e9e5..33a963c15b00d 100644 --- a/clang/test/Sema/x86-builtin-palignr.c +++ b/clang/test/Sema/x86-builtin-palignr.c @@ -4,5 +4,5 @@ #include __m64 test1(__m64 a, __m64 b, int c) { - return _mm_alignr_pi8(a, b, c); // expected-error {{argument to '__builtin_ia32_palignr' must be a constant integer}} + return _mm_alignr_pi8(a, b, c); // expected-error {{argument to '__builtin_ia32_psrldqi128_byteshift' must be a constant integer}} } diff --git a/clang/test/SemaCUDA/attr-noconvergent.cu b/clang/test/SemaCUDA/attr-noconvergent.cu new file mode 100644 index 0000000000000..0c051fdde4379 --- /dev/null +++ b/clang/test/SemaCUDA/attr-noconvergent.cu @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fsyntax-only -fcuda-is-device -verify %s + +#include "Inputs/cuda.h" + +__device__ float f0(float) __attribute__((noconvergent)); +__device__ __attribute__((noconvergent)) float f1(float); +[[clang::noconvergent]] __device__ float f2(float); + +__device__ [[clang::noconvergent(1)]] float f3(float); +// expected-error@-1 {{'noconvergent' attribute takes no arguments}} + +__device__ [[clang::noconvergent]] float g0; +// expected-warning@-1 {{'noconvergent' attribute only applies to functions and statements}} + +__device__ __attribute__((convergent)) __attribute__((noconvergent)) float f4(float); +// expected-error@-1 {{'noconvergent' and 'convergent' attributes are not compatible}} +// expected-note@-2 {{conflicting attribute is here}} + +__device__ [[clang::noconvergent]] float f5(float); +__device__ [[clang::convergent]] float f5(float); +// expected-error@-1 {{'convergent' and 'noconvergent' attributes are not compatible}} +// expected-note@-3 {{conflicting attribute is here}} + +__device__ float f5(float x) { + [[clang::noconvergent]] float y; +// expected-warning@-1 {{'noconvergent' attribute only applies to functions and statements}} + + float z; + + [[clang::noconvergent]] z = 1; +// expected-warning@-1 {{'noconvergent' attribute is ignored because there exists no call expression inside the statement}} + + [[clang::noconvergent]] z = f0(x); +} diff --git a/clang/test/SemaCXX/GH82167.cpp b/clang/test/SemaCXX/GH82167.cpp new file mode 100644 index 0000000000000..033331b82c5d4 --- /dev/null +++ b/clang/test/SemaCXX/GH82167.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++23 -fsyntax-only -verify -xobjective-c++ %s +// expected-no-diagnostics + +namespace t1 { + struct array { + char elems[2]; + }; + + template struct Literal { + array arr; + constexpr Literal() : arr("") {} + }; + + template struct Literal<0>; +} // namespace t1 + +namespace t2 { + struct array { + char elems[2]; + }; + + template struct Literal { + array arr; + constexpr Literal() : arr(@encode(int)) {} + }; + + template struct Literal<0>; +} // namespace t2 diff --git a/clang/test/SemaCXX/attr-lifetimebound.cpp b/clang/test/SemaCXX/attr-lifetimebound.cpp index 70bc545c07bd9..7db0a4d64d259 100644 --- a/clang/test/SemaCXX/attr-lifetimebound.cpp +++ b/clang/test/SemaCXX/attr-lifetimebound.cpp @@ -47,6 +47,31 @@ namespace usage_ok { q = A(); // expected-warning {{object backing the pointer q will be destroyed at the end of the full-expression}} r = A(1); // expected-warning {{object backing the pointer r will be destroyed at the end of the full-expression}} } + + struct FieldCheck { + struct Set { + int a; + }; + struct Pair { + const int& a; + int b; + Set c; + int * d; + }; + Pair p; + FieldCheck(const int& a): p(a){} + Pair& getR() [[clang::lifetimebound]] { return p; } + Pair* getP() [[clang::lifetimebound]] { return &p; } + Pair* getNoLB() { return &p; } + }; + void test_field_access() { + int x = 0; + const int& a = FieldCheck{x}.getR().a; + const int& b = FieldCheck{x}.getP()->b; // expected-warning {{temporary bound to local reference 'b' will be destroyed at the end of the full-expression}} + const int& c = FieldCheck{x}.getP()->c.a; // expected-warning {{temporary bound to local reference 'c' will be destroyed at the end of the full-expression}} + const int& d = FieldCheck{x}.getNoLB()->c.a; + const int* e = FieldCheck{x}.getR().d; + } } # 1 "" 1 3 @@ -239,3 +264,4 @@ namespace move_forward_et_al_examples { S X; S *AddressOfOk = std::addressof(X); } // namespace move_forward_et_al_examples + diff --git a/clang/test/SemaCXX/builtin_vectorelements.cpp b/clang/test/SemaCXX/builtin_vectorelements.cpp index 59ff09ac72e42..b23675ea0ac6a 100644 --- a/clang/test/SemaCXX/builtin_vectorelements.cpp +++ b/clang/test/SemaCXX/builtin_vectorelements.cpp @@ -1,7 +1,9 @@ // RUN: %clang_cc1 -triple x86_64 -std=c++20 -fsyntax-only -verify -disable-llvm-passes %s +// RUN: %clang_cc1 -triple x86_64 -std=c++20 -fsyntax-only -verify -disable-llvm-passes -fexperimental-new-constant-interpreter %s // REQUIRES: aarch64-registered-target // RUN: %clang_cc1 -triple aarch64 -target-feature +sve -std=c++20 -fsyntax-only -verify -disable-llvm-passes %s +// RUN: %clang_cc1 -triple aarch64 -target-feature +sve -std=c++20 -fsyntax-only -verify -disable-llvm-passes -fexperimental-new-constant-interpreter %s template using VecT __attribute__((vector_size(16))) = T; diff --git a/clang/test/SemaCXX/class.cpp b/clang/test/SemaCXX/class.cpp index f874b7be2b70e..2f59544e7f36c 100644 --- a/clang/test/SemaCXX/class.cpp +++ b/clang/test/SemaCXX/class.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wc++11-compat %s +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx11 -Wc++11-compat %s // RUN: %clang_cc1 -fsyntax-only -verify -Wc++11-compat %s -std=c++98 class C { public: @@ -55,6 +55,13 @@ class C { // expected-error@-2 {{static const volatile data member must be initialized out of line}} #endif static const E evi = 0; + static const int overflow = 1000000*1000000; // cxx11-error {{in-class initializer for static data member is not a constant expression}} + // expected-warning@-1 {{overflow in expression}} + static const int overflow_shift = 1<<32; // cxx11-error {{in-class initializer for static data member is not a constant expression}} + static const int overflow_shift2 = 1>>32; // cxx11-error {{in-class initializer for static data member is not a constant expression}} + static const int overflow_shift3 = 1<<-1; // cxx11-error {{in-class initializer for static data member is not a constant expression}} + static const int overflow_shift4 = 1<<-1; // cxx11-error {{in-class initializer for static data member is not a constant expression}} + static const int overflow_shift5 = -1<<1; // cxx11-error {{in-class initializer for static data member is not a constant expression}} void m() { sx = 0; diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index efb391ba0922d..6df8a4740d6cc 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -std=c++23 -isystem %S/Inputs -fsyntax-only -verify=expected,cxx20_23,cxx23 -triple x86_64-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -Wno-c99-designator -fcxx-exceptions -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion -// RUN: %clang_cc1 -std=c++20 -isystem %S/Inputs -fsyntax-only -verify=expected,cxx11_20,cxx20_23 -triple x86_64-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -Wno-c99-designator -fcxx-exceptions -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion -// RUN: %clang_cc1 -std=c++11 -isystem %S/Inputs -fsyntax-only -verify=expected,cxx11_20,cxx11 -triple x86_64-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -Wno-c99-designator -fcxx-exceptions -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion +// RUN: %clang_cc1 -std=c++23 -isystem %S/Inputs -fsyntax-only -verify=expected,cxx20_23,cxx23 -triple x86_64-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -Wno-c99-designator -fcxx-exceptions -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion +// RUN: %clang_cc1 -std=c++20 -isystem %S/Inputs -fsyntax-only -verify=expected,cxx11_20,cxx20_23,pre-cxx23 -triple x86_64-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -Wno-c99-designator -fcxx-exceptions -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion +// RUN: %clang_cc1 -std=c++11 -isystem %S/Inputs -fsyntax-only -verify=expected,cxx11_20,cxx11,pre-cxx23 -triple x86_64-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -Wno-c99-designator -fcxx-exceptions -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion namespace StaticAssertFoldTest { @@ -1011,10 +1011,12 @@ constexpr bool b(int n) { return &n; } static_assert(b(0), ""); struct NonLiteral { - NonLiteral(); + NonLiteral(); // cxx23-note {{declared here}} int f(); }; -constexpr int k = NonLiteral().f(); // expected-error {{constant expression}} expected-note {{non-literal type 'NonLiteral'}} +constexpr int k = NonLiteral().f(); // expected-error {{constant expression}} \ + // pre-cxx23-note {{non-literal type 'NonLiteral'}} \ + // cxx23-note {{non-constexpr constructor 'NonLiteral' cannot be used in a constant expression}} } @@ -1270,8 +1272,10 @@ static_assert(makeComplexWrap(1,0) != complex(0, 1), ""); namespace PR11595 { struct A { constexpr bool operator==(int x) const { return true; } }; - struct B { B(); A& x; }; - static_assert(B().x == 3, ""); // expected-error {{constant expression}} expected-note {{non-literal type 'B' cannot be used in a constant expression}} + struct B { B(); A& x; }; // cxx23-note {{declared here}} + static_assert(B().x == 3, ""); // expected-error {{constant expression}} \ + // pre-cxx23-note {{non-literal type 'B' cannot be used in a constant expression}} \ + // cxx23-note {{non-constexpr constructor 'B' cannot be used in a constant expression}} constexpr bool f(int k) { // cxx11_20-error {{constexpr function never produces a constant expression}} return B().x == k; // cxx11_20-note {{non-literal type 'B' cannot be used in a constant expression}} diff --git a/clang/test/SemaCXX/constant-expression-cxx2b.cpp b/clang/test/SemaCXX/constant-expression-cxx2b.cpp index 2519839b7ac57..42b3f81cc713d 100644 --- a/clang/test/SemaCXX/constant-expression-cxx2b.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx2b.cpp @@ -3,7 +3,7 @@ struct NonLiteral { // cxx2a-note {{'NonLiteral' is not literal}} \ // cxx23-note 2{{'NonLiteral' is not literal}} - NonLiteral() {} + NonLiteral() {} // cxx23-note 2{{declared here}} }; struct Constexpr{}; @@ -165,9 +165,9 @@ int test_in_lambdas() { auto non_literal = [](bool b) constexpr { if (!b) - NonLiteral n; // cxx23-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \ - // cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++23}} \ - // cxx23-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++23}} + NonLiteral n; // cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++23}} \ + // cxx23-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++23}} \ + // cxx23-note {{non-constexpr constructor 'NonLiteral' cannot be used in a constant expression}} return 0; }; @@ -217,7 +217,7 @@ int test_lambdas_implicitly_constexpr() { auto non_literal = [](bool b) { // cxx2a-note 2{{declared here}} if (b) - NonLiteral n; // cxx23-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} + NonLiteral n; // cxx23-note {{non-constexpr constructor 'NonLiteral' cannot be used in a constant expression}} return 0; }; diff --git a/clang/test/SemaCXX/constexpr-subobj-initialization.cpp b/clang/test/SemaCXX/constexpr-subobj-initialization.cpp index cd096a9270937..f0252df1e2ce1 100644 --- a/clang/test/SemaCXX/constexpr-subobj-initialization.cpp +++ b/clang/test/SemaCXX/constexpr-subobj-initialization.cpp @@ -1,11 +1,12 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -fexperimental-new-constant-interpreter %s namespace baseclass_uninit { struct DelBase { constexpr DelBase() = delete; // expected-note {{'DelBase' has been explicitly marked deleted here}} }; -struct Foo : DelBase { // expected-note 2{{constructor of base class 'DelBase' is not called}} +struct Foo : DelBase { // expected-note-re 2{{constructor of base class '{{.*}}DelBase' is not called}} constexpr Foo() {}; // expected-error {{call to deleted constructor of 'DelBase'}} }; constexpr Foo f; // expected-error {{must be initialized by a constant expression}} @@ -15,13 +16,13 @@ struct Bar : Foo { constexpr Bar bar; // expected-error {{must be initialized by a constant expression}} struct Base {}; -struct A : Base { // expected-note {{constructor of base class 'Base' is not called}} +struct A : Base { // expected-note-re {{constructor of base class '{{.*}}Base' is not called}} constexpr A() : value() {} // expected-error {{member initializer 'value' does not name a non-static data member or base class}} }; constexpr A a; // expected-error {{must be initialized by a constant expression}} -struct B : Base { // expected-note {{constructor of base class 'Base' is not called}} +struct B : Base { // expected-note-re {{constructor of base class '{{.*}}Base' is not called}} constexpr B() : {} // expected-error {{expected class member or base class name}} }; diff --git a/clang/test/SemaCXX/cxx-deprecated.cpp b/clang/test/SemaCXX/cxx-deprecated.cpp index 81eb07608300d..d7de609d58cdd 100644 --- a/clang/test/SemaCXX/cxx-deprecated.cpp +++ b/clang/test/SemaCXX/cxx-deprecated.cpp @@ -36,4 +36,13 @@ template // expected-warning@-1 {{'C' is deprecated}} // expected-note@#C {{'C' has been explicitly marked deprecated here}} void f(); + +namespace GH98164 { +template +auto b() = delete; // #b + +decltype(b<0>()) x; +// expected-error@-1 {{call to deleted function 'b'}} +// expected-note@#b {{candidate function [with $0 = 0] has been explicitly deleted}} +} // namespace GH98164 } // namespace cxx20_concept diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp index 5e189b758c61e..eafadb07b29e1 100644 --- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp +++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp @@ -9,12 +9,12 @@ #endif class A { - template CONST T wrong; // expected-error {{member 'wrong' declared as a template}} - template CONST T wrong_init = 5; // expected-error {{member 'wrong_init' declared as a template}} + template CONST T wrong; // expected-error {{non-static data member 'wrong' cannot be declared as a template}} + template CONST T wrong_init = 5; // expected-error {{non-static data member 'wrong_init' cannot be declared as a template}} template static CONST T right = T(100); template static CONST T right = 5; - template CONST int right; // expected-error {{member 'right' declared as a template}} - template CONST float right = 5; // expected-error {{member 'right' declared as a template}} + template CONST int right; // expected-error {{non-static data member 'right' cannot be declared as a template}} + template CONST float right = 5; // expected-error {{non-static data member 'right' cannot be declared as a template}} #ifdef PRECXX11 // expected-warning@-2 {{in-class initializer for static data member of type 'const float' is a GNU extension}} #else @@ -161,14 +161,14 @@ namespace non_const_init { #ifndef PRECXX11 namespace constexpred { class A { - template constexpr T wrong; // expected-error {{member 'wrong' declared as a template}} + template constexpr T wrong; // expected-error {{non-static data member 'wrong' cannot be declared as a template}} // expected-error@-1 {{declaration of constexpr static data member 'wrong' requires an initializer}} - template constexpr T wrong_init = 5; // expected-error {{member 'wrong_init' declared as a template}} + template constexpr T wrong_init = 5; // expected-error {{non-static data member 'wrong_init' cannot be declared as a template}} template static constexpr T right = T(100); template static constexpr T right = 5; - template constexpr int right; // expected-error {{member 'right' declared as a template}} + template constexpr int right; // expected-error {{non-static data member 'right' cannot be declared as a template}} // expected-error@-1 {{declaration of constexpr static data member 'right' requires an initializer}} - template constexpr float right = 5; // expected-error {{member 'right' declared as a template}} + template constexpr float right = 5; // expected-error {{non-static data member 'right' cannot be declared as a template}} template<> constexpr int right = 7; template<> constexpr float right; // expected-error {{declaration of constexpr static data member 'right' requires an initializer}} template static constexpr int right; // expected-error {{expected '<' after 'template'}} diff --git a/clang/test/SemaCXX/cxx1z-decomposition.cpp b/clang/test/SemaCXX/cxx1z-decomposition.cpp index 305a9ac2ebc24..19c730303625e 100644 --- a/clang/test/SemaCXX/cxx1z-decomposition.cpp +++ b/clang/test/SemaCXX/cxx1z-decomposition.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -std=c++17 -Wc++20-extensions -verify=expected %s // RUN: %clang_cc1 -std=c++20 -Wpre-c++20-compat -verify=expected %s +// RUN: %clang_cc1 -std=c++20 -Wpre-c++20-compat -fexperimental-new-constant-interpreter -verify=expected %s void use_from_own_init() { auto [a] = a; // expected-error {{binding 'a' cannot appear in the initializer of its own decomposition declaration}} diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp index 2193be03ad9a3..5392573fcdb9d 100644 --- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp +++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp @@ -110,8 +110,8 @@ struct Foo { template using Bar = Foo; // expected-note {{candidate template ignored: couldn't infer template argument 'X'}} \ - // expected-note {{implicit deduction guide declared as 'template requires __is_deducible(test9::Bar, Foo) Bar(Foo) -> Foo'}} \ - // expected-note {{implicit deduction guide declared as 'template requires __is_deducible(test9::Bar, Foo) Bar(const type-parameter-0-0 (&)[sizeof(type-parameter-0-0)]) -> Foo'}} \ + // expected-note {{implicit deduction guide declared as 'template requires __is_deducible(test9::Bar, Foo) Bar(Foo) -> Foo'}} \ + // expected-note {{implicit deduction guide declared as 'template requires __is_deducible(test9::Bar, Foo) Bar(const X (&)[sizeof(X)]) -> Foo'}} \ // expected-note {{candidate template ignored: constraints not satisfied [with X = int]}} \ // expected-note {{cannot deduce template arguments for 'Bar' from 'Foo'}} @@ -138,13 +138,13 @@ namespace test11 { struct A {}; template struct Foo { T c; }; template -using AFoo = Foo; // expected-note {{candidate template ignored: could not match 'Foo' against 'int'}} \ - // expected-note {{implicit deduction guide declared as 'template requires __is_deducible(test11::AFoo, Foo) AFoo(Foo) -> Foo'}} \ +using AFoo = Foo; // expected-note {{candidate template ignored: could not match 'Foo' against 'int'}} \ + // expected-note {{implicit deduction guide declared as 'template requires __is_deducible(test11::AFoo, Foo) AFoo(Foo) -> Foo'}} \ // expected-note {{candidate template ignored: constraints not satisfied [with Y = int]}} \ // expected-note {{cannot deduce template arguments for 'AFoo' from 'Foo'}} \ - // expected-note {{implicit deduction guide declared as 'template requires __is_deducible(test11::AFoo, Foo) AFoo(type-parameter-0-0) -> Foo'}} \ + // expected-note {{implicit deduction guide declared as 'template requires __is_deducible(test11::AFoo, Foo) AFoo(Y) -> Foo'}} \ // expected-note {{candidate function template not viable: requires 0 arguments, but 1 was provided}} \ - // expected-note {{implicit deduction guide declared as 'template requires __is_deducible(test11::AFoo, Foo) AFoo() -> Foo'}} + // expected-note {{implicit deduction guide declared as 'template requires __is_deducible(test11::AFoo, Foo) AFoo() -> Foo'}} AFoo s = {1}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'AFoo'}} } // namespace test11 @@ -211,9 +211,9 @@ template concept False = false; template using BFoo = AFoo; // expected-note {{candidate template ignored: constraints not satisfied [with V = int]}} \ // expected-note {{cannot deduce template arguments for 'BFoo' from 'Foo'}} \ - // expected-note {{implicit deduction guide declared as 'template requires __is_deducible(AFoo, Foo) && __is_deducible(test15::BFoo, Foo) BFoo(type-parameter-0-0 *) -> Foo}} \ - // expected-note {{candidate template ignored: could not match 'Foo' against 'int *'}} \ - // expected-note {{template requires __is_deducible(AFoo, Foo) && __is_deducible(test15::BFoo, Foo) BFoo(Foo) -> Foo}} + // expected-note {{implicit deduction guide declared as 'template requires __is_deducible(AFoo, Foo) && __is_deducible(test15::BFoo, Foo) BFoo(V *) -> Foo}} \ + // expected-note {{candidate template ignored: could not match 'Foo' against 'int *'}} \ + // expected-note {{template requires __is_deducible(AFoo, Foo) && __is_deducible(test15::BFoo, Foo) BFoo(Foo) -> Foo}} int i = 0; AFoo a1(&i); // OK, deduce Foo @@ -263,12 +263,12 @@ template requires False // expected-note {{because 'int' does not Foo(T) -> Foo; template -using Bar = Foo; // expected-note {{could not match 'Foo' against 'int'}} \ - // expected-note {{implicit deduction guide declared as 'template requires __is_deducible(test18::Bar, Foo) Bar(Foo) -> Foo'}} \ +using Bar = Foo; // expected-note {{could not match 'Foo' against 'int'}} \ + // expected-note {{implicit deduction guide declared as 'template requires __is_deducible(test18::Bar, Foo) Bar(Foo) -> Foo'}} \ // expected-note {{candidate template ignored: constraints not satisfied}} \ - // expected-note {{implicit deduction guide declared as 'template requires False && __is_deducible(test18::Bar, Foo) Bar(type-parameter-0-0) -> Foo'}} \ + // expected-note {{implicit deduction guide declared as 'template requires False && __is_deducible(test18::Bar, Foo) Bar(T) -> Foo'}} \ // expected-note {{candidate function template not viable}} \ - // expected-note {{implicit deduction guide declared as 'template requires __is_deducible(test18::Bar, Foo) Bar() -> Foo'}} + // expected-note {{implicit deduction guide declared as 'template requires __is_deducible(test18::Bar, Foo) Bar() -> Foo'}} Bar s = {1}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments}} } // namespace test18 @@ -296,8 +296,8 @@ class Foo {}; // Verify that template template type parameter TTP is referenced/used in the // template arguments of the RHS. template typename TTP> -using Bar = Foo>; // expected-note {{candidate template ignored: could not match 'Foo>' against 'int'}} \ - // expected-note {{implicit deduction guide declared as 'template