From 201688e0e5297592281379a55568b16a13c0b8f0 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Sat, 8 Aug 2026 09:34:10 +0900 Subject: ci: run Windows ARM64 tests on native runners Currently, ARM64 builds are cross-compiled on x64 Windows runners and the tests are skipped. With this change, static and shared ARM64 builds run on windows-11-arm runners, allowing the test suite to execute natively. Running the tests natively also exposes incorrect code generation by the MSVC ARM64 optimizer when the generic bn_ct_ne_zero() helper is inlined. Work around this by using the _CountLeadingZeros64() intrinsic on MSVC ARM64, avoiding the affected optimizer transformation and allowing the tests to pass. --- .github/workflows/windows.yml | 26 ++++++++++++++++++++++---- patches/win32_arm64_bn_arch.h.patch | 21 +++++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 patches/win32_arm64_bn_arch.h.patch diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 4814ffa..27e6633 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -22,8 +22,15 @@ jobs: fail-fast: false matrix: os: ["windows-2022", "windows-2025"] - arch: ["ARM64", "x64", "Win32"] + arch: ["x64", "Win32"] shared: ["ON", "OFF"] + include: + - os: "windows-11-arm" + arch: "ARM64" + shared: "ON" + - os: "windows-11-arm" + arch: "ARM64" + shared: "OFF" steps: - name: "Checkout repository" uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -53,12 +60,24 @@ jobs: if ($LASTEXITCODE -ne 0) { throw "IO::Socket::SSL::Utils is unavailable" } + + $vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe' + $component = if ('${{ matrix.arch }}' -eq 'ARM64') { + 'Microsoft.VisualStudio.Component.VC.Tools.ARM64' + } else { + 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64' + } + $version = & $vswhere -latest -products * -requires $component -property installationVersion + if (-not $version) { + throw "No Visual Studio installation with $component found" + } + $major = $version.Split('.')[0] $generator = cmake --help | - Select-String '^\s*\*?\s*(Visual Studio \d+ \d+)' | + Select-String "^\s*\*?\s*(Visual Studio $major \d+)" | Select-Object -First 1 | ForEach-Object { $_.Matches[0].Groups[1].Value } if (-not $generator) { - throw "No Visual Studio CMake generator found" + throw "No CMake generator found for Visual Studio $major" } Write-Host "Using generator: $generator" cmake -Bbuild -G "$generator" -A ${{ matrix.arch }} -D BUILD_SHARED_LIBS=${{ matrix.shared }} -D CMAKE_INSTALL_PREFIX=../local "-DPERL_EXECUTABLE=$perl" @@ -68,7 +87,6 @@ jobs: run: cmake --build build --config Release - name: "Test" - if: matrix.arch != 'ARM64' shell: cmd run: ctest --test-dir build -C Release --output-on-failure diff --git a/patches/win32_arm64_bn_arch.h.patch b/patches/win32_arm64_bn_arch.h.patch new file mode 100644 index 0000000..427ed94 --- /dev/null +++ b/patches/win32_arm64_bn_arch.h.patch @@ -0,0 +1,21 @@ +--- crypto/bn/arch/aarch64/bn_arch.h.orig ++++ crypto/bn/arch/aarch64/bn_arch.h +@@ -20,4 +20,17 @@ + #ifndef HEADER_BN_ARCH_H + #define HEADER_BN_ARCH_H +- ++#if defined(_MSC_VER) && defined(_M_ARM64) ++ ++#include ++ ++#define HAVE_BN_CT_NE_ZERO ++ ++static inline int ++bn_ct_ne_zero(BN_ULONG w) ++{ ++ return 1U ^ (_CountLeadingZeros64((unsigned __int64)w) >> 6); ++} ++ ++#endif ++ + #ifndef OPENSSL_NO_ASM -- cgit v1.2.3-55-g6feb