Skip to content

build: Fix compilation and runtime errors with LLVM 22#2124

Merged
lgritz merged 1 commit into
AcademySoftwareFoundation:mainfrom
sergeyvfx:llvm_22_debug
Jun 5, 2026
Merged

build: Fix compilation and runtime errors with LLVM 22#2124
lgritz merged 1 commit into
AcademySoftwareFoundation:mainfrom
sergeyvfx:llvm_22_debug

Conversation

@sergeyvfx
Copy link
Copy Markdown
Contributor

This commit fixes compilation and runtime errors of the OSL against specific builds of LLVM 22.

When LLVM is compiled with LLVM_LINK_LLVM_DYLIB=OFF (default value) an extra set of libraries needs to be used for Clang:

  • The clangOptions library is needed because getDriverOptTable() used from clangFrontend was moved from clangDriver to clangOptions.

  • Similarly, printStats() used from clangSema has been moved to clangAnalysisLifetimeSafety.

This linking error could be reproduced when LLVM is compiled with the following options:

cmake \
  -GNinja \
  -DCMAKE_BUILD_TYPE=Release \
  -DLLVM_INCLUDE_TESTS=OFF \
  -DLLVM_INCLUDE_EXAMPLES=OFF \
  -DLLVM_BUILD_LLVM_C_DYLIB=OFF \
  -DLLVM_ENABLE_UNWIND_TABLES=OFF \
  -DLLVM_ENABLE_ZSTD=OFF \
  -DLLVM_ENABLE_ZLIB=OFF \
  -DLLVM_ENABLE_PROJECTS=clang \
  -DCMAKE_INSTALL_PREFIX=/opt/local/llvm/22.1.7 \
  ../llvm

A couple of notes:

  • The linking issue can not be reproduced when using Homebrew's LLVM 22 because it uses LLVM_LINK_LLVM_DYLIB=ON. This seems to be leading to a situation when the linker issue is side-steps because of the symbols that are pulled by the dynamic LLVM library.

  • Passing LLVM_STATIC does not help with this case, since this flag only affects the way LLVM libraries are handled and does not change the way Clang libraries are handled: llvm-config --libfiles --link-static does not print any Clang-related libraries.

Since LLVM version 22 the VFS is to be explicitly created for the CompilerInstance. Prior to version 22 this was done implicitly by the LLVM when calling createFileManager(), but now this is no longer the case, and LLVM has an assertion for it. The createVirtualFileSystem() with default arguments solves this problem, and initializes CompilerInstance's VFS the same way how it was done implicitly in the older versions of LLVM. Without this, compilation of OSO triggers an assert() in LLVM:

Assertion failed: (VFS && "CompilerInstance needs a VFS for creating FileManager"), function
createFileManager, file CompilerInstance.cpp, line 387.

It is unclear whether this was causing any actual issue with release builds of LLVM, but it is better to use the API in the way it is expected to be used and create the VFS.

Last but not least, this change also fixes the following assert on the LLVM side when running OSL's test suite on macOS:

Assertion failed: ((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) && "Invalid size"), function emitIntValue, file MCStreamer.cpp, line 135.

The value that trips on this assert statement comes from the DW_AT_APPLE_major_runtime_vers that the code in DwarfDebug.cpp, and it comes from the RuntimeVersion (RV) argument of the createCompileUnit(). This runtime value is supposed to indicate Obj-C runtime version which is either 1 or 2 (value 2 is for Objective-C 2.0). Passing OSL version as the runtime version does not fit single byte, and that is why the assertion trips. This change follows Clang's code which sets the runtime version to 0 for non-Objective-C languages. It is unclear what side-effects this change could bring, but it is also a bit strange to use OSL version for things that distinguish system runtime.

In order to be able to run OSL regression tests with LLVM compiled in debug mode, LLVM_LINK_LLVM_DYLIB=ON had to be used. Without this, the following assert in the LLVM triggers upon testrender startup:

: CommandLine Error: Option 'openmp-ir-builder-optimistic-attributes' registered more than once!
LLVM ERROR: inconsistency in registered CommandLine options

This is to do with the way how LLVM registers command line arguments. It uses static variable initialization for this, and having LLVM as a static library that is pulled via CLang into both oslcomp and oslexec that are then pulled into testrender causes this situation to happen. For some reason, it does not happen if LLVM is compiled as static but release library.

The need of debug versions of OSL and LLVM libraries comes from the need to compile Blender on Windows in Debug mode, and libraries need to be compiled with a different CRT ABI.

Tested with the ctest with both LLVM 20 and 22 compiled in release. With all these changes the test suite passes to the same degree for LLVM 20 and 22, both Debug and Release. The only failing tests are related to Python module, and those I did not yet manage to get passing on a local development machine.

------ ✂️ -------------------------------------------------------------------

Checklist:

  • I have read the guidelines on contributions and code review procedures.
  • I have read the Policy on AI Coding Assistants
    and if I used AI coding assistants, I have an Assisted-by: TOOL / MODEL
    line in the pull request description above.
  • I have updated the documentation if my PR adds features or changes
    behavior.
  • I am sure that this PR's changes are tested in the testsuite.
  • I have run and passed the testsuite in CI before submitting the
    PR, by pushing the changes to my fork and seeing that the automated CI
    passed there. (Exceptions: If most tests pass and you can't figure out why
    the remaining ones fail, it's ok to submit the PR and ask for help. Or if
    any failures seem entirely unrelated to your change; sometimes things break
    on the GitHub runners.)
  • My code follows the prevailing code style of this project and I
    fixed any problems reported by the clang-format CI test.

This commit fixes compilation and runtime errors of the OSL against
specific builds of LLVM 22.

When LLVM is compiled with LLVM_LINK_LLVM_DYLIB=OFF (default value) an
extra set of libraries needs to be used for Clang:

- The clangOptions library is needed because getDriverOptTable() used
  from clangFrontend was moved from clangDriver to clangOptions.

- Similarly, printStats() used from clangSema has been moved to
  clangAnalysisLifetimeSafety.

This linking error could be reproduced when LLVM is compiled with the
following options:

```
cmake \
  -GNinja \
  -DCMAKE_BUILD_TYPE=Release \
  -DLLVM_INCLUDE_TESTS=OFF \
  -DLLVM_INCLUDE_EXAMPLES=OFF \
  -DLLVM_BUILD_LLVM_C_DYLIB=OFF \
  -DLLVM_ENABLE_UNWIND_TABLES=OFF \
  -DLLVM_ENABLE_ZSTD=OFF \
  -DLLVM_ENABLE_ZLIB=OFF \
  -DLLVM_ENABLE_PROJECTS=clang \
  -DCMAKE_INSTALL_PREFIX=/opt/local/llvm/22.1.7 \
  ../llvm
```

A couple of notes:

- The linking issue can not be reproduced when using Homebrew's
  LLVM 22 because it uses LLVM_LINK_LLVM_DYLIB=ON. This seems to be
  leading to a situation when the linker issue is side-steps because
  of the symbols that are pulled by the dynamic LLVM library.

- Passing LLVM_STATIC does not help with this case, since this flag
  only affects the way LLVM libraries are handled and does not change
  the way Clang libraries are handled:
  `llvm-config --libfiles --link-static` does not print any
  Clang-related libraries.

Since LLVM version 22 the VFS is to be explicitly created for the
CompilerInstance. Prior to version 22 this was done implicitly by the
LLVM when calling createFileManager(), but now this is no longer the
case, and LLVM has an assertion for it. The createVirtualFileSystem()
with default arguments solves this problem, and initializes
CompilerInstance's VFS the same way how it was done implicitly in the
older versions of LLVM. Without this, compilation of OSO triggers an
assert() in LLVM:

```
Assertion failed: (VFS && "CompilerInstance needs a VFS for creating FileManager"), function
createFileManager, file CompilerInstance.cpp, line 387.
```

It is unclear whether this was causing any actual issue with release
builds of LLVM, but it is better to use the API in the way it is
expected to be used and create the VFS.

Last but not least, this change also fixes the following assert on the
LLVM side when running OSL's test suite on macOS:

```
Assertion failed: ((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) && "Invalid size"), function emitIntValue, file MCStreamer.cpp, line 135.
```

The value that trips on this assert statement comes from the
DW_AT_APPLE_major_runtime_vers that the code in DwarfDebug.cpp, and it
comes from the RuntimeVersion (RV) argument of the createCompileUnit().
This runtime value is supposed to indicate Obj-C runtime version which
is either 1 or 2 (value 2 is for Objective-C 2.0). Passing OSL version
as the runtime version does not fit single byte, and that is why the
assertion trips. This change follows Clang's code which sets the
runtime version to 0 for non-Objective-C languages. It is unclear what
side-effects this change could bring, but it is also a bit strange to
use OSL version for things that distinguish system runtime.

In order to be able to run OSL regression tests with LLVM compiled in
debug mode, LLVM_LINK_LLVM_DYLIB=ON had to be used. Without this, the
following assert in the LLVM triggers upon testrender startup:

```
: CommandLine Error: Option 'openmp-ir-builder-optimistic-attributes' registered more than once!
LLVM ERROR: inconsistency in registered CommandLine options
```

This is to do with the way how LLVM registers command line arguments.
It uses static variable initialization for this, and having LLVM as a
static library that is pulled via CLang into both oslcomp and oslexec
that are then pulled into testrender causes this situation to happen.
For some reason, it does not happen if LLVM is compiled as static but
release library.

The need of debug versions of OSL and LLVM libraries comes from the
need to compile Blender on Windows in Debug mode, and libraries need
to be compiled with a different CRT ABI.

Tested with the ctest with both LLVM 20 and 22 compiled in release.
With all these changes the test suite passes to the same degree for
LLVM 20 and 22, both Debug and Release. The only failing tests are
related to Python module, and those I did not yet manage to get passing
on a local development machine.

Signed-off-by: Sergey Sharybin <sergey@blender.org>
Copy link
Copy Markdown
Collaborator

@lgritz lgritz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the deep dive in tracking this down and explaining it.

@lgritz lgritz merged commit 1a72c47 into AcademySoftwareFoundation:main Jun 5, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants