From 59e0f95a10fb52b4dfeab81b67ab3a5061aede58 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Fri, 29 May 2026 08:32:18 -0700 Subject: [PATCH] Fix Linux AArch64 build and add CI for that platform (#7273) The `--dump-cpp-ast` file tests strip references to Clang builtins so that the expected output is target-independent. The filter anchored a `__`-prefixed builtin identifier on a preceding space or quote, which matches the x86-64 `__va_list_tag` spelling but not the AArch64 `std::__va_list`, where `__` is preceded by the `::` namespace qualifier. That left a single `RecordType 'std::__va_list'` line unfiltered on AArch64, producing a spurious autoupdate diff for `thunk_ast.carbon`. Anchor the match on a preceding `:` as well so namespace-qualified builtins are also filtered. Carbon's test workflow covered Linux on x86-64 and macOS on AArch64, but had no Linux AArch64 coverage, so AArch64-specific issues that don't reproduce on macOS could land unnoticed. Add an `ubuntu-22.04-arm` runner to the matrix. The release used for Linux does not publish the monolithic `LLVM-*-Linux-ARM64` package, only a `clang+llvm-*-aarch64-linux-gnu` community build with a smaller tool set, so the Ubuntu setup now selects the tarball by `runner.arch`. The prune step uses `rm -f` since the two packages do not ship an identical set of tools to remove. Assisted-by: Claude Code with Claude Opus 4.7 --- .github/actions/build-setup-ubuntu/action.yml | 29 +++++++++++++++---- .github/workflows/tests.yaml | 5 ++-- toolchain/testing/file_test.cpp | 6 ++-- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/.github/actions/build-setup-ubuntu/action.yml b/.github/actions/build-setup-ubuntu/action.yml index 7101377de999..06a3b7d56449 100644 --- a/.github/actions/build-setup-ubuntu/action.yml +++ b/.github/actions/build-setup-ubuntu/action.yml @@ -22,6 +22,20 @@ runs: # to save time. large-packages: false + # Select the LLVM release - by the cache key and the download. + # + # x86-64 uses the LLVM 19 monolithic package. That release only + # published a smaller community build for Linux AArch64, so AArch64 uses + # the official monolithic package, first available in LLVM 20. + - name: Select LLVM release + shell: bash + run: | + if [[ "${{ runner.arch }}" == "ARM64" ]]; then + echo "LLVM_RELEASE=20.1.8" >> "$GITHUB_ENV" + else + echo "LLVM_RELEASE=19.1.7" >> "$GITHUB_ENV" + fi + # Cache and install a recent version of LLVM. This uses the GitHub action # cache to avoid directly downloading on each iteration and improve # reliability. @@ -30,15 +44,16 @@ runs: uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: ~/llvm - key: LLVM-19.1.7-Cache-ubuntu-${{ runner.arch }} + key: LLVM-${{ env.LLVM_RELEASE }}-Cache-ubuntu-${{ runner.arch }} - name: Download LLVM and Clang installation if: steps.cache-llvm-ubuntu.outputs.cache-hit != 'true' shell: bash run: | cd ~ - LLVM_RELEASE=19.1.7 - LLVM_TARBALL_NAME=LLVM-$LLVM_RELEASE-Linux-X64 + # `LLVM_RELEASE` comes from the "Select LLVM release" step; `runner.arch` + # (`X64`/`ARM64`) matches the package's arch suffix. + LLVM_TARBALL_NAME=LLVM-$LLVM_RELEASE-Linux-${{ runner.arch }} LLVM_PATH=~/llvm echo "*** Downloading $LLVM_RELEASE" wget --show-progress=off "https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_RELEASE/$LLVM_TARBALL_NAME.tar.xz" @@ -50,10 +65,12 @@ runs: echo "*** Testing `clang++ --version`" $LLVM_PATH/bin/clang++ --version # The installation contains *huge* parts of LLVM we don't need for the - # toolchain. Prune them here to keep our cache small. + # toolchain. Prune them here to keep our cache small. x86-64 and + # AArch64 use different LLVM releases whose tool sets differ, so `-f` + # ignores entries that are absent from a given package. echo "*** Cleaning the 'llvm' directory" - rm $LLVM_PATH/lib/{*.a,*.so,*.so.*} - rm $LLVM_PATH/bin/{flang-*,mlir-*,clang-{scan-deps,check,repl},*-test,llvm-{lto*,reduce,bolt*,exegesis,jitlink},bugpoint,opt,llc} + rm -f $LLVM_PATH/lib/{*.a,*.so,*.so.*} + rm -f $LLVM_PATH/bin/{flang-*,mlir-*,clang-{scan-deps,check,repl},*-test,llvm-{lto*,reduce,bolt*,exegesis,jitlink},bugpoint,opt,llc} echo "*** Size of the 'llvm' directory" du -hs $LLVM_PATH diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index a6d24627d2a0..676837c3cd2d 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -27,8 +27,9 @@ jobs: matrix.config.name) || '' }} (${{ matrix.runner }}) strategy: matrix: - # Test a recent version of each supported OS. - runner: ['ubuntu-22.04', 'macos-14'] + # Test a recent version of each supported OS, covering both x86-64 and + # AArch64: Linux on x86-64 and AArch64, and macOS on AArch64. + runner: ['ubuntu-22.04', 'ubuntu-22.04-arm', 'macos-14'] # Create a synthetic matrix dimension with the event name for filtering. event: ['${{ github.event_name }}'] config: diff --git a/toolchain/testing/file_test.cpp b/toolchain/testing/file_test.cpp index b69d4c41c35b..3aa60b2c4e06 100644 --- a/toolchain/testing/file_test.cpp +++ b/toolchain/testing/file_test.cpp @@ -308,9 +308,11 @@ static auto DoClangASTCheckReplacements(std::string& check_line) -> void { return; } - // Filter out references to builtins. + // Filter out references to builtins. The `__`-prefixed identifier may be + // namespace-qualified, such as the AArch64 `std::__va_list`, so a preceding + // `:` also anchors the match. static const RE2 is_builtin_referring_re( - R"(`-BuiltinType |[ ']__[a-zA-Z]|\| `\-PointerType 0x[a-f0-9]+ 'char \*'$)"); + R"(`-BuiltinType |[ ':]__[a-zA-Z]|\| `\-PointerType 0x[a-f0-9]+ 'char \*'$)"); if (RE2::PartialMatch(check_line, is_builtin_referring_re)) { check_line.clear(); return;