From 7bcf83eb859b4ce7ffcc599835ec2e6058fbd12f Mon Sep 17 00:00:00 2001
From: Larry Gritz <lg@larrygritz.com>
Date: Wed, 4 Mar 2026 20:29:28 -0800
Subject: [PATCH] build: Support llvm 22, clang 22 for building (#2086)

Fix the minor API changes that came with LLVM 22.

Signed-off-by: Larry Gritz <lg@larrygritz.com>
---
 .github/workflows/build-steps.yml |  2 +-
 .github/workflows/ci.yml          |  6 +++---
 INSTALL.md                        |  4 ++--
 src/cmake/externalpackages.cmake  |  2 +-
 src/liboslcomp/oslcomp.cpp        |  4 ++++
 src/liboslexec/llvm_util.cpp      | 15 ++++++++++++++-
 6 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/.github/workflows/build-steps.yml b/.github/workflows/build-steps.yml
index 761938c55..a0e70070b 100644
--- a/.github/workflows/build-steps.yml
+++ b/.github/workflows/build-steps.yml
@@ -144,7 +144,7 @@ jobs:
           restore-keys: ${{inputs.nametag}}
       - name: Install LLVM and Clang
         if: inputs.llvm_action_ver != ''
-        uses: KyleMayes/install-llvm-action@98e68e10c96dffcb7bfed8b2144541a66b49aa02 # v2.0.8
+        uses: KyleMayes/install-llvm-action@ebc0426251bc40c7cd31162802432c68818ab8f0 # v2.0.9
         with:
           version: ${{ inputs.llvm_action_ver }}
       - name: Dependencies
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b62e3c47b..b5802371f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -391,7 +391,7 @@ jobs:
             setenvs: export LLVM_VERSION=14.0.0 LLVM_DISTRO_NAME=ubuntu-18.04
                             OPENIMAGEIO_CMAKE_FLAGS="-DBUILD_FMT_VERSION=7.0.1"
                             PUGIXML_VERSION=v1.10
-          - desc: latest releases gcc13/C++17 llvm18 oiio-rel exr3.4 py3.12 avx2 batch-b16avx512
+          - desc: latest releases gcc13/C++17 llvm20 oiio-rel exr3.4 py3.12 avx2 batch-b16avx512
             nametag: linux-latest-releases
             runner: ubuntu-24.04
             cc_compiler: gcc-14
@@ -604,7 +604,7 @@ jobs:
           # Windows 2022 / MSVS 17 case is below. It's not working yet,
           # work in progress.
           #
-          - desc: Windows-2022 VS2022
+          - desc: Windows-2022 VS2022 llvm20 oiio3.1
             runner: windows-2022
             nametag: windows-2022
             generator: "Visual Studio 17 2022"
@@ -617,7 +617,7 @@ jobs:
                             PUGIXML_VERSION=v1.14
                             OpenImageIO_BUILD_MISSING_DEPS="Freetype;TIFF;libdeflate;libjpeg-turbo"
                             LLVM_GOOGLE_DRIVE_ID="1uy7PNVlTQ-H56unXGOS6siRWtNcdS1J7"
-          - desc: Windows-2025 VS2022
+          - desc: Windows-2025 VS2022 llvm20 oiio3.1
             runner: windows-2025
             nametag: windows-2025
             generator: "Visual Studio 17 2022"
diff --git a/INSTALL.md b/INSTALL.md
index aa9d69188..b701a4a37 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -24,7 +24,7 @@ NEW or CHANGED minimum dependencies since the last major release are **bold**.
 
 * A suitable C++17 compiler to build OSL itself, which may be any of:
    - GCC 9.3 or newer (tested through gcc 14)
-   - Clang 5 or newer (tested through clang 20)
+   - Clang 5 or newer (tested through clang 22)
    - Microsoft Visual Studio 2017 or newer
    - Intel C++ compiler icc version 19 or newer or LLVM-based icx compiler
      version 2022 or newer.
@@ -50,7 +50,7 @@ NEW or CHANGED minimum dependencies since the last major release are **bold**.
     DYLD_LIBRARY_PATH on OS X).
 
 * [LLVM](http://www.llvm.org) **14.0 or newer**, 15, 16, 17, 18, 19, 20, 21,
-  including clang libraries.
+  22, including clang libraries.
 
 * (optional) For GPU rendering on NVIDIA GPUs:
     * [OptiX](https://developer.nvidia.com/rtx/ray-tracing/optix) 7.0 or higher.
diff --git a/src/cmake/externalpackages.cmake b/src/cmake/externalpackages.cmake
index 3906b8dec..97f0b66f6 100644
--- a/src/cmake/externalpackages.cmake
+++ b/src/cmake/externalpackages.cmake
@@ -58,7 +58,7 @@ checked_find_package (pugixml REQUIRED
 # LLVM library setup
 checked_find_package (LLVM REQUIRED
                       VERSION_MIN 14.0
-                      VERSION_MAX 21.9
+                      VERSION_MAX 22.9
                       PRINT LLVM_SYSTEM_LIBRARIES CLANG_LIBRARIES
                             LLVM_SHARED_MODE)
 # ensure include directory is added (in case of non-standard locations
diff --git a/src/liboslcomp/oslcomp.cpp b/src/liboslcomp/oslcomp.cpp
index 027f47d01..f978dd101 100644
--- a/src/liboslcomp/oslcomp.cpp
+++ b/src/liboslcomp/oslcomp.cpp
@@ -201,7 +201,11 @@ OSLCompilerImpl::preprocess_buffer(const std::string& buffer,
     inst.setTarget(target);
 
     inst.createFileManager();
+#if OSL_LLVM_VERSION >= 220
+    inst.createSourceManager();
+#else
     inst.createSourceManager(inst.getFileManager());
+#endif
     clang::SourceManager& sm = inst.getSourceManager();
     sm.setMainFileID(sm.createFileID(std::move(mbuf), clang::SrcMgr::C_User));
 
diff --git a/src/liboslexec/llvm_util.cpp b/src/liboslexec/llvm_util.cpp
index 759978888..7a9db27bf 100644
--- a/src/liboslexec/llvm_util.cpp
+++ b/src/liboslexec/llvm_util.cpp
@@ -1543,7 +1543,11 @@ LLVM_Util::make_jit_execengine(std::string* err, TargetISA requestedISA,
     // TODO: investigate if reciprocals can be disabled by other means.
     // Perhaps enable UnsafeFPMath, then modify creation of DIV instructions
     // to remove the arcp (allow reciprocal) flag on that instructions
+#if OSL_LLVM_VERSION < 220
+    // UnsafeFPMath was removed from TargetOptions in LLVM 22; FP math
+    // control is now handled via per-instruction fast-math flags in IR.
     options.UnsafeFPMath = false;
+#endif
     // Since there are OSL language functions isinf and isnan,
     // we cannot assume there will not be infs and NANs
     options.NoInfsFPMath = false;
@@ -1805,7 +1809,11 @@ LLVM_Util::nvptx_target_machine()
         // N.B. 'Standard' only allow fusion of 'blessed' ops (currently just
         // fmuladd). To truly disable FMA and never fuse FP-ops, we need to
         // instead use llvm::FPOpFusion::Strict.
-        options.UnsafeFPMath                           = 1;
+#if OSL_LLVM_VERSION < 220
+        // UnsafeFPMath was removed from TargetOptions in LLVM 22; FP math
+        // control is now handled via per-instruction fast-math flags in IR.
+        options.UnsafeFPMath = 1;
+#endif
         options.NoInfsFPMath                           = 1;
         options.NoNaNsFPMath                           = 1;
         options.HonorSignDependentRoundingFPMathOption = 0;
@@ -1817,8 +1825,13 @@ LLVM_Util::nvptx_target_machine()
 
         // Verify that the NVPTX target has been initialized
         std::string error;
+#if OSL_LLVM_VERSION >= 220
+        const llvm::Target* llvm_target
+            = llvm::TargetRegistry::lookupTarget(ModuleTriple, error);
+#else
         const llvm::Target* llvm_target
             = llvm::TargetRegistry::lookupTarget(ModuleTriple.str(), error);
+#endif
         OSL_ASSERT(llvm_target
                    && "PTX compile error: LLVM Target is not initialized");
 
