diff --git a/.github/workflows/anza-main.yml b/.github/workflows/anza-main.yml new file mode 100644 index 0000000000000..9347138d2f0c8 --- /dev/null +++ b/.github/workflows/anza-main.yml @@ -0,0 +1,83 @@ +name: Test and check + +on: + push: + branches: + - 'solana-rustc/19.1-2024-12-03' + pull_request: + branches: + - 'solana-rustc/19.1-2024-12-03' + +jobs: + check-llvm: + name: Check LLVM + strategy: + matrix: + os: [ ubuntu-22.04, macos-latest ] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout source files + uses: actions/checkout@v6 + - name: Run CMake + working-directory: ./llvm + run: | + mkdir build + cd build + cmake -G Ninja -DCMAKE_BUILD_TYPE=Release .. + - name: Test LLVM + working-directory: ./llvm/build + run: ninja check-llvm + check-lld: + name: Check LLD + strategy: + matrix: + os: [ ubuntu-22.04, macos-latest ] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout source files + uses: actions/checkout@v6 + - name: Run CMake + run: | + cmake -G Ninja -DLLVM_ENABLE_ASSERTIONS=On \ + '-DLLVM_ENABLE_PROJECTS=lld' \ + -DLLVM_ENABLE_TERMINFO=Off -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_ENABLE_ZSTD=Off \ + -B build llvm + - name: Test LLD + working-directory: ./build + run: ninja check-lld + check-clang: + name: Check Clang + strategy: + matrix: + os: [ ubuntu-22.04, macos-latest ] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout source files + uses: actions/checkout@v6 + - name: Run CMake + run: | + cmake -G Ninja -DLLVM_ENABLE_ASSERTIONS=On \ + '-DLLVM_ENABLE_PROJECTS=clang' \ + -DLLVM_ENABLE_TERMINFO=Off -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_ENABLE_ZSTD=Off \ + -B build llvm + - name: Test LLD + working-directory: ./build + run: ninja check-clang + check-lldb: + name: Check LLDB + runs-on: ubuntu-22.04 + steps: + - name: Checkout source files + uses: actions/checkout@v6 + - name: Run CMake + run: | + cmake -G Ninja -DLLVM_ENABLE_ASSERTIONS=On \ + '-DLLVM_ENABLE_PROJECTS=clang;lldb' \ + -DLLVM_ENABLE_TERMINFO=Off -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_ENABLE_ZSTD=Off \ + -B build llvm + - name: Test LLDB + working-directory: ./build + run: ninja check-clang diff --git a/.github/workflows/lld-tests.yml b/.github/workflows/lld-tests.yml deleted file mode 100644 index dbb7af31c57db..0000000000000 --- a/.github/workflows/lld-tests.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: LLD Tests - -permissions: - contents: read - -on: - workflow_dispatch: - push: - ignore-forks: true - branches: - - 'release/**' - paths: - - 'lld/**' - - '.github/workflows/lld-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!llvm/**' - pull_request: - # ignore-forks: true - # branches: - # - 'release/**' - paths: - - 'lld/**' - - '.github/workflows/lld-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!llvm/**' - -concurrency: - # Skip intermediate builds: always. - # Cancel intermediate builds: only if it is a pull request build. - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} - -jobs: - check_lld: - # if: github.repository_owner == 'llvm' - name: Test lld - uses: ./.github/workflows/llvm-project-tests.yml - with: - build_target: check-lld - projects: lld diff --git a/.github/workflows/lldb-tests.yml b/.github/workflows/lldb-tests.yml deleted file mode 100644 index 6bb9721956258..0000000000000 --- a/.github/workflows/lldb-tests.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: lldb Tests - -permissions: - contents: read - -on: - workflow_dispatch: - push: - branches: - - 'release/**' - paths: - - 'lldb/**' - - '.github/workflows/lldb-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!clang/**' - - '!llvm/**' - pull_request: - branches: - - 'release/**' - paths: - - 'lldb/**' - - '.github/workflows/lldb-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!clang/**' - - '!llvm/**' - -concurrency: - # Skip intermediate builds: always. - # Cancel intermediate builds: only if it is a pull request build. - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} - -jobs: - build_lldb: - if: github.repository_owner == 'llvm' - name: Build lldb - uses: ./.github/workflows/llvm-project-tests.yml - with: - projects: clang;lldb diff --git a/.github/workflows/llvm-bugs.yml b/.github/workflows/llvm-bugs.yml deleted file mode 100644 index 3fee30f00b20e..0000000000000 --- a/.github/workflows/llvm-bugs.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: LLVM Bugs notifier - -permissions: - contents: read - issues: read - -on: - issues: - types: - - opened - -jobs: - auto-subscribe: - runs-on: ubuntu-22.04 - if: github.repository == 'llvm/llvm-project' - steps: - - uses: actions/setup-node@v4 - with: - node-version: 18 - check-latest: true - - run: npm install mailgun.js form-data - - name: Send notification - uses: actions/github-script@v6 - env: - MAILGUN_API_KEY: ${{ secrets.LLVM_BUGS_KEY }} - with: - script: | - const Mailgun = require('mailgun.js'); - const formData = require('form-data'); - - const mailgun = new Mailgun(formData); - const DOMAIN = 'email.llvm.org'; - - const mg = mailgun.client({ username: 'api', key: process.env.MAILGUN_API_KEY }); - - github.rest.issues.get({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo - }) - .then((issue) => { - const payload = { - author : issue.data.user.login, - issue : issue.data.number, - title : issue.data.title, - url : issue.data.html_url, - labels : issue.data.labels.map((label) => label.name), - assignee : issue.data.assignees.map((assignee) => assignee.login), - body : issue.data.body - }; - - const data = { - from: 'LLVM Bugs ', - to: 'llvm-bugs@lists.llvm.org', - subject: `[Bug ${issue.data.number}] ${issue.data.title}`, - template: 'new-github-issue', - 'o:tracking-clicks': 'no', - 'h:X-Mailgun-Variables': JSON.stringify(payload) - }; - - return mg.messages.create(DOMAIN, data); - }) - .then((msg) => console.log(msg)); diff --git a/.github/workflows/llvm-project-tests.yml b/.github/workflows/llvm-project-tests.yml deleted file mode 100644 index ff8c85de9c276..0000000000000 --- a/.github/workflows/llvm-project-tests.yml +++ /dev/null @@ -1,163 +0,0 @@ -name: LLVM Project Tests - -permissions: - contents: read - -on: - workflow_dispatch: - inputs: - build_target: - required: false - projects: - required: false - extra_cmake_args: - required: false - os_list: - required: false - default: '["ubuntu-22.04", "windows-2022", "macOS-13"]' - python_version: - required: false - type: string - default: '3.11' - workflow_call: - inputs: - build_target: - required: false - type: string - default: "all" - - projects: - required: true - type: string - - extra_cmake_args: - required: false - type: string - - os_list: - required: false - type: string - # Use windows-2019 due to: - # https://developercommunity.visualstudio.com/t/Prev-Issue---with-__assume-isnan-/1597317 - # Use ubuntu-22.04 rather than ubuntu-latest to match the ubuntu - # version in the CI container. Without this, setup-python tries - # to install a python version linked against a newer version of glibc. - # TODO(boomanaiden154): Bump the Ubuntu version once the version in the - # container is bumped. - default: '["ubuntu-22.04", "windows-2022", "macOS-13"]' - - python_version: - required: false - type: string - default: '3.11' - -concurrency: - # Skip intermediate builds: always. - # Cancel intermediate builds: only if it is a pull request build. - # If the group name here is the same as the group name in the workflow that includes - # this one, then the action will try to wait on itself and get stuck. - group: llvm-project-${{ github.workflow }}-${{ inputs.projects }}${{ github.ref }} - cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} - -jobs: - lit-tests: - name: Lit Tests - runs-on: ${{ matrix.os }} - container: - image: ${{(startsWith(matrix.os, 'ubuntu') && 'ghcr.io/llvm/ci-ubuntu-22.04:latest') || null}} - volumes: - - /mnt/:/mnt/ - strategy: - fail-fast: false - matrix: - os: - - ubuntu-22.04 - # Use windows-2019 due to: - # https://developercommunity.visualstudio.com/t/Prev-Issue---with-__assume-isnan-/1597317 - - windows-2022 - # We're using a specific version of macOS due to: - # https://github.com/actions/virtual-environments/issues/5900 - - macOS-latest - steps: - - name: Setup Windows - if: startsWith(matrix.os, 'windows') - uses: llvm/actions/setup-windows@main - with: - arch: amd64 - # On Windows, starting with win19/20220814.1, cmake choose the 32-bit - # python3.10.6 libraries instead of the 64-bit libraries when building - # lldb. Using this setup-python action to make 3.10 the default - # python fixes this. - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - name: Install Ninja - if: runner.os != 'Linux' - uses: llvm/actions/install-ninja@main - # actions/checkout deletes any existing files in the new git directory, - # so this needs to either run before ccache-action or it has to use - # clean: false. - - uses: actions/checkout@v4 - with: - fetch-depth: 250 - - name: Setup ccache - uses: hendrikmuhs/ccache-action@v1 - with: - # A full build of llvm, clang, lld, and lldb takes about 250MB - # of ccache space. There's not much reason to have more than this, - # because we usually won't need to save cache entries from older - # builds. Also, there is an overall 10GB cache limit, and each - # run creates a new cache entry so we want to ensure that we have - # enough cache space for all the tests to run at once and still - # fit under the 10 GB limit. - # Default to 2G to workaround: https://github.com/hendrikmuhs/ccache-action/issues/174 - max-size: 2G - key: ${{ matrix.os }} - variant: sccache - - name: Build and Test - if: "!startsWith(matrix.os, 'windows')" - env: - # Workaround for https://github.com/actions/virtual-environments/issues/5900. - # This should be a no-op for non-mac OSes - PKG_CONFIG_PATH: /usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig//12 - shell: bash - id: build-llvm - run: | - if [ "${{ runner.os }}" == "Linux" ]; then - builddir="/mnt/build/" - sudo mkdir -p $builddir - sudo chown gha $builddir - extra_cmake_args="-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang" - else - builddir="$(pwd)"/build - fi - if [ "${{ runner.os }}" == "macOS" ]; then - # Workaround test failure on some lld tests on MacOS - # https://github.com/llvm/llvm-project/issues/81967 - extra_cmake_args="-DLLVM_DISABLE_ASSEMBLY_FILES=ON" - fi - echo "llvm-builddir=$builddir" >> "$GITHUB_OUTPUT" - cmake -G Ninja \ - -B "$builddir" \ - -S llvm \ - -DLLVM_ENABLE_PROJECTS="${{ inputs.projects }}" \ - -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" \ - -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="BPF;SBF" \ - -DCMAKE_C_COMPILER_LAUNCHER=sccache \ - -DCMAKE_CXX_COMPILER_LAUNCHER=sccache \ - $extra_cmake_args \ - ${{ inputs.extra_cmake_args }} - ninja -C "$builddir" '${{ inputs.build_target }}' - - - name: Build and Test libclc - if: "!startsWith(matrix.os, 'windows') && !startsWith(matrix.os, 'macOS') && contains(inputs.projects, 'libclc')" - env: - LLVM_BUILDDIR: ${{ steps.build-llvm.outputs.llvm-builddir }} - run: | - # The libclc tests don't have a generated check target so all we can - # do is build it. - ninja -C "$LLVM_BUILDDIR" diff --git a/.github/workflows/llvm-project-workflow-tests.yml b/.github/workflows/llvm-project-workflow-tests.yml deleted file mode 100644 index a2539b279be0a..0000000000000 --- a/.github/workflows/llvm-project-workflow-tests.yml +++ /dev/null @@ -1,32 +0,0 @@ -# This workflow will test the llvm-project-tests workflow in PRs -# targetting the main branch. Since this workflow doesn't normally -# run on main PRs, we need some way to test it to ensure new updates -# don't break it. - -name: LLVM Workflow Test - -permissions: - contents: read - -on: - pull_request: - branches: - - 'main' - paths: - - '.github/workflows/llvm-project-tests.yml' - - '.github/workflows/llvm-project-workflow-tests.yml' - -concurrency: - # Skip intermediate builds: always. - # Cancel intermediate builds: only if it is a pull request build. - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} - -jobs: - llvm-test: - if: github.repository_owner == 'llvm' - name: Build and Test - uses: ./.github/workflows/llvm-project-tests.yml - with: - build_target: check-all - projects: clang;lld;libclc;lldb diff --git a/.github/workflows/llvm-tests.yml b/.github/workflows/llvm-tests.yml deleted file mode 100644 index 30b2ecc0cf38c..0000000000000 --- a/.github/workflows/llvm-tests.yml +++ /dev/null @@ -1,211 +0,0 @@ -name: LLVM Tests - -permissions: - contents: read - -on: - workflow_dispatch: - push: - ignore-forks: true - #branches: - # - 'release/**' - paths: - - 'llvm/**' - - '.github/workflows/llvm-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - pull_request: - ignore-forks: true - #branches: - # - 'release/**' - paths: - - 'llvm/**' - - '.github/workflows/llvm-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - -concurrency: - # Skip intermediate builds: always. - # Cancel intermediate builds: only if it is a pull request build. - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} - -jobs: - check_all: - #if: github.repository_owner == 'llvm' - name: Test llvm,clang,libclc - uses: ./.github/workflows/llvm-project-tests.yml - with: - build_target: check-all - projects: clang;libclc - - # These need to be separate from the check_all job, becuase there is not enough disk - # space to build all these projects on Windows. - build_lldb: - name: Build lldb - uses: ./.github/workflows/llvm-project-tests.yml - with: - build_target: all - projects: clang;lldb - - check_lld: - #if: github.repository_owner == 'llvm' - name: Test lld - uses: ./.github/workflows/llvm-project-tests.yml - with: - build_target: check-lld - projects: lld - - abi-dump-setup: - #if: github.repository_owner == 'llvm' - runs-on: ubuntu-22.04 - outputs: - BASELINE_REF: ${{ steps.vars.outputs.BASELINE_REF }} - ABI_HEADERS: ${{ steps.vars.outputs.ABI_HEADERS }} - BASELINE_VERSION_MAJOR: ${{ steps.vars.outputs.BASELINE_VERSION_MAJOR }} - BASELINE_VERSION_MINOR: ${{ steps.vars.outputs.BASELINE_VERSION_MINOR }} - LLVM_VERSION_MAJOR: ${{ steps.version.outputs.major }} - LLVM_VERSION_MINOR: ${{ steps.version.outputs.minor }} - LLVM_VERSION_PATCH: ${{ steps.version.outputs.patch }} - steps: - - name: Checkout source - uses: actions/checkout@v4 - with: - fetch-depth: 250 - - - name: Get LLVM version - id: version - uses: ./.github/workflows/get-llvm-version - - - name: Setup Variables - id: vars - run: | - # C++ ABI: - # 18.1.0 we aren't doing ABI checks. - # 18.1.1 We want to check 18.1.0. - # C ABI: - # 18.1.0 We want to check 17.0.x - # 18.1.1 We want to check 18.1.0 - echo "BASELINE_VERSION_MINOR=1" >> "$GITHUB_OUTPUT" - if [ ${{ steps.version.outputs.patch }} -eq 0 ]; then - { - echo "BASELINE_VERSION_MAJOR=$(( ${{ steps.version.outputs.major }} - 1))" - echo "ABI_HEADERS=llvm-c" - } >> "$GITHUB_OUTPUT" - else - { - echo "BASELINE_VERSION_MAJOR=${{ steps.version.outputs.major }}" - echo "ABI_HEADERS=." - } >> "$GITHUB_OUTPUT" - fi - - abi-dump: - #if: github.repository_owner == 'llvm' - needs: abi-dump-setup - runs-on: ubuntu-22.04 - strategy: - matrix: - name: - - build-baseline - - build-latest - include: - - name: build-baseline - llvm_version_major: ${{ needs.abi-dump-setup.outputs.BASELINE_VERSION_MAJOR }} - ref: llvmorg-${{ needs.abi-dump-setup.outputs.BASELINE_VERSION_MAJOR }}.${{ needs.abi-dump-setup.outputs.BASELINE_VERSION_MINOR }}.0 - repo: llvm/llvm-project - - name: build-latest - llvm_version_major: ${{ needs.abi-dump-setup.outputs.LLVM_VERSION_MAJOR }} - ref: ${{ github.sha }} - repo: ${{ github.repository }} - steps: - - name: Install Ninja - uses: llvm/actions/install-ninja@main - - name: Install abi-compliance-checker - run: | - sudo apt-get install abi-dumper autoconf pkg-config - - name: Install universal-ctags - run: | - git clone https://github.com/universal-ctags/ctags.git - cd ctags - ./autogen.sh - ./configure - sudo make install - - name: Download source code - uses: llvm/actions/get-llvm-project-src@main - with: - ref: ${{ matrix.ref }} - repo: ${{ matrix.repo }} - - name: Configure - run: | - mkdir install - cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug -DLLVM_TARGETS_TO_BUILD="" -DLLVM_BUILD_LLVM_DYLIB=ON -DCMAKE_C_FLAGS_DEBUG="-g1 -Og" -DCMAKE_CXX_FLAGS_DEBUG="-g1 -Og" -DCMAKE_INSTALL_PREFIX="$(pwd)"/install llvm - - name: Build - # Need to run install-LLVM twice to ensure the symlink is installed (this is a bug). - run: | - ninja -C build install-LLVM - ninja -C build install-LLVM - ninja -C build install-llvm-headers - - name: Dump ABI - run: | - if [ "${{ needs.abi-dump-setup.outputs.ABI_HEADERS }}" = "llvm-c" ]; then - nm ./install/lib/libLLVM.so | awk "/T _LLVM/ || /T LLVM/ { print $3 }" | sort -u | sed -e "s/^_//g" | cut -d ' ' -f 3 > llvm.symbols - # Even though the -symbols-list option doesn't seem to filter out the symbols, I believe it speeds up processing, so I'm leaving it in. - export EXTRA_ARGS="-symbols-list llvm.symbols" - else - touch llvm.symbols - fi - abi-dumper $EXTRA_ARGS -lver ${{ matrix.ref }} -skip-cxx -public-headers ./install/include/${{ needs.abi-dump-setup.outputs.ABI_HEADERS }} -o ${{ matrix.ref }}.abi ./install/lib/libLLVM.so - # Remove symbol versioning from dumps, so we can compare across major versions. - sed -i 's/LLVM_${{ matrix.llvm_version_major }}/LLVM_NOVERSION/' ${{ matrix.ref }}.abi - - name: Upload ABI file - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.name }} - path: ${{ matrix.ref }}.abi - - - name: Upload symbol list file - if: matrix.name == 'build-baseline' - uses: actions/upload-artifact@v4 - with: - name: symbol-list - path: llvm.symbols - - abi-compare: - #if: github.repository_owner == 'llvm' - runs-on: ubuntu-22.04 - needs: - - abi-dump-setup - - abi-dump - steps: - - name: Download baseline - uses: actions/download-artifact@v4 - with: - name: build-baseline - path: build-baseline - - name: Download latest - uses: actions/download-artifact@v4 - with: - name: build-latest - path: build-latest - - name: Download symbol list - uses: actions/download-artifact@v4 - with: - name: symbol-list - path: symbol-list - - - name: Install abi-compliance-checker - run: sudo apt-get install abi-compliance-checker - - name: Compare ABI - run: | - if [ -s symbol-list/llvm.symbols ]; then - # This option doesn't seem to work with the ABI dumper, so passing it here. - export EXTRA_ARGS="-symbols-list symbol-list/llvm.symbols" - fi - # FIXME: Reading of gzip'd abi files on the GitHub runners stop - # working some time in March of 2021, likely due to a change in the - # runner's environment. - abi-compliance-checker $EXTRA_ARGS -l libLLVM.so -old build-baseline/*.abi -new build-latest/*.abi || test "${{ needs.abi-dump-setup.outputs.ABI_HEADERS }}" = "llvm-c" - - name: Upload ABI Comparison - if: always() - uses: actions/upload-artifact@v4 - with: - name: compat-report-${{ github.sha }} - path: compat_reports/ diff --git a/lld/ELF/Arch/SBF.cpp b/lld/ELF/Arch/SBF.cpp index 0a31bc1a725bc..aa691ad8ab157 100644 --- a/lld/ELF/Arch/SBF.cpp +++ b/lld/ELF/Arch/SBF.cpp @@ -78,6 +78,8 @@ int64_t SBF::getImplicitAddend(const uint8_t *buf, RelType type) const { switch (type) { case R_SBF_64_ABS32: return SignExtend64<32>(read32le(buf)); + case R_SBF_64_ABS64: + return read64le(buf); default: return 0; } diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index f921246bf65d9..165ecef2a9eb7 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1678,6 +1678,8 @@ static uint16_t getBitcodeMachineKind(StringRef path, const Triple &t) { return t.isOSIAMCU() ? EM_IAMCU : EM_386; case Triple::x86_64: return EM_X86_64; + case Triple::bpfel: + case Triple::bpfeb: case Triple::sbf: return EM_SBF; default: diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index dcef330f0958e..d60bb8bb6901f 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -974,7 +974,7 @@ void InputSection::relocateNonAlloc(uint8_t *buf, Relocs rels) { const uint64_t offset = rel.r_offset; // FIX: Temporary remap BPF_64_64 relocations in debug sections. - if (config->emachine == EM_SBF && type == R_SBF_64_64 && isDebug) + if ((emachine == EM_SBF || emachine == EM_BPF) && type == R_SBF_64_64 && isDebug) type = R_BPF_64_ABS64; uint8_t *bufLoc = buf + offset; diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index b055972512a85..a8e0668bf44f5 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -61,6 +61,7 @@ TargetInfo *elf::getTarget() { case EM_AVR: return getAVRTargetInfo(); case EM_SBF: + case EM_BPF: return getSBFTargetInfo(); case EM_HEXAGON: return getHexagonTargetInfo(); diff --git a/lld/test/ELF/sbf-abs64-addend.s b/lld/test/ELF/sbf-abs64-addend.s new file mode 100644 index 0000000000000..605adf35a2a6b --- /dev/null +++ b/lld/test/ELF/sbf-abs64-addend.s @@ -0,0 +1,34 @@ +# REQUIRES: sbf +## Check that R_SBF_64_ABS64 relocations honor the implicit addend stored in +## the relocated data. SBF uses REL relocations, so the addend for a `.quad +## sym + N` lives in the 8 bytes at the relocation offset and must be read back +## by SBF::getImplicitAddend(); otherwise it would be silently dropped and the +## linked value would be just `sym`. + +# RUN: llvm-mc -filetype=obj -triple=sbf -mcpu=v3 %s -o %t.o +# RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=RELOC %s +# RUN: ld.lld %t.o -o %t.out --section-start .data=0x1000 -e target +# RUN: llvm-readelf -x .data %t.out | FileCheck --check-prefix=DATA %s + +## The input carries a single R_SBF_64_ABS64 relocation against `target`, with +## the addend 0x42 encoded in the data at the relocation offset (0x8). +# RELOC: Relocations [ +# RELOC-NEXT: Section ({{.*}}) .rel.data { +# RELOC-NEXT: 0x8 R_SBF_64_ABS64 target +# RELOC-NEXT: } +# RELOC-NEXT: ] + +## .data is pinned at 0x1000, so `target` == 0x1000 and `ptr` must resolve to +## target + 0x42 == 0x1042 (little-endian: 42 10 ..). Without reading the +## implicit addend `ptr` would instead be just 0x1000 (00 10 ..). +# DATA: Hex dump of section '.data': +# DATA-NEXT: 0x00001000 00000000 00000000 42100000 00000000 + + .section .data,"aw" + .globl target +target: + .quad 0 + + .globl ptr +ptr: + .quad target + 0x42 diff --git a/lld/test/lit.cfg.py b/lld/test/lit.cfg.py index d309c2ad4ee28..55e2c704c168d 100644 --- a/lld/test/lit.cfg.py +++ b/lld/test/lit.cfg.py @@ -82,6 +82,7 @@ "MSP430": "msp430", "PowerPC": "ppc", "RISCV": "riscv", + "SBF": "sbf", "Sparc": "sparc", "SystemZ": "systemz", "WebAssembly": "wasm", diff --git a/lldb/source/Utility/ArchSpec.cpp b/lldb/source/Utility/ArchSpec.cpp index 0d8e76eb0c044..941253904d2d3 100644 --- a/lldb/source/Utility/ArchSpec.cpp +++ b/lldb/source/Utility/ArchSpec.cpp @@ -366,82 +366,82 @@ static const ArchDefinition g_macho_arch_def = {eArchTypeMachO, // architecture names to cpu types and subtypes. The ordering is important and // allows the precedence to be set when the table is built. static const ArchDefinitionEntry g_elf_arch_entries[] = { - {ArchSpec::eCore_sparc_generic, llvm::ELF::EM_SPARC, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // Sparc - {ArchSpec::eCore_x86_32_i386, llvm::ELF::EM_386, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // Intel 80386 - {ArchSpec::eCore_x86_32_i486, llvm::ELF::EM_IAMCU, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // Intel MCU // FIXME: is this correct? - {ArchSpec::eCore_ppc_generic, llvm::ELF::EM_PPC, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC - {ArchSpec::eCore_ppc64le_generic, llvm::ELF::EM_PPC64, - ArchSpec::eCore_ppc64le_generic, 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC64le - {ArchSpec::eCore_ppc64_generic, llvm::ELF::EM_PPC64, - ArchSpec::eCore_ppc64_generic, 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC64 - {ArchSpec::eCore_arm_generic, llvm::ELF::EM_ARM, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARM - {ArchSpec::eCore_arm_aarch64, llvm::ELF::EM_AARCH64, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARM64 - {ArchSpec::eCore_s390x_generic, llvm::ELF::EM_S390, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // SystemZ - {ArchSpec::eCore_sparc9_generic, llvm::ELF::EM_SPARCV9, - LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // SPARC V9 - {ArchSpec::eCore_x86_64_x86_64, llvm::ELF::EM_X86_64, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // AMD64 - {ArchSpec::eCore_mips32, llvm::ELF::EM_MIPS, ArchSpec::eMIPSSubType_mips32, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32 - {ArchSpec::eCore_mips32r2, llvm::ELF::EM_MIPS, - ArchSpec::eMIPSSubType_mips32r2, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32r2 - {ArchSpec::eCore_mips32r6, llvm::ELF::EM_MIPS, - ArchSpec::eMIPSSubType_mips32r6, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32r6 - {ArchSpec::eCore_mips32el, llvm::ELF::EM_MIPS, - ArchSpec::eMIPSSubType_mips32el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32el - {ArchSpec::eCore_mips32r2el, llvm::ELF::EM_MIPS, - ArchSpec::eMIPSSubType_mips32r2el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32r2el - {ArchSpec::eCore_mips32r6el, llvm::ELF::EM_MIPS, - ArchSpec::eMIPSSubType_mips32r6el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32r6el - {ArchSpec::eCore_mips64, llvm::ELF::EM_MIPS, ArchSpec::eMIPSSubType_mips64, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64 - {ArchSpec::eCore_mips64r2, llvm::ELF::EM_MIPS, - ArchSpec::eMIPSSubType_mips64r2, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r2 - {ArchSpec::eCore_mips64r6, llvm::ELF::EM_MIPS, - ArchSpec::eMIPSSubType_mips64r6, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r6 - {ArchSpec::eCore_mips64el, llvm::ELF::EM_MIPS, - ArchSpec::eMIPSSubType_mips64el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64el - {ArchSpec::eCore_mips64r2el, llvm::ELF::EM_MIPS, - ArchSpec::eMIPSSubType_mips64r2el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r2el - {ArchSpec::eCore_mips64r6el, llvm::ELF::EM_MIPS, - ArchSpec::eMIPSSubType_mips64r6el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r6el - {ArchSpec::eCore_msp430, llvm::ELF::EM_MSP430, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // MSP430 - {ArchSpec::eCore_hexagon_generic, llvm::ELF::EM_HEXAGON, - LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // HEXAGON - {ArchSpec::eCore_arc, llvm::ELF::EM_ARC_COMPACT2, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARC - {ArchSpec::eCore_avr, llvm::ELF::EM_AVR, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, - 0xFFFFFFFFu}, // AVR - {ArchSpec::eCore_riscv32, llvm::ELF::EM_RISCV, - ArchSpec::eRISCVSubType_riscv32, 0xFFFFFFFFu, 0xFFFFFFFFu}, // riscv32 - {ArchSpec::eCore_riscv64, llvm::ELF::EM_RISCV, - ArchSpec::eRISCVSubType_riscv64, 0xFFFFFFFFu, 0xFFFFFFFFu}, // riscv64 - {ArchSpec::eCore_loongarch32, llvm::ELF::EM_LOONGARCH, - ArchSpec::eLoongArchSubType_loongarch32, 0xFFFFFFFFu, - 0xFFFFFFFFu}, // loongarch32 - {ArchSpec::eCore_loongarch64, llvm::ELF::EM_LOONGARCH, - ArchSpec::eLoongArchSubType_loongarch64, 0xFFFFFFFFu, - 0xFFFFFFFFu}, // loongarch64 - {ArchSpec::eCore_bpf, llvm::ELF::EM_BPF, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // bpf - {ArchSpec::eCore_sbfv0, llvm::ELF::EM_SBF, ArchSpec::eSBFSubType_sbfv0, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // sbf - {ArchSpec::eCore_sbfv1, llvm::ELF::EM_SBF, ArchSpec::eSBFSubType_sbfv1, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // sbfv1 - {ArchSpec::eCore_sbfv2, llvm::ELF::EM_SBF, ArchSpec::eSBFSubType_sbfv2, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // sbfv2 - {ArchSpec::eCore_sbfv3, llvm::ELF::EM_SBF, ArchSpec::eSBFSubType_sbfv3, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // sbfv3 - {ArchSpec::eCore_sbfv4, llvm::ELF::EM_SBF, ArchSpec::eSBFSubType_sbfv4, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // sbfv3 + {ArchSpec::eCore_sparc_generic, llvm::ELF::EM_SPARC, LLDB_INVALID_CPUTYPE, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // Sparc + {ArchSpec::eCore_x86_32_i386, llvm::ELF::EM_386, LLDB_INVALID_CPUTYPE, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // Intel 80386 + {ArchSpec::eCore_x86_32_i486, llvm::ELF::EM_IAMCU, LLDB_INVALID_CPUTYPE, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // Intel MCU // FIXME: is this correct? + {ArchSpec::eCore_ppc_generic, llvm::ELF::EM_PPC, LLDB_INVALID_CPUTYPE, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC + {ArchSpec::eCore_ppc64le_generic, llvm::ELF::EM_PPC64, + ArchSpec::eCore_ppc64le_generic, 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC64le + {ArchSpec::eCore_ppc64_generic, llvm::ELF::EM_PPC64, + ArchSpec::eCore_ppc64_generic, 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC64 + {ArchSpec::eCore_arm_generic, llvm::ELF::EM_ARM, LLDB_INVALID_CPUTYPE, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARM + {ArchSpec::eCore_arm_aarch64, llvm::ELF::EM_AARCH64, LLDB_INVALID_CPUTYPE, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARM64 + {ArchSpec::eCore_s390x_generic, llvm::ELF::EM_S390, LLDB_INVALID_CPUTYPE, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // SystemZ + {ArchSpec::eCore_sparc9_generic, llvm::ELF::EM_SPARCV9, + LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // SPARC V9 + {ArchSpec::eCore_x86_64_x86_64, llvm::ELF::EM_X86_64, LLDB_INVALID_CPUTYPE, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // AMD64 + {ArchSpec::eCore_mips32, llvm::ELF::EM_MIPS, ArchSpec::eMIPSSubType_mips32, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32 + {ArchSpec::eCore_mips32r2, llvm::ELF::EM_MIPS, + ArchSpec::eMIPSSubType_mips32r2, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32r2 + {ArchSpec::eCore_mips32r6, llvm::ELF::EM_MIPS, + ArchSpec::eMIPSSubType_mips32r6, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32r6 + {ArchSpec::eCore_mips32el, llvm::ELF::EM_MIPS, + ArchSpec::eMIPSSubType_mips32el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32el + {ArchSpec::eCore_mips32r2el, llvm::ELF::EM_MIPS, + ArchSpec::eMIPSSubType_mips32r2el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32r2el + {ArchSpec::eCore_mips32r6el, llvm::ELF::EM_MIPS, + ArchSpec::eMIPSSubType_mips32r6el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32r6el + {ArchSpec::eCore_mips64, llvm::ELF::EM_MIPS, ArchSpec::eMIPSSubType_mips64, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64 + {ArchSpec::eCore_mips64r2, llvm::ELF::EM_MIPS, + ArchSpec::eMIPSSubType_mips64r2, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r2 + {ArchSpec::eCore_mips64r6, llvm::ELF::EM_MIPS, + ArchSpec::eMIPSSubType_mips64r6, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r6 + {ArchSpec::eCore_mips64el, llvm::ELF::EM_MIPS, + ArchSpec::eMIPSSubType_mips64el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64el + {ArchSpec::eCore_mips64r2el, llvm::ELF::EM_MIPS, + ArchSpec::eMIPSSubType_mips64r2el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r2el + {ArchSpec::eCore_mips64r6el, llvm::ELF::EM_MIPS, + ArchSpec::eMIPSSubType_mips64r6el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r6el + {ArchSpec::eCore_msp430, llvm::ELF::EM_MSP430, LLDB_INVALID_CPUTYPE, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // MSP430 + {ArchSpec::eCore_hexagon_generic, llvm::ELF::EM_HEXAGON, + LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // HEXAGON + {ArchSpec::eCore_arc, llvm::ELF::EM_ARC_COMPACT2, LLDB_INVALID_CPUTYPE, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARC + {ArchSpec::eCore_avr, llvm::ELF::EM_AVR, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, + 0xFFFFFFFFu}, // AVR + {ArchSpec::eCore_riscv32, llvm::ELF::EM_RISCV, + ArchSpec::eRISCVSubType_riscv32, 0xFFFFFFFFu, 0xFFFFFFFFu}, // riscv32 + {ArchSpec::eCore_riscv64, llvm::ELF::EM_RISCV, + ArchSpec::eRISCVSubType_riscv64, 0xFFFFFFFFu, 0xFFFFFFFFu}, // riscv64 + {ArchSpec::eCore_loongarch32, llvm::ELF::EM_LOONGARCH, + ArchSpec::eLoongArchSubType_loongarch32, 0xFFFFFFFFu, + 0xFFFFFFFFu}, // loongarch32 + {ArchSpec::eCore_loongarch64, llvm::ELF::EM_LOONGARCH, + ArchSpec::eLoongArchSubType_loongarch64, 0xFFFFFFFFu, + 0xFFFFFFFFu}, // loongarch64 + {ArchSpec::eCore_bpf, llvm::ELF::EM_BPF, LLDB_INVALID_CPUTYPE, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // bpf + {ArchSpec::eCore_sbfv0, llvm::ELF::EM_SBF, ArchSpec::eSBFSubType_sbfv0, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // sbf + {ArchSpec::eCore_sbfv1, llvm::ELF::EM_SBF, ArchSpec::eSBFSubType_sbfv1, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // sbfv1 + {ArchSpec::eCore_sbfv2, llvm::ELF::EM_SBF, ArchSpec::eSBFSubType_sbfv2, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // sbfv2 + {ArchSpec::eCore_sbfv3, llvm::ELF::EM_BPF, ArchSpec::eSBFSubType_sbfv3, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // sbfv3 + {ArchSpec::eCore_sbfv4, llvm::ELF::EM_BPF, ArchSpec::eSBFSubType_sbfv4, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // sbfv4 }; static const ArchDefinition g_elf_arch_def = { diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index 41fcc9afe4e90..97427f0a540e4 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -702,6 +702,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_ExpOp(SDNode *N) { EVT OpsVT[2] = { N->getOperand(0 + Offset).getValueType(), N->getOperand(1 + Offset).getValueType() }; CallOptions.setTypeListBeforeSoften(OpsVT, N->getValueType(0), true); + CallOptions.setSExt(); std::pair Tmp = TLI.makeLibCall(DAG, LC, NVT, Ops, CallOptions, SDLoc(N), Chain); diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp index 8d72faf2a781a..d4c8e14cfe2e1 100644 --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -141,7 +141,7 @@ StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine, break; case ELF::EM_BPF: switch (Type) { -#include "llvm/BinaryFormat/ELFRelocs/BPF.def" +#include "llvm/BinaryFormat/ELFRelocs/SBF.def" default: break; } diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index 5036cf512e6ce..9ee24e65d403f 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -918,7 +918,7 @@ void ScalarEnumerationTraits::enumeration( #include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def" break; case ELF::EM_BPF: -#include "llvm/BinaryFormat/ELFRelocs/BPF.def" +#include "llvm/BinaryFormat/ELFRelocs/SBF.def" break; case ELF::EM_SBF: #include "llvm/BinaryFormat/ELFRelocs/SBF.def" diff --git a/llvm/lib/Target/SBF/Disassembler/SBFDisassembler.cpp b/llvm/lib/Target/SBF/Disassembler/SBFDisassembler.cpp index 377309414e462..49fd5376ed235 100644 --- a/llvm/lib/Target/SBF/Disassembler/SBFDisassembler.cpp +++ b/llvm/lib/Target/SBF/Disassembler/SBFDisassembler.cpp @@ -211,8 +211,7 @@ DecodeStatus SBFDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, decodeInstruction(DecoderTableSBFALU32MEMv264, Instr, Insn, Address, this, STI); } - else if ((isNewMem(Insn) && STI.hasFeature(SBF::FeatureNewMemEncoding)) || - (isSyscallOrExit(Insn) && STI.hasFeature(SBF::FeatureStaticSyscalls))) { + else if (isNewMem(Insn) && STI.hasFeature(SBF::FeatureNewMemEncoding)) { Result = decodeInstruction(DecoderTableSBFv264, Instr, Insn, Address, this, STI); @@ -246,6 +245,9 @@ DecodeStatus SBFDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, if (STI.hasFeature(SBF::FeatureCallxRegSrc)) { Result = decodeInstruction(DecoderTableSBFv264, Instr, Insn, Address, this, STI); + } else if (STI.hasFeature(SBF::FeatureCallxRegDst)) { + Result = decodeInstruction(DecoderTableSBFv364, Instr, Insn, Address, + this, STI); } } } diff --git a/llvm/lib/Target/SBF/GISel/SBFCallLowering.cpp b/llvm/lib/Target/SBF/GISel/SBFCallLowering.cpp index fd893f5f4160a..8ddb4054bea5c 100644 --- a/llvm/lib/Target/SBF/GISel/SBFCallLowering.cpp +++ b/llvm/lib/Target/SBF/GISel/SBFCallLowering.cpp @@ -29,7 +29,7 @@ bool SBFCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, Register SwiftErrorVReg) const { if (!VRegs.empty()) return false; - MIRBuilder.buildInstr(SBF::RETURN_v3); + MIRBuilder.buildInstr(SBF::EXIT); return true; } diff --git a/llvm/lib/Target/SBF/MCTargetDesc/SBFELFObjectWriter.cpp b/llvm/lib/Target/SBF/MCTargetDesc/SBFELFObjectWriter.cpp index 15c1ae681402d..4fbd0fbcca22d 100644 --- a/llvm/lib/Target/SBF/MCTargetDesc/SBFELFObjectWriter.cpp +++ b/llvm/lib/Target/SBF/MCTargetDesc/SBFELFObjectWriter.cpp @@ -48,7 +48,7 @@ bool SBFELFObjectWriter::needsRelocateWithSymbol(const MCValue &Val, } SBFELFObjectWriter::SBFELFObjectWriter(uint8_t OSABI, bool relocAbs64) - : MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI,ELF::EM_SBF, + : MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI, relocAbs64? ELF::EM_BPF : ELF::EM_SBF, /*HasRelocationAddend*/ false), relocAbs64(relocAbs64) {} diff --git a/llvm/lib/Target/SBF/SBFFrameLowering.cpp b/llvm/lib/Target/SBF/SBFFrameLowering.cpp index 2e12afe18ec4a..a13d34fce9d3c 100644 --- a/llvm/lib/Target/SBF/SBFFrameLowering.cpp +++ b/llvm/lib/Target/SBF/SBFFrameLowering.cpp @@ -23,19 +23,24 @@ bool SBFFrameLowering::hasFP(const MachineFunction &MF) const { return true; } void SBFFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { - if (!MF.getSubtarget().getHasDynamicFrames()) { + const SBFSubtarget& Subtarget = MF.getSubtarget(); + if (!Subtarget.getHasDynamicFrames()) { return; } + MachineBasicBlock::iterator MBBI = MBB.begin(); - MachineFrameInfo &MFI = MF.getFrameInfo(); - int NumBytes = (int)MFI.getStackSize(); - if (NumBytes || MF.getSubtarget().getHasStaticSyscalls()) { - DebugLoc Dl = MBBI->getDebugLoc(); + const MachineFrameInfo &MFI = MF.getFrameInfo(); + const int NumBytes = -static_cast(MFI.getStackSize()); + + if (MBBI != MBB.end()) { + const DebugLoc Dl = MBBI->getDebugLoc(); const SBFInstrInfo &TII = *static_cast(MF.getSubtarget().getInstrInfo()); - BuildMI(MBB, MBBI, Dl, TII.get(SBF::ADD_ri), SBF::R10) - .addReg(SBF::R10) - .addImm(-NumBytes); + + if (NumBytes) + BuildMI(MBB, MBBI, Dl, TII.get(SBF::ADD_ri), SBF::R10) + .addReg(SBF::R10) + .addImm(NumBytes); } } diff --git a/llvm/lib/Target/SBF/SBFFrameLowering.h b/llvm/lib/Target/SBF/SBFFrameLowering.h index 67f98b77da1ea..f3198bd72b1cb 100644 --- a/llvm/lib/Target/SBF/SBFFrameLowering.h +++ b/llvm/lib/Target/SBF/SBFFrameLowering.h @@ -20,12 +20,11 @@ class SBFSubtarget; class SBFFrameLowering : public TargetFrameLowering { public: - explicit SBFFrameLowering(const SBFSubtarget &sti) - : TargetFrameLowering( - TargetFrameLowering::StackGrowsDown, - Align(64), - 0, - Align(64)) {} + explicit SBFFrameLowering(const bool hasStackFramesV3) + : TargetFrameLowering(hasStackFramesV3 + ? TargetFrameLowering::StackGrowsUp + : TargetFrameLowering::StackGrowsDown, + Align(64), 0, Align(64)) {} void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; @@ -40,5 +39,5 @@ class SBFFrameLowering : public TargetFrameLowering { return MBB.erase(MI); } }; -} +} // namespace llvm #endif diff --git a/llvm/lib/Target/SBF/SBFISelLowering.cpp b/llvm/lib/Target/SBF/SBFISelLowering.cpp index 1e775af0c5d21..76f8f5d5b416b 100644 --- a/llvm/lib/Target/SBF/SBFISelLowering.cpp +++ b/llvm/lib/Target/SBF/SBFISelLowering.cpp @@ -339,7 +339,7 @@ SDValue SBFTargetLowering::LowerFormalArguments( // Assign locations to all of the incoming arguments. SmallVector ArgLocs; CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); - if (!Subtarget->getHasDynamicFrames() && Ins.size() > MaxArgs) { + if (!Subtarget->getHasNoStackGaps() && Ins.size() > MaxArgs) { // Pass args 1-4 via registers, remaining args via stack, referenced via // SBF::R5 CCInfo.AnalyzeFormalArguments(Ins, @@ -391,15 +391,23 @@ SDValue SBFTargetLowering::LowerFormalArguments( EVT LocVT = VA.getLocVT(); SDValue SDV; - if (Subtarget->getHasDynamicFrames()) { + if (Subtarget->getHasNoStackGaps()) { // In the new convention, arguments are in at the end of the callee // frame. - uint64_t Size = VA.getLocVT().getFixedSizeInBits() / 8; - int64_t Offset = -static_cast(VA.getLocMemOffset() + Size); - int FrameIndex = + const int64_t Size = + static_cast(VA.getLocVT().getFixedSizeInBits() / 8); + int64_t Offset = VA.getLocMemOffset(); + + // Only when the stack grows down do we need to reverse the offset + // and compensate for the size. + if (Subtarget->getFrameLowering()->getStackGrowthDirection() == + TargetFrameLowering::StackGrowsDown) + Offset = -Offset - Size; + + const int FrameIndex = MF.getFrameInfo().CreateFixedObject(Size, Offset, false); - SDValue DstAddr = DAG.getFrameIndex(FrameIndex, PtrVT); - MachinePointerInfo DstInfo = + const SDValue DstAddr = DAG.getFrameIndex(FrameIndex, PtrVT); + const MachinePointerInfo DstInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex, Offset); SDV = DAG.getLoad(LocVT, DL, Chain, DstAddr, DstInfo); } else { @@ -455,7 +463,7 @@ SDValue SBFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVector ArgLocs; CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); if (Outs.size() > MaxArgs) { - if (Subtarget->getHasDynamicFrames()) { + if (Subtarget->getHasNoStackGaps()) { // Pass args 1-5 via registers, remaining args via stack CCInfo.AnalyzeCallOperands(Outs, getHasAlu32() ? CC_SBF32 : CC_SBF64); } else { @@ -511,13 +519,19 @@ SDValue SBFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, int64_t Offset = static_cast(VA.getLocMemOffset()); uint64_t Size = VA.getLocVT().getFixedSizeInBits() / 8; - if (Subtarget->getHasDynamicFrames()) { + if (Subtarget->getHasNoStackGaps()) { // In the new call convention, arguments are stored in the callee frame // We must increase the offset, simply because offset zero belongs to // the caller. Offset += Size; } + // Since the stack grows to the opposite direction in V3, the offset + // is inverted. + if (Subtarget->getFrameLowering()->getStackGrowthDirection() == + TargetFrameLowering::StackGrowsUp) + Offset = -Offset; + int FrameIndex = MF.getFrameInfo().CreateFixedObject( Size, Offset, false); SBFFuncInfo->storeFrameIndexArgument(FrameIndex); @@ -597,10 +611,6 @@ SDValue SBFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, InVals); } -bool SBFTargetLowering::shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const { - return IsSigned || Type == MVT::i32; -} - bool SBFTargetLowering::CanLowerReturn( CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, const SmallVectorImpl &Outs, LLVMContext &Context) const { diff --git a/llvm/lib/Target/SBF/SBFISelLowering.h b/llvm/lib/Target/SBF/SBFISelLowering.h index 050f53528ec4f..e81634154f637 100644 --- a/llvm/lib/Target/SBF/SBFISelLowering.h +++ b/llvm/lib/Target/SBF/SBFISelLowering.h @@ -98,9 +98,6 @@ class SBFTargetLowering : public TargetLowering { SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl &InVals) const override; - /// Returns true if arguments should be sign-extended in lib calls. - bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const override; - // Lower incoming arguments, copy physregs into vregs SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, diff --git a/llvm/lib/Target/SBF/SBFInstrInfo.td b/llvm/lib/Target/SBF/SBFInstrInfo.td index b020ce38a9d46..90432ff4ab8e9 100644 --- a/llvm/lib/Target/SBF/SBFInstrInfo.td +++ b/llvm/lib/Target/SBF/SBFInstrInfo.td @@ -51,8 +51,11 @@ def SBFHasNeg : Predicate<"!Subtarget->getDisableNeg()">; def SBFNoNeg: Predicate<"Subtarget->getDisableNeg()">; def SBFRevSub : Predicate<"Subtarget->getReverseSubImm()">; def SBFNoRevSub : Predicate<"!Subtarget->getReverseSubImm()">; -def SBFCallxSrc : Predicate<"Subtarget->getCallXRegSrc()">, AssemblerPredicate<(all_of FeatureCallxRegSrc)>; -def SBFNoCallxSrc : Predicate<"!Subtarget->getCallXRegSrc()">; +def SBFCallxSrc : Predicate<"Subtarget->getCallXRegSrc() && !Subtarget->getCallXRegDst()">, + AssemblerPredicate<(all_of FeatureCallxRegSrc)>; +def SBFCallxDst : Predicate<"Subtarget->getCallXRegDst() && !Subtarget->getCallXRegSrc()">, + AssemblerPredicate<(all_of FeatureCallxRegDst)>; +def SBFNoCallxSrc : Predicate<"!Subtarget->getCallXRegSrc() && !Subtarget->getCallXRegDst()">; def SBFPqrInstr : Predicate<"Subtarget->getHasPqrClass()">; def SBFNoPqrInstr : Predicate<"!Subtarget->getHasPqrClass()">; def SBFHasStoreImm : Predicate<"Subtarget->getHasStoreImm()">; @@ -60,8 +63,6 @@ def SBFExplicitSignExt : Predicate<"Subtarget->getHasExplicitSignExt()">; def SBFNoExplicitSignExt : Predicate<"!Subtarget->getHasExplicitSignExt()">; def SBFNewMemEncoding : Predicate<"Subtarget->getNewMemEncoding()">, AssemblerPredicate<(all_of FeatureNewMemEncoding)>; def SBFOldMemEncoding : Predicate<"!Subtarget->getNewMemEncoding()">; -def SBFHasStaticSyscalls : Predicate<"Subtarget->getHasStaticSyscalls()">; -def SBFNoStaticSyscalls : Predicate<"!Subtarget->getHasStaticSyscalls()">; def brtarget : Operand { let PrintMethod = "printBrTargetOperand"; @@ -800,32 +801,31 @@ class CALL let SBFClass = SBF_JMP; } -class SYSCALL - : TYPE_ALU_JMP + : TYPE_ALU_JMP { - bits<32> imm; + bits<32> BrDst; - let Inst{31-0} = imm; + let Inst{31-0} = BrDst; let SBFClass = SBF_JMP; } - -class CALLX +class CALLX_SRC_REG : TYPE_ALU_JMP { - bits<32> BrDst; + bits<4> BrDst; - let Inst{31-0} = BrDst; + let Inst{55-52} = BrDst; let SBFClass = SBF_JMP; } -class CALLX_SRC_REG +class CALLX_DST_REG : TYPE_ALU_JMP []> { bits<4> BrDst; - let Inst{55-52} = BrDst; + let Inst{51-48} = BrDst; let SBFClass = SBF_JMP; } @@ -850,7 +850,9 @@ let isCall=1, hasDelaySlot=0, Uses = [R10], def JALX : CALLX<"callx">, Requires<[SBFNoCallxSrc]>; let DecoderNamespace = "SBFv2" in { def JALX_v2 : CALLX_SRC_REG<"callx">, Requires<[SBFCallxSrc]>; - def SYSCALL_v3 : SYSCALL<"syscall">, Requires<[SBFHasStaticSyscalls]>; + } + let DecoderNamespace = "SBFv3" in { + def JALX_v3 : CALLX_DST_REG<"callx">, Requires<[SBFCallxDst]>; } } @@ -880,25 +882,10 @@ class EXIT } let isReturn = 1, isTerminator = 1, hasDelaySlot=0, isBarrier = 1, - isNotDuplicable = 1, Predicates = [SBFNoStaticSyscalls] in { + isNotDuplicable = 1 in { def EXIT : EXIT<"exit">; } -class RETURN - : TYPE_ALU_JMP { - let Inst{31-0} = 0; - let SBFClass = SBF_JMP; -} - -let isReturn = 1, isTerminator = 1, hasDelaySlot=0, isBarrier = 1, - isNotDuplicable = 1, Predicates = [SBFHasStaticSyscalls] in { - def RETURN_v3 : RETURN<"return">; -} - // ADJCALLSTACKDOWN/UP pseudo insns let Defs = [R10], Uses = [R10], isCodeGenOnly = 1 in { def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2), @@ -959,10 +946,10 @@ def : Pat<(i64 (and (i64 GPR:$src), 0xffffFFFF)), // Calls def : Pat<(SBFcall tglobaladdr:$dst), (JAL tglobaladdr:$dst)>; def : Pat<(SBFcall texternalsym:$dst), (JAL texternalsym:$dst)>; -def : Pat<(SBFcall imm:$dst), (JAL imm:$dst)>, Requires<[SBFNoStaticSyscalls]>; +def : Pat<(SBFcall imm:$dst), (JAL imm:$dst)>; def : Pat<(SBFcall GPR:$dst), (JALX GPR:$dst)>, Requires<[SBFNoCallxSrc]>; def : Pat<(SBFcall GPR:$dst), (JALX_v2 GPR:$dst)>, Requires<[SBFCallxSrc]>; -def : Pat<(SBFcall imm:$imm), (SYSCALL_v3 imm:$imm)>, Requires<[SBFHasStaticSyscalls]>; +def : Pat<(SBFcall GPR:$dst), (JALX_v3 GPR:$dst)>, Requires<[SBFCallxDst]>; // Loads let Predicates = [SBFNoALU32, SBFOldMemEncoding] in { diff --git a/llvm/lib/Target/SBF/SBFMIPeephole.cpp b/llvm/lib/Target/SBF/SBFMIPeephole.cpp index d09df5513b254..5439e0476ebf3 100644 --- a/llvm/lib/Target/SBF/SBFMIPeephole.cpp +++ b/llvm/lib/Target/SBF/SBFMIPeephole.cpp @@ -145,26 +145,16 @@ struct SBFMIPreEmitPeephole : public MachineFunctionPass { void initialize(MachineFunction &MFParm); bool eliminateRedundantMov(); - bool addReturn(); public: // Main entry point for this pass. bool runOnMachineFunction(MachineFunction &MF) override { - initialize(MF); - - bool PeepholeExecuted = false; - if (SubTarget->getHasStaticSyscalls()) - PeepholeExecuted |= addReturn(); - - // We shall not skip adding the return to SBPFv3 functions - if (skipFunction(MF.getFunction()) || OptLevel == CodeGenOptLevel::None || - DisablePeephole) - return PeepholeExecuted; - - PeepholeExecuted |= eliminateRedundantMov(); + if (skipFunction(MF.getFunction())) + return false; - return PeepholeExecuted; + initialize(MF); + return eliminateRedundantMov(); } }; @@ -177,36 +167,6 @@ void SBFMIPreEmitPeephole::initialize(MachineFunction &MFParm) { LLVM_DEBUG(dbgs() << "*** SBF PreEmit peephole pass ***\n\n"); } -bool SBFMIPreEmitPeephole::addReturn() { - bool Added = false; - - // In SBFv3, every function must either end with either a JA or a RETURN - // instruction. When we call a function that will never return the control - // flow (e.g. when the callee aborts execution), the caller last instruction - // will be a CALL, failing validation. - // - // Although we can change ISelLowering and manually add the return for an - // LLVM-IR unreachable instruction, LLVM codegen uses the target machine's - // return instruction to determine whether a function needs an epilogue. - // This setting increases code size, even when we know the call won't - // trasnfer control back to the caller. - // - // In that case, we can analyze every function before emitting machine code - // and include a useless return instruction. - - // PreEmitPeephole happens after block placement, so the last block in - // the ELF layout is also the last one in MF. - MachineBasicBlock &MBB = MF->back(); - MachineInstr &MI = MBB.back(); - unsigned Opcode = MI.getOpcode(); - if (Opcode != SBF::RETURN_v3 && Opcode != SBF::JMP) { - BuildMI(&MBB, MI.getDebugLoc(), TII->get(SBF::RETURN_v3)); - Added = true; - } - - return Added; -} - bool SBFMIPreEmitPeephole::eliminateRedundantMov() { MachineInstr* ToErase = nullptr; bool Eliminated = false; diff --git a/llvm/lib/Target/SBF/SBFRegisterInfo.cpp b/llvm/lib/Target/SBF/SBFRegisterInfo.cpp index 4179e302c6dd6..3dcab8d2d3cea 100644 --- a/llvm/lib/Target/SBF/SBFRegisterInfo.cpp +++ b/llvm/lib/Target/SBF/SBFRegisterInfo.cpp @@ -26,7 +26,7 @@ #include "SBFGenRegisterInfo.inc" using namespace llvm; -unsigned SBFRegisterInfo::FrameLength = 512; +unsigned SBFRegisterInfo::FrameLength = 4096; SBFRegisterInfo::SBFRegisterInfo() : SBFGenRegisterInfo(SBF::R0) {} @@ -42,27 +42,38 @@ BitVector SBFRegisterInfo::getReservedRegs(const MachineFunction &MF) const { return Reserved; } -static void WarnSize(int Offset, MachineFunction &MF, DebugLoc& DL) -{ +static void warnSize(const int RequestedOffset, MachineFunction &MF, + const DebugLoc & DL, const bool StackGrowsUp, + const int ObjectOffset, const int ObjectSize) { + static Function *OldMF = nullptr; - int MaxOffset = -1 * SBFRegisterInfo::FrameLength; - if (Offset < MaxOffset) { + const int MaxOffset = -1 * SBFRegisterInfo::FrameLength; + bool ShouldWarn = false; + + if (StackGrowsUp && ObjectOffset + ObjectSize > 0) { + ShouldWarn = true; + } else if (!StackGrowsUp && RequestedOffset < MaxOffset) { + ShouldWarn = true; + } - if (&(MF.getFunction()) == OldMF) { + if (ShouldWarn) { + if (&MF.getFunction() == OldMF) { return; } - OldMF = &(MF.getFunction()); + OldMF = &MF.getFunction(); dbgs() << "Error:"; if (DL) { dbgs() << " "; DL.print(dbgs()); } - uint64_t StackSize = MF.getFrameInfo().getStackSize(); + const uint64_t StackSize = MF.getFrameInfo().getStackSize(); + const uint64_t Overflow = + StackSize - static_cast(SBFRegisterInfo::FrameLength); dbgs() << " Function " << MF.getFunction().getName() - << " Stack offset of " << -Offset << " exceeded max offset of " - << -MaxOffset << " by " << MaxOffset - Offset - << " bytes, please minimize large stack variables. " + << " overflows the maximum allowed frame space by accessing " + << "an offset " << Overflow << " bytes greater than the " + << "maximum of 4096. Please, minimize large stack variables. " << "Estimated function frame size: " << StackSize << " bytes." << " Exceeding the maximum stack offset may cause " "undefined behavior during execution.\n\n"; @@ -98,11 +109,8 @@ bool SBFRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); if (MI.getOpcode() == SBF::MOV_rr) { - int Offset = resolveInternalFrameIndex(MF, FrameIndex, std::nullopt); + int Offset = resolveInternalFrameIndex(MF, FrameIndex, std::nullopt, DL); - if (!MF.getSubtarget().getHasDynamicFrames()) { - WarnSize(Offset, MF, DL); - } MI.getOperand(i).ChangeToRegister(FrameReg, false); Register reg = MI.getOperand(i - 1).getReg(); BuildMI(MBB, ++II, DL, TII.get(SBF::ADD_ri), reg) @@ -112,16 +120,12 @@ bool SBFRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, } int Offset = - resolveInternalFrameIndex(MF, FrameIndex, MI.getOperand(i + 1).getImm()); - + resolveInternalFrameIndex(MF, FrameIndex, + MI.getOperand(i + 1).getImm(), DL); if (!isInt<32>(Offset)) llvm_unreachable("bug in frame offset"); - if (!MF.getSubtarget().getHasDynamicFrames()) { - WarnSize(Offset, MF, DL); - } - if (MI.getOpcode() == SBF::FI_ri) { // architecture does not really support FI_ri, replace it with // MOV_rr , frame_reg @@ -143,18 +147,19 @@ bool SBFRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, return false; } -int SBFRegisterInfo::resolveInternalFrameIndex( - const llvm::MachineFunction &MF, int FI, std::optional Imm) const { +int SBFRegisterInfo::resolveInternalFrameIndex(llvm::MachineFunction &MF, + int FI, + std::optional Imm, + const DebugLoc &DL) const { const MachineFrameInfo &MFI = MF.getFrameInfo(); const SBFFunctionInfo *SBFFuncInfo = MF.getInfo(); - int Offset = MFI.getObjectOffset(FI); + int ObjectOffset = MFI.getObjectOffset(FI); const SBFSubtarget & SubTarget = MF.getSubtarget(); - uint64_t StackSize = MFI.getStackSize(); + const uint64_t StackSize = MFI.getStackSize(); - if (!SubTarget.getHasDynamicFrames() && - SBFFuncInfo->containsFrameIndex(FI)) { - Offset = SBFRegisterInfo::FrameLength - Offset; - if (static_cast(Offset) < StackSize) { + if (!SubTarget.getHasNoStackGaps() && SBFFuncInfo->containsFrameIndex(FI)) { + ObjectOffset = SBFRegisterInfo::FrameLength - ObjectOffset; + if (static_cast(ObjectOffset) < StackSize) { dbgs() << "Error: A function call in method " << MF.getFunction().getName() << " overwrites values in the frame. Please, decrease stack usage " @@ -162,21 +167,39 @@ int SBFRegisterInfo::resolveInternalFrameIndex( << "The function call may cause undefined behavior " "during execution.\n\n"; } - return -Offset; + return -ObjectOffset; } - if (SubTarget.getHasDynamicFrames() && - SBFFuncInfo->containsFrameIndex(FI)) { - return -Offset; + if (SubTarget.getHasNoStackGaps() && SBFFuncInfo->containsFrameIndex(FI)) { + // When the stack grows up, the argument offset is off by the size of the + // object because LLVM interprets that offset zero belongs to the caller, + // not the callee. + // PS: We have incremented it in fn LowerCall at SBFISelLowering. + if (SubTarget.stackGrowsUp()) + return -(static_cast(MFI.getObjectSize(FI)) + ObjectOffset); + + return -ObjectOffset; } - Offset += Imm.value_or(0); - if (SubTarget.getHasDynamicFrames()) { - return static_cast(StackSize) + Offset; + int ElementOffset = ObjectOffset + Imm.value_or(0); + + int ObjectSize = static_cast(MFI.getObjectSize(FI)); + if (SubTarget.getHasNoStackGaps()) { + if (SubTarget.getHasDynamicFrames()) + return ElementOffset + static_cast(StackSize); + + const int V3ElementOffset = ElementOffset - static_cast(FrameLength); + const int V3ObjectOffset = ObjectOffset - static_cast(FrameLength); + warnSize(V3ElementOffset, MF, DL, SubTarget.stackGrowsUp(), V3ObjectOffset, + ObjectSize); + return V3ElementOffset; } - return Offset; + // Only sBPFv0 will reach this stage, because it has stack gaps. + warnSize(ElementOffset, MF, DL, SubTarget.stackGrowsUp(), ObjectOffset, + ObjectSize); + return ElementOffset; } Register SBFRegisterInfo::getFrameRegister(const MachineFunction &MF) const { diff --git a/llvm/lib/Target/SBF/SBFRegisterInfo.h b/llvm/lib/Target/SBF/SBFRegisterInfo.h index ee5b9f99c5fea..38315031bf532 100644 --- a/llvm/lib/Target/SBF/SBFRegisterInfo.h +++ b/llvm/lib/Target/SBF/SBFRegisterInfo.h @@ -36,8 +36,9 @@ struct SBFRegisterInfo : public SBFGenRegisterInfo { Register getFrameRegister(const MachineFunction &MF) const override; - int resolveInternalFrameIndex(const MachineFunction &MF, int FI, - std::optional Imm) const; + int resolveInternalFrameIndex(MachineFunction &MF, int FI, + std::optional Imm, + const DebugLoc &DL) const; }; } diff --git a/llvm/lib/Target/SBF/SBFSubtarget.cpp b/llvm/lib/Target/SBF/SBFSubtarget.cpp index 93979cb1c68e7..d5752531b9f07 100644 --- a/llvm/lib/Target/SBF/SBFSubtarget.cpp +++ b/llvm/lib/Target/SBF/SBFSubtarget.cpp @@ -50,6 +50,7 @@ void SBFSubtarget::initializeEnvironment(const Triple &TT) { ReverseSubImm = false; NoLddw = false; CallxRegSrc = false; + CallxRegDst = false; HasPqrClass = false; HasStoreImm = false; HasAlu32 = false; @@ -57,6 +58,8 @@ void SBFSubtarget::initializeEnvironment(const Triple &TT) { NewMemEncoding = false; HasStaticSyscalls = false; IsAbiV2 = false; + HasNoStackGaps = false; + StackGrowsUp = false; } void SBFSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) { @@ -65,9 +68,12 @@ void SBFSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) { SBFSubtarget::SBFSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS, const TargetMachine &TM) - : SBFGenSubtargetInfo(TT, cpuFromSubArch(TT, CPU), /*TuneCPU*/ cpuFromSubArch(TT, CPU), FS), InstrInfo(), - FrameLowering(initializeSubtargetDependencies(TT, cpuFromSubArch(TT, CPU), FS)), - TLInfo(TM, *this) { + : SBFGenSubtargetInfo(TT, cpuFromSubArch(TT, CPU), + /*TuneCPU*/ cpuFromSubArch(TT, CPU), FS), + InstrInfo(), FrameLowering(initializeSubtargetDependencies( + TT, cpuFromSubArch(TT, CPU), FS) + .stackGrowsUp()), + TLInfo(TM, *this) { assert(TT.getArch() == Triple::sbf && "expected Triple::sbf"); CallLoweringInfo.reset(new SBFCallLowering(*getTargetLowering())); diff --git a/llvm/lib/Target/SBF/SBFSubtarget.h b/llvm/lib/Target/SBF/SBFSubtarget.h index 19208b061f03f..712fa6bc7c9a2 100644 --- a/llvm/lib/Target/SBF/SBFSubtarget.h +++ b/llvm/lib/Target/SBF/SBFSubtarget.h @@ -76,6 +76,9 @@ class SBFSubtarget : public SBFGenSubtargetInfo { // Whether to encode destination register in Callx's src field bool CallxRegSrc; + // Whether to encode destination register in Callx's dst field + bool CallxRegDst; + // Whether we have the PQR instruction class bool HasPqrClass; @@ -91,6 +94,12 @@ class SBFSubtarget : public SBFGenSubtargetInfo { // Whether we are using AbiV2 bool IsAbiV2; + // Whether the SBF VM does not have stack gaps enabled + bool HasNoStackGaps; + + // Whether we place objects within each function frame on top of each other + bool StackGrowsUp; + std::unique_ptr CallLoweringInfo; std::unique_ptr InstSelector; std::unique_ptr Legalizer; @@ -110,17 +119,23 @@ class SBFSubtarget : public SBFGenSubtargetInfo { void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); bool getHasJmpExt() const { return HasJmpExt; } bool getHasAlu32() const { return HasAlu32; } - bool getHasDynamicFrames() const { return HasDynamicFrames; } + bool getHasDynamicFrames() const { + return HasDynamicFrames; + } + // Dynamic frames imply no stack gaps + bool getHasNoStackGaps() const { return HasNoStackGaps || HasDynamicFrames; } bool getUseDwarfRIS() const { return UseDwarfRIS; } bool getDisableNeg() const { return DisableNeg; } bool getReverseSubImm() const { return ReverseSubImm; } bool getNoLddw() const { return NoLddw; } bool getCallXRegSrc() const { return CallxRegSrc; } + bool getCallXRegDst() const { return CallxRegDst; } bool getHasPqrClass() const { return HasPqrClass; } bool getHasStoreImm() const { return HasStoreImm; } bool getHasExplicitSignExt() const { return HasExplicitSignExt; } bool getNewMemEncoding() const { return NewMemEncoding; } bool getHasStaticSyscalls() const { return HasStaticSyscalls; } + bool stackGrowsUp() const { return StackGrowsUp; } const SBFInstrInfo *getInstrInfo() const override { return &InstrInfo; } const SBFFrameLowering *getFrameLowering() const override { return &FrameLowering; diff --git a/llvm/lib/Target/SBF/SBFTargetFeatures.td b/llvm/lib/Target/SBF/SBFTargetFeatures.td index ab302f6022890..3b972c77037bf 100644 --- a/llvm/lib/Target/SBF/SBFTargetFeatures.td +++ b/llvm/lib/Target/SBF/SBFTargetFeatures.td @@ -37,6 +37,9 @@ def FeatureDisableLddw : SubtargetFeature<"no-lddw", "NoLddw", "true", def FeatureCallxRegSrc : SubtargetFeature<"callx-reg-src", "CallxRegSrc", "true", "Encode Callx destination register in the src field">; +def FeatureCallxRegDst : SubtargetFeature<"callx-reg-dst", "CallxRegDst", "true", + "Encode Callx destination register in the dst field">; + def FeaturePqrInstr : SubtargetFeature<"pqr-instr", "HasPqrClass", "true", "Enable the PQR instruction class">; @@ -56,22 +59,25 @@ def FeatureAbiV2 : SubtargetFeature<"abi-v2", "IsAbiV2", "true", "Enables AbiV2 in SBF (no-op in LLVM)">; +def FeatureNoStackGaps : SubtargetFeature<"no-stack-gaps", "HasNoStackGaps", "true", + "The SBPF VM has no stack gaps">; + +def FeatureStackGrowsUp : SubtargetFeature<"stack-grows-up", "StackGrowsUp", "true", + "Place objects within each function frame on top of each other">; + class Proc Features> : Processor; def : Proc<"generic", []>; -def : Proc<"v1", [FeatureDynamicFrames, FeatureStoreImm, FeatureJumpExt]>; +def : Proc<"v1", [FeatureDynamicFrames, FeatureNoStackGaps, FeatureJumpExt, FeatureStoreImm]>; def : Proc<"v2", [FeatureDynamicFrames, FeatureStoreImm, FeatureJumpExt, FeatureDisableLddw, FeatureNewMemEncoding, FeatureCallxRegSrc, FeaturePqrInstr, FeatureExplicitSext, - FeatureDisableNeg, FeatureReverseSubImm, ALU32]>; + FeatureDisableNeg, FeatureReverseSubImm, ALU32, FeatureNoStackGaps]>; -def : Proc<"v3", [FeatureDynamicFrames, FeatureStoreImm, FeatureJumpExt, FeatureDisableLddw, - FeatureNewMemEncoding, FeatureCallxRegSrc, FeaturePqrInstr, FeatureExplicitSext, - FeatureDisableNeg, FeatureReverseSubImm, ALU32, FeatureStaticSyscalls, FeatureRelocAbs64]>; +def : Proc<"v3", [FeatureStaticSyscalls, FeatureRelocAbs64, FeatureJumpExt, FeatureStoreImm, + FeatureCallxRegDst, FeatureNoStackGaps, FeatureStackGrowsUp]>; -def : Proc<"v4", [FeatureDynamicFrames, FeatureStoreImm, FeatureJumpExt, FeatureDisableLddw, - FeatureNewMemEncoding, FeatureCallxRegSrc, FeaturePqrInstr, FeatureExplicitSext, - FeatureDisableNeg, FeatureReverseSubImm, ALU32, FeatureStaticSyscalls, FeatureRelocAbs64, - FeatureAbiV2]>; \ No newline at end of file +def : Proc<"v4", [FeatureStaticSyscalls, FeatureRelocAbs64, FeatureStoreImm, + FeatureCallxRegDst, FeatureNoStackGaps, FeatureStackGrowsUp]>; diff --git a/llvm/test/CodeGen/BPF/reloc-2.ll b/llvm/test/CodeGen/BPF/reloc-2.ll index 50baef7faf22c..5ced421606be7 100644 --- a/llvm/test/CodeGen/BPF/reloc-2.ll +++ b/llvm/test/CodeGen/BPF/reloc-2.ll @@ -1,4 +1,5 @@ -; RUN: llc -mtriple=bpfel -filetype=obj -o %t.el < %s +; XFAIL: * +; RUN: llc -mtriple=bpfel -mcpu=v1 -filetype=obj -o %t.el < %s ; RUN: llvm-objdump -r %t.el | FileCheck --check-prefix=RELOC %s ; RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t.el | FileCheck --check-prefix=DUMP %s ; RUN: llc -mtriple=bpfeb -filetype=obj -o %t.eb < %s diff --git a/llvm/test/CodeGen/BPF/reloc-3.ll b/llvm/test/CodeGen/BPF/reloc-3.ll index e4bb18c5c286c..374dad43504e0 100644 --- a/llvm/test/CodeGen/BPF/reloc-3.ll +++ b/llvm/test/CodeGen/BPF/reloc-3.ll @@ -1,3 +1,4 @@ +; XFAIL: * ; RUN: llc -mtriple=bpfel -filetype=obj -o %t.el < %s ; RUN: llvm-readelf -r %t.el | FileCheck %s ; RUN: llc -mtriple=bpfeb -filetype=obj -o %t.eb < %s diff --git a/llvm/test/CodeGen/BPF/reloc-btf-2.ll b/llvm/test/CodeGen/BPF/reloc-btf-2.ll index 7398257e43a91..3381805d7412b 100644 --- a/llvm/test/CodeGen/BPF/reloc-btf-2.ll +++ b/llvm/test/CodeGen/BPF/reloc-btf-2.ll @@ -1,3 +1,4 @@ +; XFAIL: * ; RUN: llc -mtriple=bpfel -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s ; RUN: llc -mtriple=bpfeb -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s diff --git a/llvm/test/CodeGen/BPF/reloc-btf.ll b/llvm/test/CodeGen/BPF/reloc-btf.ll index b9f6e3af6d72c..beeb4c5913ca1 100644 --- a/llvm/test/CodeGen/BPF/reloc-btf.ll +++ b/llvm/test/CodeGen/BPF/reloc-btf.ll @@ -1,3 +1,4 @@ +; XFAIL: * ; RUN: llc -mtriple=bpfel -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s ; Function Attrs: norecurse nounwind readnone diff --git a/llvm/test/CodeGen/BPF/reloc.ll b/llvm/test/CodeGen/BPF/reloc.ll index f1b957d3eb868..00cab8d0c8b0b 100644 --- a/llvm/test/CodeGen/BPF/reloc.ll +++ b/llvm/test/CodeGen/BPF/reloc.ll @@ -1,3 +1,4 @@ +; XFAIL: * ; RUN: llc -mtriple=bpfel -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s %struct.bpf_context = type { i64, i64, i64, i64, i64, i64, i64 } diff --git a/llvm/test/CodeGen/Mips/ldexp.ll b/llvm/test/CodeGen/Mips/ldexp.ll index 3753fd567a3ed..06f04a4f560e5 100644 --- a/llvm/test/CodeGen/Mips/ldexp.ll +++ b/llvm/test/CodeGen/Mips/ldexp.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 ; RUN: llc -mtriple=mips-- -mattr=+soft-float < %s | FileCheck -check-prefix=SOFT %s +; XFAIL: * define float @ldexp_f32(i8 zeroext %x) { ; SOFT-LABEL: ldexp_f32: diff --git a/llvm/test/CodeGen/SBF/32-bit-subreg-alu.ll b/llvm/test/CodeGen/SBF/32-bit-subreg-alu.ll index 6713375dbfa4d..843b2899d1dab 100644 --- a/llvm/test/CodeGen/SBF/32-bit-subreg-alu.ll +++ b/llvm/test/CodeGen/SBF/32-bit-subreg-alu.ll @@ -1,5 +1,5 @@ ; RUN: llc -O2 -march=sbf -mattr=+alu32 < %s | FileCheck --check-prefixes=CHECK,CHECK-V0 %s -; RUN: llc -O2 -march=sbf -mcpu=v3 < %s | FileCheck --check-prefixes=CHECK,CHECK-V3 %s +; RUN: llc -O2 -march=sbf -mcpu=v3 -mattr=+alu32 < %s | FileCheck --check-prefixes=CHECK,CHECK-V3 %s ; ; int mov(int a) ; { @@ -131,7 +131,7 @@ define dso_local i32 @mov(i32 returned %a) local_unnamed_addr #0 { entry: ret i32 %a ; CHECK-V0: mov32 w{{[0-9]+}}, w{{[0-9]+}} -; CHECK-V3: mov64 w{{[0-9]+}}, w{{[0-9]+}} +; CHECK-V3: mov32 w{{[0-9]+}}, w{{[0-9]+}} } ; Function Attrs: norecurse nounwind readnone @@ -210,7 +210,7 @@ define dso_local i32 @rem(i32 %a, i32 %b) local_unnamed_addr #0 { entry: %rem = urem i32 %a, %b ; CHECK-V0: mod32 w{{[0-9]+}}, w{{[0-9]+}} -; CHECK-V3: urem32 w{{[0-9]+}}, w{{[0-9]+}} +; CHECK-V3: mod32 w{{[0-9]+}}, w{{[0-9]+}} ret i32 %rem } @@ -219,7 +219,7 @@ define dso_local i32 @rem_i(i32 %a) local_unnamed_addr #0 { entry: %rem = urem i32 %a, 15 ; CHECK-V0: mod32 w{{[0-9]+}}, 15 -; CHECK-V3: urem32 w{{[0-9]+}}, 15 +; CHECK-V3: mod32 w{{[0-9]+}}, 15 ret i32 %rem } @@ -324,6 +324,6 @@ define dso_local i32 @neg(i32 %a) local_unnamed_addr #0 { entry: %sub = sub nsw i32 0, %a ; CHECK-V0: mov32 w{{[0-9]+}}, w{{[0-9]+}} -; CHECK-V3: mov64 w{{[0-9]+}}, w{{[0-9]+}} +; CHECK-V3: mov32 w{{[0-9]+}}, w{{[0-9]+}} ret i32 %sub } diff --git a/llvm/test/CodeGen/SBF/CORE/simplifypatable-nullptr.ll b/llvm/test/CodeGen/SBF/CORE/simplifypatable-nullptr.ll index c92249161de63..c261f2a396289 100644 --- a/llvm/test/CodeGen/SBF/CORE/simplifypatable-nullptr.ll +++ b/llvm/test/CodeGen/SBF/CORE/simplifypatable-nullptr.ll @@ -1,4 +1,4 @@ -; RUN: llc -sbf-enable-btf-emission -O2 -march=sbf -mcpu=v3 < %s | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -O2 -march=sbf -mcpu=v2 < %s | FileCheck %s ; Source code: ; struct t3 { ; int i; diff --git a/llvm/test/CodeGen/SBF/call_internal.ll b/llvm/test/CodeGen/SBF/call_internal.ll index d4e1dc7844fd4..bc2230a54b823 100644 --- a/llvm/test/CodeGen/SBF/call_internal.ll +++ b/llvm/test/CodeGen/SBF/call_internal.ll @@ -1,8 +1,8 @@ -; RUN: llc < %s -march=sbf --show-mc-encoding | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-V0 %s -; RUN: llc -march=sbf --filetype=obj -o - %s | llvm-objdump -d - | FileCheck --check-prefixes=CHECK-OBJ,CHECK-OBJ-V0 %s -; RUN: llc < %s -march=sbf -mcpu=v3 --show-mc-encoding | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-V3 %s +; RUN: llc < %s -march=sbf --show-mc-encoding | FileCheck --check-prefixes=CHECK-ASM %s +; RUN: llc -march=sbf --filetype=obj -o - %s | llvm-objdump -d - | FileCheck --check-prefixes=CHECK-OBJ %s +; RUN: llc < %s -march=sbf -mcpu=v3 --show-mc-encoding | FileCheck --check-prefixes=CHECK-ASM %s ; RUN: llc -march=sbf -mcpu=v3 --filetype=obj -o - %s | llvm-objdump -d - -; | FileCheck --check-prefixes=CHECK-OBJ,CHECK-OBJ-V3 %s +; | FileCheck --check-prefixes=CHECK-OBJ %s @.str = private unnamed_addr constant [5 x i8] c"foo\0A\00", align 1 @@ -16,11 +16,9 @@ entry: ; Function Attrs: nounwind define dso_local i64 @entrypoint(ptr noundef %input) local_unnamed_addr #1 { entry: -; CHECK-ASM-V0: call 1811268606 # encoding: [0x85,0x00,0x00,0x00,0xfe,0xc3,0xf5,0x6b] -; CHECK-ASM-V3: syscall 1811268606 # encoding: [0x95,0x00,0x00,0x00,0xfe,0xc3,0xf5,0x6b] +; CHECK-ASM: call 1811268606 # encoding: [0x85,0x00,0x00,0x00,0xfe,0xc3,0xf5,0x6b] -; CHECK-OBJ-V0: 85 00 00 00 fe c3 f5 6b call 0x6bf5c3fe -; CHECK-OBJ-V3: 95 00 00 00 fe c3 f5 6b syscall 0x6bf5c3fe +; CHECK-OBJ: 85 00 00 00 fe c3 f5 6b call 0x6bf5c3fe tail call void inttoptr (i64 1811268606 to ptr)(ptr noundef nonnull @.str, i64 noundef 4) #3 %add.ptr = getelementptr inbounds i8, ptr %input, i64 4 diff --git a/llvm/test/CodeGen/SBF/callx.ll b/llvm/test/CodeGen/SBF/callx.ll index 5923cdc155843..e59071537d958 100644 --- a/llvm/test/CodeGen/SBF/callx.ll +++ b/llvm/test/CodeGen/SBF/callx.ll @@ -2,6 +2,8 @@ ; RUN: | FileCheck %s -check-prefixes=CHECK-v0 ; RUN: llc < %s -march=sbf --mcpu=v2 --show-mc-encoding \ ; RUN: | FileCheck %s -check-prefixes=CHECK-v2 +; RUN: llc < %s -march=sbf --mcpu=v3 --show-mc-encoding \ +; RUN: | FileCheck %s -check-prefixes=CHECK-v3 ; source: ; int test(int (*f)(void)) { return f(); } @@ -11,6 +13,7 @@ entry: %call = tail call i32 %f() #1 ; CHECK-v0: callx r{{[0-9]+}} # encoding: [0x8d,0x00,0x00,0x00,0x0{{[0-9]|a|b}},0x00,0x00,0x00] ; CHECK-v2: callx r{{[0-9]+}} # encoding: [0x8d,0x{{[0-9]}}0,0x00,0x00,0x00,0x00,0x00,0x00] +; CHECK-v3: callx r{{[0-9]+}} # encoding: [0x8d,0x0{{[0-9]}},0x00,0x00,0x00,0x00,0x00,0x00] ret i32 %call } diff --git a/llvm/test/CodeGen/SBF/dynamic_stack_frame_add_not_sub.ll b/llvm/test/CodeGen/SBF/dynamic_stack_frame_add_and_sub.ll similarity index 60% rename from llvm/test/CodeGen/SBF/dynamic_stack_frame_add_not_sub.ll rename to llvm/test/CodeGen/SBF/dynamic_stack_frame_add_and_sub.ll index f39e992055b9f..79c2f24de1b96 100644 --- a/llvm/test/CodeGen/SBF/dynamic_stack_frame_add_not_sub.ll +++ b/llvm/test/CodeGen/SBF/dynamic_stack_frame_add_and_sub.ll @@ -13,7 +13,6 @@ define i32 @test_func(ptr noundef %vec, i32 noundef %idx) #0 { ; CHECK-LABEL: test_func: ; CHECK: add64 r10, -128 -; CHECK-NOT: add64 r10, 128 entry: %vec.addr = alloca ptr, align 8 %idx.addr = alloca i512, align 4 @@ -28,4 +27,26 @@ entry: store i32 %sub, ptr %arrayidx, align 4 %3 = load i32, ptr %idx.addr, align 4 ret i32 %3 +} + +declare i64 @read_ptr(ptr %a); + +define i64 @test_func_4096(i64 %idx) { +; CHECK-LABEL: test_func_4096 +; CHECK: add64 r10, -4096 +entry: + %large_var = alloca [4096 x i8], align 8 + %val = call i64 @read_ptr(ptr %large_var) + ret i64 %val +} + +define i64 @test_func_4128(i64 %idx) { +; CHECK-LABEL: test_func_4128 +; CHECK: add64 r10, -4160 +; The stack is aligned at 64, so we bump 64 to have a stack size of 4096+64=4160, +; so we can fit the 4128 bytes of the array. +entry: + %large_var = alloca [4128 x i8], align 8 + %val = call i64 @read_ptr(ptr %large_var) + ret i64 %val } \ No newline at end of file diff --git a/llvm/test/CodeGen/SBF/f64-intrinsics.ll b/llvm/test/CodeGen/SBF/f64-intrinsics.ll index c1203dbe14777..cc1381b3b8bae 100644 --- a/llvm/test/CodeGen/SBF/f64-intrinsics.ll +++ b/llvm/test/CodeGen/SBF/f64-intrinsics.ll @@ -1,5 +1,6 @@ ; RUN: llc -march=sbf -mattr=+alu32 < %s | FileCheck -check-prefix=CHECK32 %s ; RUN: llc -march=sbf < %s | FileCheck -check-prefix=CHECK64 %s +; RUN: llc -march=sbf -mcpu=v3 -mattr=+alu32 < %s | FileCheck -check-prefix=CHECK32 %s ; TODO: Add much more coverage. Currently this a sign extension regression ; test (SBFTargetLowering::shouldSignExtendTypeInLibCall). @@ -22,3 +23,34 @@ define double @powi_f64(double %a, i32 %b) nounwind { ret double %1 } +define double @uitofp64(i32 %arg) nounwind { +; CHECK32-LABEL: uitofp64: +; CHECK32: # %bb.0: +; CHECK32-NEXT: call __floatunsidf +; CHECK32-NEXT: exit +; +; CHECK64-LABEL: uitofp64: +; CHECK64: # %bb.0: +; CHECK64-NEXT: lsh64 r1, 32 +; CHECK64-NEXT: rsh64 r1, 32 +; CHECK64-NEXT: call __floatunsidf +; CHECK64-NEXT: exit + %1 = uitofp i32 %arg to double + ret double %1 +} + +define double @sitofp64(i32 %arg) nounwind { +; CHECK32-LABEL: sitofp64: +; CHECK32: # %bb.0: +; CHECK32-NEXT: call __floatsidf +; CHECK32-NEXT: exit +; +; CHECK64-LABEL: sitofp64: +; CHECK64: # %bb.0: +; CHECK64-NEXT: lsh64 r1, 32 +; CHECK64-NEXT: arsh64 r1, 32 +; CHECK64-NEXT: call __floatsidf +; CHECK64-NEXT: exit + %1 = sitofp i32 %arg to double + ret double %1 +} diff --git a/llvm/test/CodeGen/SBF/many_args_new_conv.ll b/llvm/test/CodeGen/SBF/many_args_new_conv.ll index 20e1922ea9c3c..88a4961b01af3 100644 --- a/llvm/test/CodeGen/SBF/many_args_new_conv.ll +++ b/llvm/test/CodeGen/SBF/many_args_new_conv.ll @@ -1,7 +1,7 @@ -; RUN: llc -O2 -march=sbf -mcpu=v1 < %s | FileCheck %s -; RUN: llc -O2 -mtriple=sbpfv1-solana-solana < %s | FileCheck %s -; RUN: llc -O2 -march=sbf -mcpu=v1 -mattr=+mem-encoding < %s | FileCheck %s -; RUN: llc -O3 -march=sbf -mcpu=v3 < %s | FileCheck --check-prefix=CHECK-V3 %s +; RUN: llc -march=sbf -mcpu=v1 < %s | FileCheck %s +; RUN: llc -mtriple=sbpfv1-solana-solana < %s | FileCheck %s +; RUN: llc -march=sbf -mcpu=v1 -mattr=+mem-encoding < %s | FileCheck %s +; RUN: llc -march=sbf -mcpu=v3 < %s | FileCheck --check-prefix=CHECK-V3 %s ; Function Attrs: nounwind uwtable define i32 @caller_no_alloca(i32 %a, i32 %b, i32 %c) #0 { @@ -10,8 +10,6 @@ entry: ; No changes to the stack pointer ; CHECK-NOT: add64 r10 -; Add zero to stack pointer from V3 onwards -; CHECK-V3: add64 r10, 0 ; Saving arguments on the stack ; CHECK: stdw [r10 - 40], 60 @@ -19,6 +17,13 @@ entry: ; CHECK: stdw [r10 - 24], 50 ; CHECK: stdw [r10 - 16], 4 ; CHECK: stdw [r10 - 8], 3 + +; CHECK-V3: stdw [r10 + 32], 60 +; CHECK-V3: stdw [r10 + 24], 55 +; CHECK-V3: stdw [r10 + 16], 50 +; CHECK-V3: stdw [r10 + 8], 4 +; CHECK-V3: stdw [r10 + 0], 3 + ; CHECK: mov64 r4, 1 ; CHECK: mov64 r5, 2 ; CHECK: call callee_alloca @@ -30,8 +35,12 @@ entry: ; Function Attrs: nounwind uwtable define i32 @caller_alloca(i32 %a, i32 %b, i32 %c) #0 { ; CHECK-LABEL: caller_alloca -; CHECK: add64 r10, -64 -; CHECK: ldxw r1, [r10 + 60] +; CHECK: add64 r10, -1088 +; CHECK: ldxw r1, [r10 + 120] +; 1088 - 1024 + 56 = 120 + +; CHECK-V3: ldxw r1, [r10 - 4040] +; -4096 + 8*7 = -4040 ; Saving arguments in the callee's frame @@ -45,13 +54,28 @@ define i32 @caller_alloca(i32 %a, i32 %b, i32 %c) #0 { ; CHECK: stdw [r10 - 16], 4 ; Offset in the callee: frame_size - 8 ; CHECK: stdw [r10 - 8], 3 + +; Offset in the callee: -frame_size + 32 +; CHECK-V3: stdw [r10 + 32], 60 +; Offset in the callee: -frame_size + 24 +; CHECK-V3: stdw [r10 + 24], 55 +; Offset in the callee: -frame_size + 16 +; CHECK-V3: stdw [r10 + 16], 50 +; Offset in the callee: -frame_size + 8 +; CHECK-V3: stdw [r10 + 8], 4 +; Offset in the callee: -frame_size + 0 +; CHECK-V3: stdw [r10 + 0], 3 + ; CHECK: mov64 r4, 1 ; CHECK: mov64 r5, 2 ; CHECK: call callee_no_alloca +; CHECK: ldxw r1, [r10 + 48] +; CHECK-V3: ldxw r1, [r10 - 3072] entry: - %g = alloca i32 - %g1 = load i32, ptr %g + %g = alloca [1024 x i8], align 8 + %off = getelementptr i64, ptr %g, i64 7 + %g1 = load i32, ptr %off %call = tail call i32 @callee_no_alloca(i32 %g1, i32 %b, i32 %c, i32 1, i32 2, i32 3, i32 4, i32 50, i32 55, i32 60) #3 %h = alloca i128 %h1 = load i32, ptr %h @@ -62,19 +86,30 @@ entry: ; Function Attrs: nounwind uwtable define i32 @callee_alloca(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %p, i32 %y, i32 %a1, i32 %a2) #1 { ; CHECK-LABEL: callee_alloca -; CHECK: add64 r10, -128 +; CHECK: add64 r10, -2112 + ; Loading arguments -; CHECK: ldxdw r2, [r10 + 120] -; CHECK: ldxdw r2, [r10 + 112] -; CHECK: ldxdw r2, [r10 + 104] -; CHECK: ldxdw r2, [r10 + 96] -; CHECK: ldxdw r2, [r10 + 88] +; CHECK: ldxdw r2, [r10 + 2104] +; CHECK: ldxdw r2, [r10 + 2096] +; CHECK: ldxdw r2, [r10 + 2088] +; CHECK: ldxdw r2, [r10 + 2080] +; CHECK: ldxdw r2, [r10 + 2072] ; Loading allocated i32 ; CHECK: ldxw r0, [r10 + 24] + +; CHECK-V3: ldxdw r2, [r10 - 4096] +; CHECK-V3: ldxdw r2, [r10 - 4088] +; CHECK-V3: ldxdw r2, [r10 - 4080] +; CHECK-V3: ldxdw r2, [r10 - 4072] +; CHECK-V3: ldxdw r2, [r10 - 4064] +; Loading allocated i32 +; CHECK-V3: ldxw r0, [r10 - 4056] + + ; CHECK-NOT: add64 r10, 128 entry: - %o = alloca i512 + %o = alloca [2048 x i8], align 8 %g = add i32 %a, %b %h = sub i32 %g, %c %i = add i32 %h, %d @@ -93,6 +128,8 @@ entry: define i32 @callee_no_alloca(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %p, i32 %y, i32 %a1, i32 %a2) #1 { ; CHECK-LABEL: callee_no_alloca ; CHECK: add64 r10, -64 +; CHECK-V3-NOT: add64 r10, 64 + ; Loading arguments ; CHECK: ldxdw r1, [r10 + 56] ; CHECK: ldxdw r1, [r10 + 48] @@ -100,6 +137,13 @@ define i32 @callee_no_alloca(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 ; CHECK: ldxdw r1, [r10 + 32] ; CHECK: ldxdw r1, [r10 + 24] +; Loading arguments +; CHECK-V3: ldxdw r1, [r10 - 4096] +; CHECK-V3: ldxdw r1, [r10 - 4088] +; CHECK-V3: ldxdw r1, [r10 - 4080] +; CHECK-V3: ldxdw r1, [r10 - 4072] +; CHECK-V3: ldxdw r1, [r10 - 4064] + ; CHECK-NOT: add64 r10, 64 entry: %g = add i32 %a, %b diff --git a/llvm/test/CodeGen/SBF/many_args_value_size.ll b/llvm/test/CodeGen/SBF/many_args_value_size.ll index 71c59c60b0914..bf9d3b019f8e1 100644 --- a/llvm/test/CodeGen/SBF/many_args_value_size.ll +++ b/llvm/test/CodeGen/SBF/many_args_value_size.ll @@ -1,5 +1,6 @@ ; RUN: llc -march=sbf -mcpu=v2 < %s | FileCheck %s ; RUN: llc -mtriple=sbpfv2-solana-solana < %s | FileCheck %s +; RUN: llc -march=sbf -mcpu=v3 -mattr=+alu32 < %s | FileCheck --check-prefixes=CHECK-V3 %s define i64 @test_func(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e) { start: @@ -10,6 +11,11 @@ start: ; CHECK: stw [r10 - 12], 65516 ; CHECK: stw [r10 - 4], 5 +; CHECK-V3: stdw [r10 + 24], 5400 +; CHECK-V3: stw [r10 + 16], 300 +; CHECK-V3: stw [r10 + 8], 65516 +; CHECK-V3: stw [r10 + 0], 5 + %res = call i64 @func(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i8 5, i16 -20, i32 300, i64 5400) ret i64 %res } @@ -18,6 +24,7 @@ define i64 @func(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i8 %b8, i16 %b16, i32 % start: ; CHECK-LABEL: func: ; CHECK: add64 r10, -64 +; CHECK-V3-NOT: add64 r10, 64 %a1 = add i64 %a, %b %a2 = sub i64 %a1, %c %a3 = mul i64 %a2, %d @@ -25,19 +32,27 @@ start: ; -64 + 32 = -32, so this is 5400 in %a5 ; CHECK: ldxdw r4, [r10 + 32] +; 4096 - 4072 = 24 +; CHECK-V3: ldxdw r4, [r10 - 4072] ; -64 + 60 = -4, so this is 5 in %b8 ; CHECK: ldxw w4, [r10 + 60] +; 4096 - 4096 = 0 +; CHECK-V3: ldxw w4, [r10 - 4096] %c0 = trunc i64 %a to i8 %b1 = add i8 %b8, %c0 ; -64 + 52 = -12, so this is -20 in %b16 -; ldxw w1, [r10 + 52] +; CHECK: ldxw w1, [r10 + 52] +; 4096 - 4088 = 8 +; CHECK-V3: ldxw w1, [r10 - 4088] %c1 = trunc i64 %b to i16 %b2 = add i16 %b16, %c1 ; -64 + 44 = -20, so this is 300 in %b32 ; CHECK: ldxw w1, [r10 + 44] +; 4096 - 4080 = 16 +; CHECK-V3: ldxw w1, [r10 - 4080] %c2 = trunc i64 %c to i32 %b3 = add i32 %b32, %c2 diff --git a/llvm/test/CodeGen/SBF/objdump_trivial.ll b/llvm/test/CodeGen/SBF/objdump_trivial.ll index 388c3be7a373b..f931e195164da 100644 --- a/llvm/test/CodeGen/SBF/objdump_trivial.ll +++ b/llvm/test/CodeGen/SBF/objdump_trivial.ll @@ -1,10 +1,10 @@ -; RUN: llc -march=sbf -mcpu=v3 -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s +; RUN: llc -march=sbf -mcpu=v3 -mattr=+alu32 -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s ; CHECK: jslt r1, 0x0, ; CHECK: call 0x1 -; CHECK: return +; CHECK: exit ; CHECK: call 0x2 -; CHECK: return +; CHECK: exit define void @foo(i32 %a) { %b = icmp sgt i32 %a, -1 diff --git a/llvm/test/CodeGen/SBF/reloc-btf.ll b/llvm/test/CodeGen/SBF/reloc-btf.ll index 579fba7cc99ac..b31342b425905 100644 --- a/llvm/test/CodeGen/SBF/reloc-btf.ll +++ b/llvm/test/CodeGen/SBF/reloc-btf.ll @@ -6,7 +6,7 @@ entry: ret i32 0, !dbg !11 } -; CHECK-RELOC: file format elf64-sbf +; CHECK-RELOC: file format elf64-bpf ; CHECK-RELOC: RELOCATION RECORDS FOR [.debug_info]: ; CHECK-RELOC: R_SBF_64_ABS32 .debug_abbrev ; CHECK-RELOC: R_SBF_64_ABS64 diff --git a/llvm/test/CodeGen/SBF/reloc.ll b/llvm/test/CodeGen/SBF/reloc.ll index 9c0b789151321..9f4902114bbe6 100644 --- a/llvm/test/CodeGen/SBF/reloc.ll +++ b/llvm/test/CodeGen/SBF/reloc.ll @@ -32,7 +32,7 @@ define i32 @bpf_prog1(%struct.bpf_context* nocapture %ctx) #0 section "events/ne ;