From ebea2aa2aeda5d2dd401c5301ca2c019be812bc2 Mon Sep 17 00:00:00 2001 From: Damyan Pepper Date: Wed, 15 Jul 2026 10:55:10 -0700 Subject: [PATCH 01/16] Allow ARM64 builds on any Windows runner Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 94ff14fb-6023-4436-8382-29a19a4c54b0 --- .../workflows/build-and-test-callable.yaml | 166 +++++++++++++++--- docs/offload-distribution.md | 7 + 2 files changed, 152 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build-and-test-callable.yaml b/.github/workflows/build-and-test-callable.yaml index fbfa2e3e5..4500db5e8 100644 --- a/.github/workflows/build-and-test-callable.yaml +++ b/.github/workflows/build-and-test-callable.yaml @@ -126,14 +126,15 @@ jobs: build: permissions: checks: write - # When SplitBuild is true, build on any available runner of - # the right architecture. Otherwise, build on the GPU runner. + # When SplitBuild is true, build on any available runner that can produce + # the requested target. windows-qc targets ARM64 but may cross-compile on + # an X64 Windows builder. Otherwise, build on the GPU runner. runs-on: >- ${{ fromJSON( inputs.SplitBuild != true && format('["self-hosted", "hlsl-{0}"]', inputs.SKU) || inputs.SKU == 'windows-qc' - && '["self-hosted", "ARM64", "Windows"]' + && '["self-hosted", "Windows"]' || inputs.SKU == 'macos' && '["self-hosted", "hlsl-macos"]' || '["self-hosted", "Windows", "X64"]' @@ -168,16 +169,67 @@ jobs: ref: main path: golden-images fetch-depth: 1 - - name: Setup Windows x64 - if: inputs.OS == 'windows' && runner.arch != 'ARM64' + - name: Setup Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + pip-install: -r ${{ github.workspace }}/OffloadTest/test/requirements.txt + - name: Setup Windows host tools + if: >- + inputs.OS == 'windows' + && inputs.SplitBuild == true + && inputs.SKU == 'windows-qc' + && runner.arch != 'ARM64' uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main with: arch: amd64 - - name: Setup Windows - if: inputs.OS == 'windows' && runner.arch == 'ARM64' + - name: Build native host tools + if: >- + inputs.OS == 'windows' + && inputs.SplitBuild == true + && inputs.SKU == 'windows-qc' + && runner.arch != 'ARM64' + shell: bash + run: | + set -euxo pipefail + + cmake -G Ninja \ + -S "$GITHUB_WORKSPACE/DXC" \ + -B "$GITHUB_WORKSPACE/DXC/host-build" \ + -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_ENABLE_ASSERTIONS=Off \ + -C "$GITHUB_WORKSPACE/DXC/cmake/caches/PredefinedParams.cmake" \ + -C "$GITHUB_WORKSPACE/OffloadTest/cmake/caches/sccache.cmake" \ + -DHLSL_DISABLE_SOURCE_GENERATION=On + cmake --build "$GITHUB_WORKSPACE/DXC/host-build" \ + --target llvm-tblgen clang-tblgen llvm-config + + cmake -G Ninja \ + -S "$GITHUB_WORKSPACE/llvm-project/llvm" \ + -B "$GITHUB_WORKSPACE/llvm-project/host-build" \ + -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_ENABLE_ASSERTIONS=Off \ + -DLLVM_ENABLE_PROJECTS=clang \ + -DLLVM_TARGETS_TO_BUILD=Native \ + -C "$GITHUB_WORKSPACE/OffloadTest/cmake/caches/sccache.cmake" + cmake --build "$GITHUB_WORKSPACE/llvm-project/host-build" \ + --target llvm-tblgen clang-tblgen llvm-config + - name: Setup Windows x64 target + if: inputs.OS == 'windows' && inputs.SKU != 'windows-qc' + uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main + with: + arch: amd64 + - name: Setup Windows ARM64 target + if: inputs.OS == 'windows' && inputs.SKU == 'windows-qc' uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main with: arch: arm64 + - name: Report Windows build architecture + if: inputs.OS == 'windows' + shell: bash + run: | + echo "Runner architecture: ${{ runner.arch }}" + echo "MSVC host architecture: ${VSCMD_ARG_HOST_ARCH:-unknown}" + echo "MSVC target architecture: ${VSCMD_ARG_TGT_ARCH:-unknown}" # When SplitBuild is enabled, force clang into the build set even if # the TestTarget doesn't use it. Reason: install-distribution depends # on clang (it ships in the install prefix), so if clang isn't part @@ -189,24 +241,96 @@ jobs: shell: bash if: contains(inputs.TestTarget, 'clang') || inputs.SplitBuild == true run: echo TEST_CLANG=On >> $GITHUB_OUTPUT - - name: Setup Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - with: - pip-install: -r ${{ github.workspace }}/OffloadTest/test/requirements.txt - name: Build DXC + shell: bash run: | - cd DXC - mkdir build - cd build - cmake -G Ninja -DCMAKE_BUILD_TYPE=${{ inputs.BuildType }} -DLLVM_ENABLE_ASSERTIONS=On -C ${{ github.workspace }}/DXC/cmake/caches/PredefinedParams.cmake -C ${{ github.workspace }}/OffloadTest/cmake/caches/sccache.cmake -DHLSL_DISABLE_SOURCE_GENERATION=On ${{ github.workspace }}/DXC/ - ninja + set -euxo pipefail + cross_args=() + if [ '${{ inputs.SplitBuild }}' = 'true' ] \ + && [ '${{ inputs.SKU }}' = 'windows-qc' ] \ + && [ '${{ runner.arch }}' != 'ARM64' ]; then + cross_args=( + -DCMAKE_SYSTEM_NAME=Windows + -DCMAKE_SYSTEM_PROCESSOR=ARM64 + "-DLLVM_NATIVE_BUILD=$GITHUB_WORKSPACE/DXC/host-build" + "-DLLVM_TABLEGEN=$GITHUB_WORKSPACE/DXC/host-build/bin/llvm-tblgen.exe" + "-DCLANG_TABLEGEN=$GITHUB_WORKSPACE/DXC/host-build/bin/clang-tblgen.exe" + ) + fi + cmake -G Ninja \ + -S "$GITHUB_WORKSPACE/DXC" \ + -B "$GITHUB_WORKSPACE/DXC/build" \ + -DCMAKE_BUILD_TYPE=${{ inputs.BuildType }} \ + -DLLVM_ENABLE_ASSERTIONS=On \ + -C "$GITHUB_WORKSPACE/DXC/cmake/caches/PredefinedParams.cmake" \ + -C "$GITHUB_WORKSPACE/OffloadTest/cmake/caches/sccache.cmake" \ + -DHLSL_DISABLE_SOURCE_GENERATION=On \ + "${cross_args[@]}" + cmake --build "$GITHUB_WORKSPACE/DXC/build" - name: Build LLVM + shell: bash run: | - cd llvm-project - mkdir build - cd build - cmake -G Ninja ${{ inputs.LLVM-ExtraCMakeArgs }} -DCMAKE_BUILD_TYPE=${{ inputs.BuildType }} -DLLVM_ENABLE_ASSERTIONS=On -DLLVM_EXTERNAL_PROJECTS="OffloadTest" -DHLSL_ENABLE_OFFLOAD_DISTRIBUTION=${{ inputs.SplitBuild == true && 'On' || 'Off' }} -C ${{ github.workspace }}/llvm-project/clang/cmake/caches/HLSL.cmake -C ${{ github.workspace }}/OffloadTest/cmake/caches/sccache.cmake -DDXC_DIR=${{ github.workspace }}/DXC/build/bin -DLLVM_EXTERNAL_OFFLOADTEST_SOURCE_DIR=${{ github.workspace }}/OffloadTest -DLLVM_LIT_ARGS="--xunit-xml-output=testresults.xunit.xml -v" -DOFFLOADTEST_TEST_CLANG=${{steps.Test-Clang.outputs.TEST_CLANG || 'Off' }} -DGOLDENIMAGE_DIR=${{ github.workspace }}/golden-images -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install ${{ github.workspace }}/llvm-project/llvm/ - ninja hlsl-test-depends + set -euxo pipefail + cross_args=() + if [ '${{ inputs.SplitBuild }}' = 'true' ] \ + && [ '${{ inputs.SKU }}' = 'windows-qc' ] \ + && [ '${{ runner.arch }}' != 'ARM64' ]; then + cross_args=( + -DCMAKE_SYSTEM_NAME=Windows + -DCMAKE_SYSTEM_PROCESSOR=ARM64 + -DCMAKE_C_COMPILER_TARGET=arm64-pc-windows-msvc + -DCMAKE_CXX_COMPILER_TARGET=arm64-pc-windows-msvc + "-DLLVM_NATIVE_BUILD=$GITHUB_WORKSPACE/llvm-project/host-build" + "-DLLVM_NATIVE_TOOL_DIR=$GITHUB_WORKSPACE/llvm-project/host-build/bin" + ) + fi + cmake -G Ninja \ + -S "$GITHUB_WORKSPACE/llvm-project/llvm" \ + -B "$GITHUB_WORKSPACE/llvm-project/build" \ + ${{ inputs.LLVM-ExtraCMakeArgs }} \ + -DCMAKE_BUILD_TYPE=${{ inputs.BuildType }} \ + -DLLVM_ENABLE_ASSERTIONS=On \ + -DLLVM_EXTERNAL_PROJECTS="OffloadTest" \ + -DHLSL_ENABLE_OFFLOAD_DISTRIBUTION=${{ inputs.SplitBuild == true && 'On' || 'Off' }} \ + -C "$GITHUB_WORKSPACE/llvm-project/clang/cmake/caches/HLSL.cmake" \ + -C "$GITHUB_WORKSPACE/OffloadTest/cmake/caches/sccache.cmake" \ + "-DDXC_DIR=$GITHUB_WORKSPACE/DXC/build/bin" \ + "-DLLVM_EXTERNAL_OFFLOADTEST_SOURCE_DIR=$GITHUB_WORKSPACE/OffloadTest" \ + -DLLVM_LIT_ARGS="--xunit-xml-output=testresults.xunit.xml -v" \ + -DOFFLOADTEST_TEST_CLANG=${{steps.Test-Clang.outputs.TEST_CLANG || 'Off' }} \ + "-DGOLDENIMAGE_DIR=$GITHUB_WORKSPACE/golden-images" \ + "-DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/install" \ + "${cross_args[@]}" + cmake --build "$GITHUB_WORKSPACE/llvm-project/build" \ + --target hlsl-test-depends + - name: Verify ARM64 build artifacts + if: >- + inputs.OS == 'windows' + && inputs.SplitBuild == true + && inputs.SKU == 'windows-qc' + shell: powershell + run: | + $expectedMachine = 0xAA64 + $files = @( + "$env:GITHUB_WORKSPACE\DXC\build\bin\dxc.exe", + "$env:GITHUB_WORKSPACE\llvm-project\build\bin\clang.exe" + ) + foreach ($file in $files) { + $stream = [System.IO.File]::OpenRead($file) + try { + $reader = [System.IO.BinaryReader]::new($stream) + $stream.Position = 0x3c + $peOffset = $reader.ReadInt32() + $stream.Position = $peOffset + 4 + $machine = $reader.ReadUInt16() + } finally { + $stream.Dispose() + } + if ($machine -ne $expectedMachine) { + throw "$file has PE machine 0x$($machine.ToString('X4')); expected ARM64 (0xAA64)" + } + Write-Host "$file is ARM64" + } # Surface sccache cache state after the heavy compile work so we can # track hit rate / cache size across runs and diagnose cold-cache # blowups on new builders. Always-runs so we still get stats on diff --git a/docs/offload-distribution.md b/docs/offload-distribution.md index d2859adb3..f793ef8cf 100644 --- a/docs/offload-distribution.md +++ b/docs/offload-distribution.md @@ -185,3 +185,10 @@ The reusable workflow `.github/workflows/build-and-test-callable.yaml` implements this flow when invoked with `SplitBuild=true`. The build job produces two artifacts (`build--` and `dxc--`) and the test job consumes both. + +For the `windows-qc` SKU, the build job targets ARM64 independently of the +build host architecture. It is scheduled on the generic self-hosted Windows +pool: an ARM64 host builds natively, while an X64 host first builds the native +LLVM/DXC generator tools and then cross-compiles the packaged binaries for +Windows ARM64. The workflow verifies the PE machine type before uploading the +artifacts. The test job remains pinned to the ARM64 `hlsl-windows-qc` runner. From 9e6c15984c4db7e497be3af43028b37910a87ed3 Mon Sep 17 00:00:00 2001 From: Damyan Pepper Date: Wed, 15 Jul 2026 11:04:48 -0700 Subject: [PATCH 02/16] Fix cross-runner build environments Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 94ff14fb-6023-4436-8382-29a19a4c54b0 --- .../workflows/build-and-test-callable.yaml | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-and-test-callable.yaml b/.github/workflows/build-and-test-callable.yaml index 4500db5e8..3c7f42292 100644 --- a/.github/workflows/build-and-test-callable.yaml +++ b/.github/workflows/build-and-test-callable.yaml @@ -218,11 +218,28 @@ jobs: uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main with: arch: amd64 - - name: Setup Windows ARM64 target - if: inputs.OS == 'windows' && inputs.SKU == 'windows-qc' + - name: Setup Windows ARM64 cross target + if: >- + inputs.OS == 'windows' + && inputs.SKU == 'windows-qc' + && runner.arch != 'ARM64' + uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main + with: + # setup-windows forwards this input to VsDevCmd.bat after -arch=. + arch: arm64 -host_arch=amd64 + - name: Setup Windows ARM64 native target + if: >- + inputs.OS == 'windows' + && inputs.SKU == 'windows-qc' + && runner.arch == 'ARM64' uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main with: arch: arm64 + # VsDevCmd replaces PATH. Run setup-python after the final target setup + # so Python and Git Bash are available to the remaining workflow steps. + - name: Restore Python and Git Bash paths + if: inputs.OS == 'windows' + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - name: Report Windows build architecture if: inputs.OS == 'windows' shell: bash @@ -244,7 +261,7 @@ jobs: - name: Build DXC shell: bash run: | - set -euxo pipefail + set -exo pipefail cross_args=() if [ '${{ inputs.SplitBuild }}' = 'true' ] \ && [ '${{ inputs.SKU }}' = 'windows-qc' ] \ @@ -270,7 +287,7 @@ jobs: - name: Build LLVM shell: bash run: | - set -euxo pipefail + set -exo pipefail cross_args=() if [ '${{ inputs.SplitBuild }}' = 'true' ] \ && [ '${{ inputs.SKU }}' = 'windows-qc' ] \ From cd99223286c39b86fae72d81c08c3835516736d6 Mon Sep 17 00:00:00 2001 From: Damyan Pepper Date: Wed, 15 Jul 2026 11:24:55 -0700 Subject: [PATCH 03/16] Restore Git Bash after Windows setup Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 94ff14fb-6023-4436-8382-29a19a4c54b0 --- .../workflows/build-and-test-callable.yaml | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-and-test-callable.yaml b/.github/workflows/build-and-test-callable.yaml index 3c7f42292..ff6834528 100644 --- a/.github/workflows/build-and-test-callable.yaml +++ b/.github/workflows/build-and-test-callable.yaml @@ -182,6 +182,16 @@ jobs: uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main with: arch: amd64 + - name: Restore Git Bash for host tools + if: >- + inputs.OS == 'windows' + && inputs.SplitBuild == true + && inputs.SKU == 'windows-qc' + && runner.arch != 'ARM64' + shell: powershell + run: | + "C:\Program Files\Git\bin" >> $env:GITHUB_PATH + "C:\Program Files\Git\usr\bin" >> $env:GITHUB_PATH - name: Build native host tools if: >- inputs.OS == 'windows' @@ -235,11 +245,17 @@ jobs: uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main with: arch: arm64 - # VsDevCmd replaces PATH. Run setup-python after the final target setup - # so Python and Git Bash are available to the remaining workflow steps. - - name: Restore Python and Git Bash paths + # VsDevCmd replaces PATH. Restore the tool paths required by the + # remaining workflow steps after the final target setup. + - name: Restore Python path if: inputs.OS == 'windows' uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + - name: Restore Git Bash path + if: inputs.OS == 'windows' + shell: powershell + run: | + "C:\Program Files\Git\bin" >> $env:GITHUB_PATH + "C:\Program Files\Git\usr\bin" >> $env:GITHUB_PATH - name: Report Windows build architecture if: inputs.OS == 'windows' shell: bash From 31476d2e259b6a24b55ac37bb766fabf62ea7af3 Mon Sep 17 00:00:00 2001 From: Damyan Pepper Date: Wed, 15 Jul 2026 11:38:51 -0700 Subject: [PATCH 04/16] Isolate native host tool setup Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 94ff14fb-6023-4436-8382-29a19a4c54b0 --- .../workflows/build-and-test-callable.yaml | 67 +++++++------------ 1 file changed, 26 insertions(+), 41 deletions(-) diff --git a/.github/workflows/build-and-test-callable.yaml b/.github/workflows/build-and-test-callable.yaml index ff6834528..ecd8f99c8 100644 --- a/.github/workflows/build-and-test-callable.yaml +++ b/.github/workflows/build-and-test-callable.yaml @@ -173,56 +173,41 @@ jobs: uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: pip-install: -r ${{ github.workspace }}/OffloadTest/test/requirements.txt - - name: Setup Windows host tools - if: >- - inputs.OS == 'windows' - && inputs.SplitBuild == true - && inputs.SKU == 'windows-qc' - && runner.arch != 'ARM64' - uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main - with: - arch: amd64 - - name: Restore Git Bash for host tools - if: >- - inputs.OS == 'windows' - && inputs.SplitBuild == true - && inputs.SKU == 'windows-qc' - && runner.arch != 'ARM64' - shell: powershell - run: | - "C:\Program Files\Git\bin" >> $env:GITHUB_PATH - "C:\Program Files\Git\usr\bin" >> $env:GITHUB_PATH - name: Build native host tools if: >- inputs.OS == 'windows' && inputs.SplitBuild == true && inputs.SKU == 'windows-qc' && runner.arch != 'ARM64' - shell: bash + shell: cmd run: | - set -euxo pipefail + for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath`) do set "InstallDir=%%i" + call "%InstallDir%\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 - cmake -G Ninja \ - -S "$GITHUB_WORKSPACE/DXC" \ - -B "$GITHUB_WORKSPACE/DXC/host-build" \ - -DCMAKE_BUILD_TYPE=Release \ - -DLLVM_ENABLE_ASSERTIONS=Off \ - -C "$GITHUB_WORKSPACE/DXC/cmake/caches/PredefinedParams.cmake" \ - -C "$GITHUB_WORKSPACE/OffloadTest/cmake/caches/sccache.cmake" \ - -DHLSL_DISABLE_SOURCE_GENERATION=On - cmake --build "$GITHUB_WORKSPACE/DXC/host-build" \ - --target llvm-tblgen clang-tblgen llvm-config + cmake -G Ninja ^ + -S "%GITHUB_WORKSPACE%\DXC" ^ + -B "%GITHUB_WORKSPACE%\DXC\host-build" ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DLLVM_ENABLE_ASSERTIONS=Off ^ + -C "%GITHUB_WORKSPACE%\DXC\cmake\caches\PredefinedParams.cmake" ^ + -C "%GITHUB_WORKSPACE%\OffloadTest\cmake\caches\sccache.cmake" ^ + -DHLSL_DISABLE_SOURCE_GENERATION=On + if errorlevel 1 exit /b 1 + cmake --build "%GITHUB_WORKSPACE%\DXC\host-build" ^ + --target llvm-tblgen clang-tblgen llvm-config + if errorlevel 1 exit /b 1 - cmake -G Ninja \ - -S "$GITHUB_WORKSPACE/llvm-project/llvm" \ - -B "$GITHUB_WORKSPACE/llvm-project/host-build" \ - -DCMAKE_BUILD_TYPE=Release \ - -DLLVM_ENABLE_ASSERTIONS=Off \ - -DLLVM_ENABLE_PROJECTS=clang \ - -DLLVM_TARGETS_TO_BUILD=Native \ - -C "$GITHUB_WORKSPACE/OffloadTest/cmake/caches/sccache.cmake" - cmake --build "$GITHUB_WORKSPACE/llvm-project/host-build" \ - --target llvm-tblgen clang-tblgen llvm-config + cmake -G Ninja ^ + -S "%GITHUB_WORKSPACE%\llvm-project\llvm" ^ + -B "%GITHUB_WORKSPACE%\llvm-project\host-build" ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DLLVM_ENABLE_ASSERTIONS=Off ^ + -DLLVM_ENABLE_PROJECTS=clang ^ + -DLLVM_TARGETS_TO_BUILD=Native ^ + -C "%GITHUB_WORKSPACE%\OffloadTest\cmake\caches\sccache.cmake" + if errorlevel 1 exit /b 1 + cmake --build "%GITHUB_WORKSPACE%\llvm-project\host-build" ^ + --target llvm-tblgen clang-tblgen llvm-config - name: Setup Windows x64 target if: inputs.OS == 'windows' && inputs.SKU != 'windows-qc' uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main From 8d6da50bd60e4a4ad98b64859f1a6c4667a282c6 Mon Sep 17 00:00:00 2001 From: Damyan Pepper Date: Wed, 15 Jul 2026 13:13:34 -0700 Subject: [PATCH 05/16] Use x64-hosted ARM64 cross tools Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 94ff14fb-6023-4436-8382-29a19a4c54b0 --- .github/workflows/build-and-test-callable.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test-callable.yaml b/.github/workflows/build-and-test-callable.yaml index ecd8f99c8..5deef3b58 100644 --- a/.github/workflows/build-and-test-callable.yaml +++ b/.github/workflows/build-and-test-callable.yaml @@ -221,7 +221,7 @@ jobs: uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main with: # setup-windows forwards this input to VsDevCmd.bat after -arch=. - arch: arm64 -host_arch=amd64 + arch: arm64 -host_arch=x64 - name: Setup Windows ARM64 native target if: >- inputs.OS == 'windows' From 073bcb91ef854b925a7309ad4efd6b981750bc47 Mon Sep 17 00:00:00 2001 From: Damyan Pepper Date: Wed, 15 Jul 2026 14:40:53 -0700 Subject: [PATCH 06/16] Target ARM64 explicitly in DXC cross builds Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 94ff14fb-6023-4436-8382-29a19a4c54b0 --- .github/workflows/build-and-test-callable.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build-and-test-callable.yaml b/.github/workflows/build-and-test-callable.yaml index 5deef3b58..cc5c9edc7 100644 --- a/.github/workflows/build-and-test-callable.yaml +++ b/.github/workflows/build-and-test-callable.yaml @@ -270,6 +270,10 @@ jobs: cross_args=( -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_SYSTEM_PROCESSOR=ARM64 + -DCMAKE_C_COMPILER=clang-cl + -DCMAKE_CXX_COMPILER=clang-cl + -DCMAKE_C_COMPILER_TARGET=arm64-pc-windows-msvc + -DCMAKE_CXX_COMPILER_TARGET=arm64-pc-windows-msvc "-DLLVM_NATIVE_BUILD=$GITHUB_WORKSPACE/DXC/host-build" "-DLLVM_TABLEGEN=$GITHUB_WORKSPACE/DXC/host-build/bin/llvm-tblgen.exe" "-DCLANG_TABLEGEN=$GITHUB_WORKSPACE/DXC/host-build/bin/clang-tblgen.exe" From 440ecaa04500f1c859c19f2dc061858fae387d58 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Mon, 20 Jul 2026 17:23:09 -0700 Subject: [PATCH 07/16] add arm64 latest libs to all machines, and force machines to use latest msvc version. Reuse the pinned latest version --- .../workflows/build-and-test-callable.yaml | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-and-test-callable.yaml b/.github/workflows/build-and-test-callable.yaml index cc5c9edc7..e75fd3dae 100644 --- a/.github/workflows/build-and-test-callable.yaml +++ b/.github/workflows/build-and-test-callable.yaml @@ -173,6 +173,23 @@ jobs: uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: pip-install: -r ${{ github.workspace }}/OffloadTest/test/requirements.txt + - name: Pin MSVC toolset + # The runner's default v143 toolset (Microsoft.VCToolsVersion.v143.default.txt) + # can lag Microsoft.VCToolsVersion.default.txt and lack the x64/ARM64 base + # libraries, which breaks host and cross builds depending on which runner + # picks up the job. Pin every VsDevCmd in this job to the default (latest) + # toolset, which VS keeps complete. + if: >- + inputs.OS == 'windows' + && inputs.SplitBuild == true + && inputs.SKU == 'windows-qc' + shell: pwsh + run: | + $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + $vs = & $vswhere -latest -property installationPath + $ver = (Get-Content "$vs\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt").Trim() + "VCToolsVersion=$ver" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + Write-Host "Pinned VCToolsVersion=$ver" - name: Build native host tools if: >- inputs.OS == 'windows' @@ -182,7 +199,7 @@ jobs: shell: cmd run: | for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath`) do set "InstallDir=%%i" - call "%InstallDir%\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 + call "%InstallDir%\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -vcvars_ver=%VCToolsVersion% cmake -G Ninja ^ -S "%GITHUB_WORKSPACE%\DXC" ^ @@ -221,7 +238,7 @@ jobs: uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main with: # setup-windows forwards this input to VsDevCmd.bat after -arch=. - arch: arm64 -host_arch=x64 + arch: arm64 -host_arch=x64 -vcvars_ver=${{ env.VCToolsVersion }} - name: Setup Windows ARM64 native target if: >- inputs.OS == 'windows' @@ -229,7 +246,7 @@ jobs: && runner.arch == 'ARM64' uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main with: - arch: arm64 + arch: arm64 -vcvars_ver=${{ env.VCToolsVersion }} # VsDevCmd replaces PATH. Restore the tool paths required by the # remaining workflow steps after the final target setup. - name: Restore Python path From 7ac4f7f327efa65c549b9434c0a6803f8e273c87 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Tue, 21 Jul 2026 13:42:48 -0700 Subject: [PATCH 08/16] self review: simplify, and x64 builds arm64 bins, no more native arm64 bin builders --- .../workflows/build-and-test-callable.yaml | 64 +++++++------------ docs/offload-distribution.md | 35 ++++++++-- 2 files changed, 51 insertions(+), 48 deletions(-) diff --git a/.github/workflows/build-and-test-callable.yaml b/.github/workflows/build-and-test-callable.yaml index e75fd3dae..0ae327f66 100644 --- a/.github/workflows/build-and-test-callable.yaml +++ b/.github/workflows/build-and-test-callable.yaml @@ -126,15 +126,12 @@ jobs: build: permissions: checks: write - # When SplitBuild is true, build on any available runner that can produce - # the requested target. windows-qc targets ARM64 but may cross-compile on - # an X64 Windows builder. Otherwise, build on the GPU runner. + # Split builds run on any X64 Windows runner (windows-qc targets ARM64 but + # is always cross-compiled on X64). Non-split builds run on the GPU runner. runs-on: >- ${{ fromJSON( inputs.SplitBuild != true && format('["self-hosted", "hlsl-{0}"]', inputs.SKU) - || inputs.SKU == 'windows-qc' - && '["self-hosted", "Windows"]' || inputs.SKU == 'macos' && '["self-hosted", "hlsl-macos"]' || '["self-hosted", "Windows", "X64"]' @@ -174,15 +171,9 @@ jobs: with: pip-install: -r ${{ github.workspace }}/OffloadTest/test/requirements.txt - name: Pin MSVC toolset - # The runner's default v143 toolset (Microsoft.VCToolsVersion.v143.default.txt) - # can lag Microsoft.VCToolsVersion.default.txt and lack the x64/ARM64 base - # libraries, which breaks host and cross builds depending on which runner - # picks up the job. Pin every VsDevCmd in this job to the default (latest) - # toolset, which VS keeps complete. - if: >- - inputs.OS == 'windows' - && inputs.SplitBuild == true - && inputs.SKU == 'windows-qc' + # The default v143 toolset can lag the complete default toolset and lack + # x64/ARM64 base libs. Pin every VsDevCmd to the default (latest) toolset. + if: inputs.OS == 'windows' shell: pwsh run: | $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" @@ -190,12 +181,19 @@ jobs: $ver = (Get-Content "$vs\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt").Trim() "VCToolsVersion=$ver" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 Write-Host "Pinned VCToolsVersion=$ver" + - name: Compute build mode + # Single source of truth for the ARM64 cross build: SplitBuild + windows-qc + # builds on X64 and targets ARM64. Cross steps key off env.ARM64_CROSS. + if: inputs.OS == 'windows' + shell: bash + run: | + cross=false + if [ '${{ inputs.SplitBuild }}' = 'true' ] && [ '${{ inputs.SKU }}' = 'windows-qc' ]; then + cross=true + fi + echo "ARM64_CROSS=$cross" >> "$GITHUB_ENV" - name: Build native host tools - if: >- - inputs.OS == 'windows' - && inputs.SplitBuild == true - && inputs.SKU == 'windows-qc' - && runner.arch != 'ARM64' + if: env.ARM64_CROSS == 'true' shell: cmd run: | for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath`) do set "InstallDir=%%i" @@ -229,24 +227,13 @@ jobs: if: inputs.OS == 'windows' && inputs.SKU != 'windows-qc' uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main with: - arch: amd64 + arch: amd64 -vcvars_ver=${{ env.VCToolsVersion }} - name: Setup Windows ARM64 cross target - if: >- - inputs.OS == 'windows' - && inputs.SKU == 'windows-qc' - && runner.arch != 'ARM64' + if: env.ARM64_CROSS == 'true' uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main with: # setup-windows forwards this input to VsDevCmd.bat after -arch=. arch: arm64 -host_arch=x64 -vcvars_ver=${{ env.VCToolsVersion }} - - name: Setup Windows ARM64 native target - if: >- - inputs.OS == 'windows' - && inputs.SKU == 'windows-qc' - && runner.arch == 'ARM64' - uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main - with: - arch: arm64 -vcvars_ver=${{ env.VCToolsVersion }} # VsDevCmd replaces PATH. Restore the tool paths required by the # remaining workflow steps after the final target setup. - name: Restore Python path @@ -281,9 +268,7 @@ jobs: run: | set -exo pipefail cross_args=() - if [ '${{ inputs.SplitBuild }}' = 'true' ] \ - && [ '${{ inputs.SKU }}' = 'windows-qc' ] \ - && [ '${{ runner.arch }}' != 'ARM64' ]; then + if [ "$ARM64_CROSS" = 'true' ]; then cross_args=( -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_SYSTEM_PROCESSOR=ARM64 @@ -311,9 +296,7 @@ jobs: run: | set -exo pipefail cross_args=() - if [ '${{ inputs.SplitBuild }}' = 'true' ] \ - && [ '${{ inputs.SKU }}' = 'windows-qc' ] \ - && [ '${{ runner.arch }}' != 'ARM64' ]; then + if [ "$ARM64_CROSS" = 'true' ]; then cross_args=( -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_SYSTEM_PROCESSOR=ARM64 @@ -343,10 +326,7 @@ jobs: cmake --build "$GITHUB_WORKSPACE/llvm-project/build" \ --target hlsl-test-depends - name: Verify ARM64 build artifacts - if: >- - inputs.OS == 'windows' - && inputs.SplitBuild == true - && inputs.SKU == 'windows-qc' + if: env.ARM64_CROSS == 'true' shell: powershell run: | $expectedMachine = 0xAA64 diff --git a/docs/offload-distribution.md b/docs/offload-distribution.md index f793ef8cf..2b583489a 100644 --- a/docs/offload-distribution.md +++ b/docs/offload-distribution.md @@ -186,9 +186,32 @@ implements this flow when invoked with `SplitBuild=true`. The build job produces two artifacts (`build--` and `dxc--`) and the test job consumes both. -For the `windows-qc` SKU, the build job targets ARM64 independently of the -build host architecture. It is scheduled on the generic self-hosted Windows -pool: an ARM64 host builds natively, while an X64 host first builds the native -LLVM/DXC generator tools and then cross-compiles the packaged binaries for -Windows ARM64. The workflow verifies the PE machine type before uploading the -artifacts. The test job remains pinned to the ARM64 `hlsl-windows-qc` runner. +For the `windows-qc` SKU, the build job targets ARM64 but is always scheduled +on an X64 self-hosted Windows builder (we do not build ARM64 natively). The +builder first compiles the native LLVM/DXC generator tools, then cross-compiles +the packaged binaries for Windows ARM64. The workflow verifies the PE machine +type before uploading the artifacts. The test job remains pinned to the ARM64 +`hlsl-windows-qc` runner. + +The `Compute build mode` step is the single source of truth for whether a job +cross-compiles: it sets `ARM64_CROSS=true` only when `SplitBuild` is enabled and +the SKU is `windows-qc`. Every cross-specific step (native host-tools build, +ARM64 target setup, the `cmake` cross flags, and the PE-machine verification) +keys off `env.ARM64_CROSS`, so the cross path is defined in exactly one place. + +### MSVC toolset pinning + +Windows builders can carry a v143 default toolset +(`Microsoft.VCToolsVersion.v143.default.txt`) that lags the complete default +toolset (`Microsoft.VCToolsVersion.default.txt`) and is missing the x64 and/or +ARM64 base libraries (for example `msvcrtd.lib` and `oldnames.lib`). When a job +lands on such a runner, both the native host build and the ARM64 cross build can +fail to link, and because jobs are scheduled across a heterogeneous pool the +failure is intermittent and runner-dependent. + +To make builds deterministic, the `Pin MSVC toolset` step reads the default +(latest) toolset version, which VS keeps complete, and exports it as +`VCToolsVersion` for the whole job. Every `VsDevCmd` invocation in the job then +passes `-vcvars_ver=%VCToolsVersion%` (host-tools setup, `Setup Windows x64 +target`, and `Setup Windows ARM64 cross target`) so they all resolve the same +complete toolset regardless of which runner picks up the job. From f16be1f115d4303ee437a466c4a7d6efc3d22f72 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Tue, 21 Jul 2026 13:52:39 -0700 Subject: [PATCH 09/16] repair pwsh --- .github/workflows/build-and-test-callable.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-test-callable.yaml b/.github/workflows/build-and-test-callable.yaml index 0ae327f66..93ffb7f2e 100644 --- a/.github/workflows/build-and-test-callable.yaml +++ b/.github/workflows/build-and-test-callable.yaml @@ -174,12 +174,12 @@ jobs: # The default v143 toolset can lag the complete default toolset and lack # x64/ARM64 base libs. Pin every VsDevCmd to the default (latest) toolset. if: inputs.OS == 'windows' - shell: pwsh + shell: powershell run: | $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" $vs = & $vswhere -latest -property installationPath $ver = (Get-Content "$vs\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt").Trim() - "VCToolsVersion=$ver" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + "VCToolsVersion=$ver" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding ascii Write-Host "Pinned VCToolsVersion=$ver" - name: Compute build mode # Single source of truth for the ARM64 cross build: SplitBuild + windows-qc From 03dc0c014242196862ed18076a37837fcb595f14 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Tue, 21 Jul 2026 15:37:29 -0700 Subject: [PATCH 10/16] turn off warnings as errors on spirvtools for arm64 cross, since it uses clang-cl as the compiler --- .github/workflows/build-and-test-callable.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build-and-test-callable.yaml b/.github/workflows/build-and-test-callable.yaml index 93ffb7f2e..192d923bb 100644 --- a/.github/workflows/build-and-test-callable.yaml +++ b/.github/workflows/build-and-test-callable.yaml @@ -276,6 +276,9 @@ jobs: -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_C_COMPILER_TARGET=arm64-pc-windows-msvc -DCMAKE_CXX_COMPILER_TARGET=arm64-pc-windows-msvc + # clang-cl reads DXC's -Wall as -Weverything; disable DXC warnings + # so SPIRV-Tools' hardcoded /WX doesn't fail on -Wc++98-compat. + -DLLVM_ENABLE_WARNINGS=OFF "-DLLVM_NATIVE_BUILD=$GITHUB_WORKSPACE/DXC/host-build" "-DLLVM_TABLEGEN=$GITHUB_WORKSPACE/DXC/host-build/bin/llvm-tblgen.exe" "-DCLANG_TABLEGEN=$GITHUB_WORKSPACE/DXC/host-build/bin/clang-tblgen.exe" From dbb68a4c7325e5510aae9c780c9979d9c2fdbb03 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Tue, 21 Jul 2026 18:10:02 -0700 Subject: [PATCH 11/16] subtle tweaks and fixes --- .github/workflows/build-and-test-callable.yaml | 9 ++++++++- docs/offload-distribution.md | 17 +++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-and-test-callable.yaml b/.github/workflows/build-and-test-callable.yaml index 192d923bb..8b41a9809 100644 --- a/.github/workflows/build-and-test-callable.yaml +++ b/.github/workflows/build-and-test-callable.yaml @@ -62,7 +62,7 @@ on: SplitBuild: description: 'Split build and test into separate jobs (build on any runner, test on GPU runner)' required: false - default: false + default: true type: boolean LLVM-ExtraCMakeArgs: description: 'Extra CMake Args for LLVM' @@ -234,6 +234,13 @@ jobs: with: # setup-windows forwards this input to VsDevCmd.bat after -arch=. arch: arm64 -host_arch=x64 -vcvars_ver=${{ env.VCToolsVersion }} + - name: Setup Windows ARM64 native target + # Non-split windows-qc builds natively on the ARM64 device + # (split qc cross-compiles on X64 via the step above). + if: inputs.OS == 'windows' && inputs.SKU == 'windows-qc' && env.ARM64_CROSS != 'true' + uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main + with: + arch: arm64 -vcvars_ver=${{ env.VCToolsVersion }} # VsDevCmd replaces PATH. Restore the tool paths required by the # remaining workflow steps after the final target setup. - name: Restore Python path diff --git a/docs/offload-distribution.md b/docs/offload-distribution.md index 2b583489a..03ae6e62d 100644 --- a/docs/offload-distribution.md +++ b/docs/offload-distribution.md @@ -186,18 +186,27 @@ implements this flow when invoked with `SplitBuild=true`. The build job produces two artifacts (`build--` and `dxc--`) and the test job consumes both. -For the `windows-qc` SKU, the build job targets ARM64 but is always scheduled -on an X64 self-hosted Windows builder (we do not build ARM64 natively). The +For the `windows-qc` SKU with `SplitBuild=true`, the build job targets ARM64 +but is always scheduled on an X64 self-hosted Windows builder (we do not build +ARM64 natively in the split flow). The builder first compiles the native LLVM/DXC generator tools, then cross-compiles the packaged binaries for Windows ARM64. The workflow verifies the PE machine type before uploading the artifacts. The test job remains pinned to the ARM64 `hlsl-windows-qc` runner. +A non-split `windows-qc` run (`SplitBuild=false`, e.g. a manual +`workflow_dispatch`) instead runs entirely on the ARM64 `hlsl-windows-qc` +device and builds natively via the `Setup Windows ARM64 native target` step. +The `workflow_dispatch` default is `SplitBuild=true`, so manual runs take the +X64 cross path unless explicitly overridden. + The `Compute build mode` step is the single source of truth for whether a job cross-compiles: it sets `ARM64_CROSS=true` only when `SplitBuild` is enabled and the SKU is `windows-qc`. Every cross-specific step (native host-tools build, -ARM64 target setup, the `cmake` cross flags, and the PE-machine verification) -keys off `env.ARM64_CROSS`, so the cross path is defined in exactly one place. +ARM64 cross-target setup, the `cmake` cross flags, and the PE-machine +verification) keys off `env.ARM64_CROSS`, so the cross path is defined in +exactly one place. The native-ARM64 setup step runs on the complementary case +(`windows-qc` with `ARM64_CROSS != 'true'`). ### MSVC toolset pinning From 531d6b041033be62f31d3de87d562b5a72372961 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Tue, 21 Jul 2026 23:35:00 -0700 Subject: [PATCH 12/16] freeze version.inc in native builds --- .github/workflows/build-and-test-callable.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-and-test-callable.yaml b/.github/workflows/build-and-test-callable.yaml index 8b41a9809..91973600c 100644 --- a/.github/workflows/build-and-test-callable.yaml +++ b/.github/workflows/build-and-test-callable.yaml @@ -204,6 +204,7 @@ jobs: -B "%GITHUB_WORKSPACE%\DXC\host-build" ^ -DCMAKE_BUILD_TYPE=Release ^ -DLLVM_ENABLE_ASSERTIONS=Off ^ + -DLLVM_APPEND_VC_REV=Off ^ -C "%GITHUB_WORKSPACE%\DXC\cmake\caches\PredefinedParams.cmake" ^ -C "%GITHUB_WORKSPACE%\OffloadTest\cmake\caches\sccache.cmake" ^ -DHLSL_DISABLE_SOURCE_GENERATION=On @@ -217,6 +218,7 @@ jobs: -B "%GITHUB_WORKSPACE%\llvm-project\host-build" ^ -DCMAKE_BUILD_TYPE=Release ^ -DLLVM_ENABLE_ASSERTIONS=Off ^ + -DLLVM_APPEND_VC_REV=Off ^ -DLLVM_ENABLE_PROJECTS=clang ^ -DLLVM_TARGETS_TO_BUILD=Native ^ -C "%GITHUB_WORKSPACE%\OffloadTest\cmake\caches\sccache.cmake" From 271c88f44e9c43eff342bc7495e97cd727d5ad5b Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Wed, 22 Jul 2026 09:59:02 -0700 Subject: [PATCH 13/16] add x64 libs to LIB --- .github/workflows/build-and-test-callable.yaml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-test-callable.yaml b/.github/workflows/build-and-test-callable.yaml index 91973600c..ed8d2d494 100644 --- a/.github/workflows/build-and-test-callable.yaml +++ b/.github/workflows/build-and-test-callable.yaml @@ -204,7 +204,6 @@ jobs: -B "%GITHUB_WORKSPACE%\DXC\host-build" ^ -DCMAKE_BUILD_TYPE=Release ^ -DLLVM_ENABLE_ASSERTIONS=Off ^ - -DLLVM_APPEND_VC_REV=Off ^ -C "%GITHUB_WORKSPACE%\DXC\cmake\caches\PredefinedParams.cmake" ^ -C "%GITHUB_WORKSPACE%\OffloadTest\cmake\caches\sccache.cmake" ^ -DHLSL_DISABLE_SOURCE_GENERATION=On @@ -218,7 +217,6 @@ jobs: -B "%GITHUB_WORKSPACE%\llvm-project\host-build" ^ -DCMAKE_BUILD_TYPE=Release ^ -DLLVM_ENABLE_ASSERTIONS=Off ^ - -DLLVM_APPEND_VC_REV=Off ^ -DLLVM_ENABLE_PROJECTS=clang ^ -DLLVM_TARGETS_TO_BUILD=Native ^ -C "%GITHUB_WORKSPACE%\OffloadTest\cmake\caches\sccache.cmake" @@ -243,6 +241,16 @@ jobs: uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main with: arch: arm64 -vcvars_ver=${{ env.VCToolsVersion }} + - name: Add x64 libs to LIB for native host-tool relinks + # Cross steps relink native x64 tools (llvm-config) under the ARM64 env; + # append x64 lib dirs so those links resolve the x64 CRT. + if: env.ARM64_CROSS == 'true' + shell: cmd + run: | + for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath`) do set "InstallDir=%%i" + set "ARM64_LIB=%LIB%" + call "%InstallDir%\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -vcvars_ver=%VCToolsVersion% >nul + echo LIB=%ARM64_LIB%;%LIB%>>%GITHUB_ENV% # VsDevCmd replaces PATH. Restore the tool paths required by the # remaining workflow steps after the final target setup. - name: Restore Python path From 418dfcafdd3912da9d46cd995c87b16947815f28 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Wed, 22 Jul 2026 10:49:44 -0700 Subject: [PATCH 14/16] more libpath %LIB% investigation --- .../workflows/build-and-test-callable.yaml | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build-and-test-callable.yaml b/.github/workflows/build-and-test-callable.yaml index ed8d2d494..e6633834c 100644 --- a/.github/workflows/build-and-test-callable.yaml +++ b/.github/workflows/build-and-test-callable.yaml @@ -199,6 +199,14 @@ jobs: for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath`) do set "InstallDir=%%i" call "%InstallDir%\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -vcvars_ver=%VCToolsVersion% + rem Bake x64 lib dirs into host tool links so the cross Build DXC step's + rem native llvm-config relink resolves the x64 CRT under the ARM64 env. + setlocal enabledelayedexpansion + set "LFLAGS=" + for %%d in ("%LIB:;=" "%") do if not "%%~d"=="" set LFLAGS=!LFLAGS! /LIBPATH:"%%~d" + > "%GITHUB_WORKSPACE%\host-linkflags.cmake" echo set(_extra_libpaths [=[!LFLAGS!]=]) + >> "%GITHUB_WORKSPACE%\host-linkflags.cmake" echo set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${_extra_libpaths}" CACHE STRING "" FORCE) + cmake -G Ninja ^ -S "%GITHUB_WORKSPACE%\DXC" ^ -B "%GITHUB_WORKSPACE%\DXC\host-build" ^ @@ -206,7 +214,8 @@ jobs: -DLLVM_ENABLE_ASSERTIONS=Off ^ -C "%GITHUB_WORKSPACE%\DXC\cmake\caches\PredefinedParams.cmake" ^ -C "%GITHUB_WORKSPACE%\OffloadTest\cmake\caches\sccache.cmake" ^ - -DHLSL_DISABLE_SOURCE_GENERATION=On + -DHLSL_DISABLE_SOURCE_GENERATION=On ^ + -C "%GITHUB_WORKSPACE%\host-linkflags.cmake" if errorlevel 1 exit /b 1 cmake --build "%GITHUB_WORKSPACE%\DXC\host-build" ^ --target llvm-tblgen clang-tblgen llvm-config @@ -219,7 +228,8 @@ jobs: -DLLVM_ENABLE_ASSERTIONS=Off ^ -DLLVM_ENABLE_PROJECTS=clang ^ -DLLVM_TARGETS_TO_BUILD=Native ^ - -C "%GITHUB_WORKSPACE%\OffloadTest\cmake\caches\sccache.cmake" + -C "%GITHUB_WORKSPACE%\OffloadTest\cmake\caches\sccache.cmake" ^ + -C "%GITHUB_WORKSPACE%\host-linkflags.cmake" if errorlevel 1 exit /b 1 cmake --build "%GITHUB_WORKSPACE%\llvm-project\host-build" ^ --target llvm-tblgen clang-tblgen llvm-config @@ -241,16 +251,6 @@ jobs: uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main with: arch: arm64 -vcvars_ver=${{ env.VCToolsVersion }} - - name: Add x64 libs to LIB for native host-tool relinks - # Cross steps relink native x64 tools (llvm-config) under the ARM64 env; - # append x64 lib dirs so those links resolve the x64 CRT. - if: env.ARM64_CROSS == 'true' - shell: cmd - run: | - for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath`) do set "InstallDir=%%i" - set "ARM64_LIB=%LIB%" - call "%InstallDir%\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -vcvars_ver=%VCToolsVersion% >nul - echo LIB=%ARM64_LIB%;%LIB%>>%GITHUB_ENV% # VsDevCmd replaces PATH. Restore the tool paths required by the # remaining workflow steps after the final target setup. - name: Restore Python path From cd52555de71eaee5da7860b0e92edc4b138203ee Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Wed, 22 Jul 2026 12:18:36 -0700 Subject: [PATCH 15/16] use arm64 vulkan sdk libs --- .github/workflows/build-and-test-callable.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/build-and-test-callable.yaml b/.github/workflows/build-and-test-callable.yaml index e6633834c..1159c98ee 100644 --- a/.github/workflows/build-and-test-callable.yaml +++ b/.github/workflows/build-and-test-callable.yaml @@ -269,6 +269,23 @@ jobs: echo "Runner architecture: ${{ runner.arch }}" echo "MSVC host architecture: ${VSCMD_ARG_HOST_ARCH:-unknown}" echo "MSVC target architecture: ${VSCMD_ARG_TGT_ARCH:-unknown}" + - name: Generate ARM64 Vulkan import lib + # x64 Vulkan SDK ships only an x64 vulkan-1.lib; synthesize an ARM64 + # import lib from the arch-neutral loader DLL for the cross link. + if: env.ARM64_CROSS == 'true' + shell: powershell + run: | + $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + $vs = & $vswhere -latest -property installationPath + Import-Module "$vs\Common7\Tools\Microsoft.VisualStudio.DevShell.dll" + Enter-VsDevShell -VsInstallPath $vs -DevCmdArguments '-arch=x64' -SkipAutomaticLocation + $out = "$env:GITHUB_WORKSPACE\vulkan-arm64" + New-Item -ItemType Directory -Force $out | Out-Null + $names = & dumpbin /exports "$env:VULKAN_SDK\Bin\vulkan-1.dll" | + Select-String '^\s+\d+\s+[0-9A-Fa-f]+\s+[0-9A-Fa-f]+\s+(\S+)$' | + ForEach-Object { $_.Matches[0].Groups[1].Value } + @('EXPORTS') + $names | Set-Content "$out\vulkan-1.def" + lib /def:"$out\vulkan-1.def" /machine:arm64 /out:"$out\vulkan-1.lib" # When SplitBuild is enabled, force clang into the build set even if # the TestTarget doesn't use it. Reason: install-distribution depends # on clang (it ships in the install prefix), so if clang isn't part @@ -324,6 +341,7 @@ jobs: -DCMAKE_CXX_COMPILER_TARGET=arm64-pc-windows-msvc "-DLLVM_NATIVE_BUILD=$GITHUB_WORKSPACE/llvm-project/host-build" "-DLLVM_NATIVE_TOOL_DIR=$GITHUB_WORKSPACE/llvm-project/host-build/bin" + "-DVulkan_LIBRARY=$GITHUB_WORKSPACE/vulkan-arm64/vulkan-1.lib" ) fi cmake -G Ninja \ From 93234f43d7992c0079d7035fa9cae87c1526df5d Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Wed, 22 Jul 2026 14:44:55 -0700 Subject: [PATCH 16/16] fix lib search regex --- .github/workflows/build-and-test-callable.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-and-test-callable.yaml b/.github/workflows/build-and-test-callable.yaml index 1159c98ee..38b0da8ac 100644 --- a/.github/workflows/build-and-test-callable.yaml +++ b/.github/workflows/build-and-test-callable.yaml @@ -271,7 +271,7 @@ jobs: echo "MSVC target architecture: ${VSCMD_ARG_TGT_ARCH:-unknown}" - name: Generate ARM64 Vulkan import lib # x64 Vulkan SDK ships only an x64 vulkan-1.lib; synthesize an ARM64 - # import lib from the arch-neutral loader DLL for the cross link. + # import lib from its arch-neutral export names for the cross link. if: env.ARM64_CROSS == 'true' shell: powershell run: | @@ -281,9 +281,11 @@ jobs: Enter-VsDevShell -VsInstallPath $vs -DevCmdArguments '-arch=x64' -SkipAutomaticLocation $out = "$env:GITHUB_WORKSPACE\vulkan-arm64" New-Item -ItemType Directory -Force $out | Out-Null - $names = & dumpbin /exports "$env:VULKAN_SDK\Bin\vulkan-1.dll" | - Select-String '^\s+\d+\s+[0-9A-Fa-f]+\s+[0-9A-Fa-f]+\s+(\S+)$' | + $names = & dumpbin /exports "$env:VULKAN_SDK\Lib\vulkan-1.lib" | + Select-String '^\s+(vk\w+)\s*$' | ForEach-Object { $_.Matches[0].Groups[1].Value } + if ($names.Count -eq 0) { throw "No Vulkan exports found; cannot build ARM64 import lib" } + Write-Host "Captured $($names.Count) Vulkan exports" @('EXPORTS') + $names | Set-Content "$out\vulkan-1.def" lib /def:"$out\vulkan-1.def" /machine:arm64 /out:"$out\vulkan-1.lib" # When SplitBuild is enabled, force clang into the build set even if