Home LLVM 20 SPIR-Vバックエンド公式昇格の技術的全貌:GlobalISelベースのGPUコンパイル統一基盤
投稿
キャンセル

✍️ LLVM 20 SPIR-Vバックエンド公式昇格の技術的全貌:GlobalISelベースのGPUコンパイル統一基盤

本記事は LLVM 20 Promotes SPIR-V to Official Backend(Khronos Group) および SPIR-V Target User Guide(LLVM 20.1.0公式ドキュメント) の解説記事です。

ブログ概要(Summary)

2025年1月28日、Khronos Groupは「LLVMの開発者がSPIR-VバックエンドをLLVM 20で実験的ステータスから公式ターゲットに昇格することに合意した」と発表しました。LLVM 20.1.0(2025年3月11日リリース)により、SPIR-Vバックエンドはデフォルトビルドに組み込まれ、-DLLVM_TARGETS_TO_BUILDで通常のターゲットとして有効化されます。Intel社が主要な貢献者として、SPIR-V LLVM Translatorとの互換性を維持しつつGlobalISelベースの命令選択を実装しています。

この記事は Zenn記事: LLVM 20〜22の進化を総整理 の深掘りです。

情報源

技術的背景(Technical Background)

SPIR-Vとは

SPIR-V(Standard Portable Intermediate Representation)は、Khronos Groupが策定するGPU向けバイナリ中間表現フォーマットです。以下のAPIのシェーダー/カーネルプログラムを統一的に表現します。

APISPIR-Vバージョン用途
Vulkan 1.0SPIR-V 1.0グラフィックス・Computeシェーダー
Vulkan 1.2SPIR-V 1.5レイトレーシング拡張等
Vulkan 1.3SPIR-V 1.6メッシュシェーダー等
OpenCL 2.0+SPIR-V 1.0+GPGPUカーネル
SYCLSPIR-V 1.0+クロスプラットフォームGPU

従来の「実験的」ステータスの意味

LLVM 20以前、SPIR-Vバックエンドは-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=SPIRVでのみ有効化できる実験的ターゲットでした。これにより以下の制約がありました。

  • デフォルトのLLVMビルドに含まれないため、多くのLinuxディストリビューションのLLVMパッケージに非搭載
  • テストインフラが限定的であり、リグレッション検出が不十分
  • APIの安定性が保証されず、破壊的変更のリスク

公式昇格の技術的変更点

ビルドシステムの変更

1
2
3
4
5
6
7
8
# LLVM 19以前: 実験的ターゲットとして指定
-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=SPIRV

# LLVM 20以降: 通常のターゲットとして指定
-DLLVM_TARGETS_TO_BUILD="X86;AArch64;SPIRV"

# またはallを指定すればSPIR-Vも含まれる
-DLLVM_TARGETS_TO_BUILD=all

GlobalISelベースの命令選択

SPIR-Vバックエンドの特筆すべき設計判断は、SelectionDAGではなくGlobalISel(Global Instruction Selection)を採用している点です。LLVMドキュメントによると、SelectionDAGへのフォールバックなしでGlobalISelのみで命令選択が行われます。

graph TB
    subgraph "従来のバックエンド(AMDGPU等)"
        A1[LLVM IR] --> B1[SelectionDAG]
        B1 --> C1[命令選択]
        C1 --> D1[レジスタ割当]
        D1 --> E1[機械語]
    end
    subgraph "SPIR-Vバックエンド"
        A2[LLVM IR] --> B2[GlobalISel<br>IRTranslator]
        B2 --> C2[Legalizer]
        C2 --> D2[InstructionSelector]
        D2 --> E2[SPIR-Vバイナリ]
    end

GlobalISelの採用理由は以下と推測されます。

  1. SPIR-Vの特殊性: SPIR-Vは物理レジスタを持たない仮想的なISAであり、SelectionDAGのDAGベースの命令選択が不要
  2. 型情報の保持: GlobalISelのGeneric MIR(Machine IR)はLLVM IRの型情報をより忠実に保持できる
  3. 拡張性: 新しいSPIR-V拡張への対応がGlobalISelの方が容易

サポートされるターゲットトリプル

LLVM 20.1.0ドキュメントによると、3つのターゲットアーキテクチャが定義されています。

ターゲットポインタ幅メモリモデル主な用途
spirv3232-bit物理メモリOpenCL(32bitデバイス)
spirv6464-bit物理メモリOpenCL(64bitデバイス)
spirv論理的論理メモリレイアウトVulkanシェーダー
1
2
3
4
5
6
7
8
9
10
11
# OpenCL向け(64bitポインタ)
clang --target=spirv64 -O2 -c kernel.cl -o kernel.spv

# Vulkan向け(論理メモリ)
clang --target=spirv -O2 -c shader.cl -o shader.spv

# Vulkan 1.3ランタイム指定
clang --target=spirv-unknown-vulkan1.3 -O2 -c shader.cl -o shader.spv

# AMD HSAランタイム指定
clang --target=spirv64-unknown-amdhsa -O2 -c kernel.cl -o kernel.spv

サポートされるSPIR-V拡張

LLVM 20.1.0ドキュメントには30以上のSPIR-V拡張が記載されています。-spirv-extフラグで個別に有効化できます。

Intel固有拡張

拡張機能
SPV_INTEL_arbitrary_precision_integers任意精度整数型
SPV_INTEL_bfloat16_conversionBF16変換命令
SPV_INTEL_function_pointers関数ポインタ
SPV_INTEL_joint_matrix行列演算(Xe GPU向け)
SPV_INTEL_subgroupsサブグループ操作
SPV_INTEL_variable_length_array可変長配列

Khronos標準拡張

拡張機能
SPV_KHR_bit_instructionsビット操作命令
SPV_KHR_float_controls浮動小数点制御
SPV_KHR_integer_dot_product整数ドット積
SPV_KHR_subgroup_rotateサブグループローテーション
1
2
3
4
5
6
7
8
# 特定拡張を有効化
clang --target=spirv64 -Xclang -spirv-ext=+SPV_KHR_float_controls kernel.cl

# 複数拡張を同時有効化
clang --target=spirv64 -Xclang -spirv-ext=+SPV_KHR_float_controls,+SPV_INTEL_subgroups kernel.cl

# 全拡張を有効化
clang --target=spirv64 -Xclang -spirv-ext=all kernel.cl

SPIR-V固有のLLVM IR表現

Opaque Type Encoding

SPIR-Vの特殊型はLLVMのTarget Extension Typeとして表現されます。

SPIR-V型LLVM表現
Imagetarget("spirv.Image", ...)
Samplertarget("spirv.Sampler")
SampledImagetarget("spirv.SampledImage", ...)
Eventtarget("spirv.Event")
Pipetarget("spirv.Pipe", ...)

Builtin関数の命名規則

SPIR-Vの組み込み関数は以下の命名規則に従います。

1
__spirv_{OpCodeName}{_OptionalPostfixes}

例:

  • __spirv_BuiltInGlobalInvocationId: グローバルインボケーションID取得
  • __spirv_AtomicIAdd: アトミック整数加算
  • __spirv_GroupNonUniformBallot: Non-uniformバロット操作

制約事項と今後の課題

現在の制約

LLVMドキュメントおよびiWOCL 2025(Intel Alexey Sachkovの発表)によると、以下の制約が存在します。

  1. Compute��ェーダー中心: グラフィックスシェーダー(Vertex、Fragment等)の完全サポートは今後の課題
  2. LLVM IRの制約: すべてのLLVM IR構造がSPIR-Vに1対1でマッピングされるわけではなく、一部の最適化パスの結果がSPIR-Vの制約に合わない場合がある
  3. SYCL統合: SYCL実装(Intel oneAPI DPC++等)でのLLVM SPIR-Vバックエンドの採用は段階的に進行中
  4. デバッグ情報: NonSemantic.Shader.DebugInfo.100による非セマンティックデバッグ情報のサポートは-spv-emit-nonsemantic-debug-infoフラグで有効化可能だが、機能は限定的

SPIR-V LLVM Translatorとの関係

LLVMプロジェクト内のSPIR-Vバックエンドと、Khronosが維持する外部プロジェクト「SPIR-V LLVM Translator」(llvm-spirv)は別のプロジェクトです。ただし、LLVM IR上でのSPIR-V表現規則(Builtin関数命名、型エンコーディング等)は互換性が維持されています。

GPUコンパイルエコシステムにおける位置づけ

graph TB
    A[C/C++<br>OpenCL C<br>SYCL] --> B[Clang]
    B --> C[LLVM IR]
    C --> D[SPIR-V Backend<br>公式ターゲット]
    C --> E[AMDGPU Backend]
    C --> F[NVPTX Backend]
    D --> G[Vulkan Driver<br>Intel, AMD, etc.]
    D --> H[OpenCL Driver]
    D --> I[SYCL Runtime]
    E --> J[AMD GPU直接実行]
    F --> K[NVIDIA GPU直接実行]

SPIR-Vバックエンドの公式化により、以下のワークフローが統一されます。

  • ベンダー非依存: AMDGPUやNVPTXバックエンドではベンダー固有のISAが生成されるが、SPIR-Vは各ベンダーのドライバが最終的なISA変換を行う
  • ポータビリティ: 同じSPIR-Vバイナリを異なるGPUベンダーのドライバで実��可能
  • テスト品質: 公式���ーゲットとしてLLVMのCI/CDパイプラインに組み込まれ、リグレッション検出が強化される

学術研究との関連(Academic Connection)

SPIR-Vバックエンドの公式化は、GPU向けコンパイラ研究に新しい基盤を提供します。特に以下の研究テーマに影響があります。

  • MLIR→SPIR-V変換: MLIRのGPU Dialectから直接SPIR-Vを生成するパスの品質向上が期待される
  • ClangIR→SPIR-V: GSoC 2024で開始されたClangIRからのSPIR-V生成パスは、公式バックエンドの安定性に依存
  • 自動最適化: SPIR-V��高レベル構造(StructuredControlFlow等)を活用した最適化研究

まとめと実践への示唆

SPIR-Vバックエンドの公式昇格は、以下の点で重要です。

  • デフォルトビルド組み込み: LLVMパッケージにSPIR-Vサポートが標準搭載される
  • GlobalISel採用: 将来のLLVMバックエンド開発のリファレンス実装として参照可能
  • 30以上のSPIR-V拡張対応: Intel、AMD、Khronos標準の拡張を-spirv-extで制御
  • OpenCL/Vulkan/SYCL統一: GPUコンパイルの統一パイプラインとして機能

GPU向けソフトウェア開発者は、--target=spirv64(OpenCL)または--target=spirv(Vulkan)でのコンパイルを試す際に、SPIR-V Target User Guideを参照してください。

参考文献

この投稿は CC BY 4.0 でライセンスされています。