Skip to content

Commit e9a8ec5

Browse files
build: Add compatibility with LLVM 21 (#2030)
This adds LLVM 21 compatibility by adding the relevant code changes guarded by `#ifdev`-statements for backwards compatibility. Avoid deprecated LLVM calls for 21+ Additionally also add CI checks for this. --------- Signed-off-by: Christian Heusel <[email protected]> Signed-off-by: Larry Gritz <[email protected]> Co-authored-by: Larry Gritz <[email protected]>
1 parent c7d7ec2 commit e9a8ec5

File tree

7 files changed

+96
-32
lines changed

7 files changed

+96
-32
lines changed

.github/workflows/build-steps.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ jobs:
101101
CTEST_TEST_TIMEOUT: ${{inputs.ctest_test_timeout}}
102102
USE_SIMD: ${{inputs.simd}}
103103
FMT_VERSION: ${{inputs.fmt_ver}}
104+
fmt_BUILD_VERSION: ${{inputs.fmt_ver}}
104105
OPENCOLORIO_VERSION: ${{inputs.opencolorio_ver}}
105106
OPENEXR_VERSION: ${{inputs.openexr_ver}}
106107
OPENIMAGEIO_VERSION: ${{inputs.openimageio_ver}}
@@ -134,7 +135,7 @@ jobs:
134135
restore-keys: ${{inputs.nametag}}
135136
- name: Install LLVM and Clang
136137
if: inputs.llvm_action_ver != ''
137-
uses: KyleMayes/install-llvm-action@a7a1a882e2d06ebe05d5bb97c3e1f8c984ae96fc # v2.0.7
138+
uses: KyleMayes/install-llvm-action@98e68e10c96dffcb7bfed8b2144541a66b49aa02 # v2.0.8
138139
with:
139140
version: ${{ inputs.llvm_action_ver }}
140141
- name: Dependencies

.github/workflows/ci.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -543,15 +543,14 @@ jobs:
543543
openimageio_ver: main
544544
python_ver: "3.13"
545545
setenvs: export LLVMBREWVER="@19"
546-
- desc: MacOS-15-ARM aclang16/C++17/py3.13 llvm19 oiio-main
546+
- desc: MacOS-15-ARM aclang16/C++17/py3.13 llvm21 oiio-main
547547
runner: macos-15
548548
nametag: macos15-arm-py313
549549
cc_compiler: clang
550550
cxx_compiler: clang++
551551
cxx_std: 17
552552
python_ver: "3.13"
553553
openimageio_ver: main
554-
setenvs: export LLVMBREWVER="@19"
555554

556555

557556
windows:

INSTALL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ NEW or CHANGED minimum dependencies since the last major release are **bold**.
4949
$OpenImageIO_ROOT/lib to be in your LD_LIBRARY_PATH (or
5050
DYLD_LIBRARY_PATH on OS X).
5151

52-
* [LLVM](http://www.llvm.org) **14.0 or newer**, 15, 16, 17, 18, 19, 20,
52+
* [LLVM](http://www.llvm.org) **14.0 or newer**, 15, 16, 17, 18, 19, 20, 21,
5353
including clang libraries.
5454

5555
* (optional) For GPU rendering on NVIDIA GPUs:

src/cmake/externalpackages.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ checked_find_package (pugixml REQUIRED
5858
# LLVM library setup
5959
checked_find_package (LLVM REQUIRED
6060
VERSION_MIN 14.0
61-
VERSION_MAX 20.9
61+
VERSION_MAX 21.9
6262
PRINT LLVM_SYSTEM_LIBRARIES CLANG_LIBRARIES
6363
LLVM_SHARED_MODE)
6464
# ensure include directory is added (in case of non-standard locations

src/liboslcomp/oslcomp.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,19 +171,32 @@ OSLCompilerImpl::preprocess_buffer(const std::string& buffer,
171171
llvm::raw_string_ostream errstream(preproc_errors);
172172
clang::DiagnosticOptions* diagOptions = new clang::DiagnosticOptions();
173173
clang::TextDiagnosticPrinter* diagPrinter
174+
#if OSL_LLVM_VERSION < 210
174175
= new clang::TextDiagnosticPrinter(errstream, diagOptions);
176+
#else
177+
= new clang::TextDiagnosticPrinter(errstream, *diagOptions);
178+
#endif
175179
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagIDs(
176180
new clang::DiagnosticIDs);
177181
clang::DiagnosticsEngine* diagEngine
182+
#if OSL_LLVM_VERSION < 210
178183
= new clang::DiagnosticsEngine(diagIDs, diagOptions, diagPrinter);
184+
#else
185+
= new clang::DiagnosticsEngine(diagIDs, *diagOptions, diagPrinter);
186+
#endif
179187
inst.setDiagnostics(diagEngine);
180188

181189
const std::shared_ptr<clang::TargetOptions> targetopts
182190
= std::make_shared<clang::TargetOptions>(inst.getTargetOpts());
183191
targetopts->Triple = llvm::sys::getDefaultTargetTriple();
184192
clang::TargetInfo* target
193+
#if OSL_LLVM_VERSION < 210
185194
= clang::TargetInfo::CreateTargetInfo(inst.getDiagnostics(),
186195
targetopts);
196+
#else
197+
= clang::TargetInfo::CreateTargetInfo(inst.getDiagnostics(),
198+
*targetopts);
199+
#endif
187200

188201
inst.setTarget(target);
189202

src/liboslexec/llvm_instance.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2225,7 +2225,11 @@ BackendLLVM::run()
22252225
// The triple is empty with recent versions of LLVM (e.g., 15) for reasons that aren't
22262226
// clear. So we must set them to the expected values.
22272227
// See: https://llvm.org/docs/NVPTXUsage.html
2228+
# if OSL_LLVM_VERSION < 210
22282229
ll.module()->setTargetTriple("nvptx64-nvidia-cuda");
2230+
# else
2231+
ll.module()->setTargetTriple(llvm::Triple("nvptx64-nvidia-cuda"));
2232+
# endif
22292233
ll.module()->setDataLayout(
22302234
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-i128:128:128-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64");
22312235

src/liboslexec/llvm_util.cpp

Lines changed: 74 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -476,27 +476,13 @@ LLVM_Util::LLVM_Util(const PerThreadInfo& per_thread_info, int debuglevel,
476476
m_llvm_type_longlong = (llvm::Type*)llvm::Type::getInt64Ty(*m_llvm_context);
477477
m_llvm_type_void = (llvm::Type*)llvm::Type::getVoidTy(*m_llvm_context);
478478

479-
m_llvm_type_int_ptr = llvm::PointerType::get(m_llvm_type_int, 0);
480-
m_llvm_type_int8_ptr = llvm::PointerType::get(m_llvm_type_int8, 0);
481-
m_llvm_type_int64_ptr = llvm::PointerType::get(m_llvm_type_int64, 0);
482-
m_llvm_type_bool_ptr = llvm::PointerType::get(m_llvm_type_bool, 0);
483-
m_llvm_type_char_ptr = llvm::PointerType::get(m_llvm_type_char, 0);
484-
m_llvm_type_void_ptr = m_llvm_type_char_ptr;
485-
m_llvm_type_float_ptr = llvm::PointerType::get(m_llvm_type_float, 0);
486-
m_llvm_type_longlong_ptr = llvm::PointerType::get(m_llvm_type_int64, 0);
487-
m_llvm_type_double_ptr = llvm::PointerType::get(m_llvm_type_double, 0);
488-
489479
// A triple is a struct composed of 3 floats
490480
std::vector<llvm::Type*> triplefields(3, m_llvm_type_float);
491481
m_llvm_type_triple = type_struct(triplefields, "Vec3");
492-
m_llvm_type_triple_ptr
493-
= (llvm::PointerType*)llvm::PointerType::get(m_llvm_type_triple, 0);
494482

495483
// A matrix is a struct composed 16 floats
496484
std::vector<llvm::Type*> matrixfields(16, m_llvm_type_float);
497485
m_llvm_type_matrix = type_struct(matrixfields, "Matrix4");
498-
m_llvm_type_matrix_ptr
499-
= (llvm::PointerType*)llvm::PointerType::get(m_llvm_type_matrix, 0);
500486

501487
// Setup up wide aliases
502488
// TODO: why are there casts to the base class llvm::Type *?
@@ -511,6 +497,48 @@ LLVM_Util::LLVM_Util(const PerThreadInfo& per_thread_info, int debuglevel,
511497
m_llvm_type_wide_longlong = llvm_vector_type(m_llvm_type_longlong,
512498
m_vector_width);
513499

500+
// A twide riple is a struct composed of 3 wide floats
501+
std::vector<llvm::Type*> triple_wide_fields(3, m_llvm_type_wide_float);
502+
m_llvm_type_wide_triple = type_struct(triple_wide_fields, "WideVec3");
503+
504+
// A wide matrix is a struct composed 16 wide floats
505+
std::vector<llvm::Type*> matrix_wide_fields(16, m_llvm_type_wide_float);
506+
m_llvm_type_wide_matrix = type_struct(matrix_wide_fields, "WideMatrix4");
507+
508+
#if OSL_LLVM_VERSION >= 210
509+
// All opaque pointers now. Eventually, all the typed ones can go away.
510+
m_llvm_type_void_ptr = llvm::PointerType::get(*m_llvm_context, 0);
511+
m_llvm_type_int_ptr = m_llvm_type_void_ptr;
512+
m_llvm_type_int8_ptr = m_llvm_type_void_ptr;
513+
m_llvm_type_int64_ptr = m_llvm_type_void_ptr;
514+
m_llvm_type_bool_ptr = m_llvm_type_void_ptr;
515+
m_llvm_type_char_ptr = m_llvm_type_void_ptr;
516+
m_llvm_type_float_ptr = m_llvm_type_void_ptr;
517+
m_llvm_type_longlong_ptr = m_llvm_type_void_ptr;
518+
m_llvm_type_double_ptr = m_llvm_type_void_ptr;
519+
m_llvm_type_triple_ptr = m_llvm_type_void_ptr;
520+
m_llvm_type_matrix_ptr = m_llvm_type_void_ptr;
521+
m_llvm_type_wide_char_ptr = m_llvm_type_void_ptr;
522+
m_llvm_type_wide_void_ptr = m_llvm_type_void_ptr;
523+
m_llvm_type_wide_int_ptr = m_llvm_type_void_ptr;
524+
m_llvm_type_wide_bool_ptr = m_llvm_type_void_ptr;
525+
m_llvm_type_wide_float_ptr = m_llvm_type_void_ptr;
526+
#else
527+
// Old style typed pointers. These are marked as deprecated in LLVM 21,
528+
// and will be removed in some subsequent version.
529+
m_llvm_type_int_ptr = llvm::PointerType::get(m_llvm_type_int, 0);
530+
m_llvm_type_int8_ptr = llvm::PointerType::get(m_llvm_type_int8, 0);
531+
m_llvm_type_int64_ptr = llvm::PointerType::get(m_llvm_type_int64, 0);
532+
m_llvm_type_bool_ptr = llvm::PointerType::get(m_llvm_type_bool, 0);
533+
m_llvm_type_char_ptr = llvm::PointerType::get(m_llvm_type_char, 0);
534+
m_llvm_type_void_ptr = m_llvm_type_char_ptr;
535+
m_llvm_type_float_ptr = llvm::PointerType::get(m_llvm_type_float, 0);
536+
m_llvm_type_longlong_ptr = llvm::PointerType::get(m_llvm_type_int64, 0);
537+
m_llvm_type_double_ptr = llvm::PointerType::get(m_llvm_type_double, 0);
538+
m_llvm_type_triple_ptr
539+
= (llvm::PointerType*)llvm::PointerType::get(m_llvm_type_triple, 0);
540+
m_llvm_type_matrix_ptr
541+
= (llvm::PointerType*)llvm::PointerType::get(m_llvm_type_matrix, 0);
514542
m_llvm_type_wide_char_ptr = llvm::PointerType::get(m_llvm_type_wide_char,
515543
0);
516544
m_llvm_type_wide_void_ptr = llvm_vector_type(m_llvm_type_void_ptr,
@@ -520,14 +548,7 @@ LLVM_Util::LLVM_Util(const PerThreadInfo& per_thread_info, int debuglevel,
520548
0);
521549
m_llvm_type_wide_float_ptr = llvm::PointerType::get(m_llvm_type_wide_float,
522550
0);
523-
524-
// A triple is a struct composed of 3 floats
525-
std::vector<llvm::Type*> triple_wide_fields(3, m_llvm_type_wide_float);
526-
m_llvm_type_wide_triple = type_struct(triple_wide_fields, "WideVec3");
527-
528-
// A matrix is a struct composed 16 floats
529-
std::vector<llvm::Type*> matrix_wide_fields(16, m_llvm_type_wide_float);
530-
m_llvm_type_wide_matrix = type_struct(matrix_wide_fields, "WideMatrix4");
551+
#endif
531552

532553
ustring_rep(m_ustring_rep); // setup ustring-related types
533554
}
@@ -545,14 +566,20 @@ LLVM_Util::ustring_rep(UstringRep rep)
545566
OSL_ASSERT(m_ustring_rep == UstringRep::hash);
546567
m_llvm_type_ustring = llvm::Type::getInt64Ty(*m_llvm_context);
547568
}
548-
m_llvm_type_ustring_ptr = llvm::PointerType::get(m_llvm_type_ustring, 0);
549569

550570
// Batched versions haven't been updated to handle hash yet.
551571
// For now leave them using the real ustring regardless of UstringRep
552572
m_llvm_type_wide_ustring = llvm_vector_type(m_llvm_type_real_ustring,
553573
m_vector_width);
574+
575+
#if OSL_LLVM_VERSION >= 210
576+
m_llvm_type_ustring_ptr = m_llvm_type_void_ptr;
577+
m_llvm_type_wide_ustring_ptr = m_llvm_type_void_ptr;
578+
#else
579+
m_llvm_type_ustring_ptr = llvm::PointerType::get(m_llvm_type_ustring, 0);
554580
m_llvm_type_wide_ustring_ptr
555581
= llvm::PointerType::get(m_llvm_type_wide_ustring, 0);
582+
#endif
556583
}
557584

558585

@@ -1790,8 +1817,13 @@ LLVM_Util::nvptx_target_machine()
17901817
&& "PTX compile error: LLVM Target is not initialized");
17911818

17921819
m_nvptx_target_machine = llvm_target->createTargetMachine(
1793-
ModuleTriple.str(), CUDA_TARGET_ARCH, "+ptx50", options,
1794-
llvm::Reloc::Static, llvm::CodeModel::Small,
1820+
#if OSL_LLVM_VERSION >= 210
1821+
llvm::Triple(ModuleTriple.str()),
1822+
#else
1823+
ModuleTriple.str(),
1824+
#endif
1825+
CUDA_TARGET_ARCH, "+ptx50", options, llvm::Reloc::Static,
1826+
llvm::CodeModel::Small,
17951827
#if OSL_LLVM_VERSION >= 180
17961828
llvm::CodeGenOptLevel::Default
17971829
#else
@@ -2911,7 +2943,11 @@ LLVM_Util::type_struct_field_at_index(llvm::Type* type, int index)
29112943
llvm::PointerType*
29122944
LLVM_Util::type_ptr(llvm::Type* type)
29132945
{
2946+
#if OSL_LLVM_VERSION >= 210
2947+
return m_llvm_type_void_ptr;
2948+
#else
29142949
return llvm::PointerType::get(type, 0);
2950+
#endif
29152951
}
29162952

29172953
llvm::Type*
@@ -2959,8 +2995,12 @@ llvm::PointerType*
29592995
LLVM_Util::type_function_ptr(llvm::Type* rettype, cspan<llvm::Type*> params,
29602996
bool varargs)
29612997
{
2998+
#if OSL_LLVM_VERSION >= 210
2999+
return m_llvm_type_void_ptr;
3000+
#else
29623001
llvm::FunctionType* functype = type_function(rettype, params, varargs);
29633002
return llvm::PointerType::getUnqual(functype);
3003+
#endif
29643004
}
29653005

29663006

@@ -3784,8 +3824,7 @@ llvm::Value*
37843824
LLVM_Util::ptr_to_cast(llvm::Value* val, llvm::Type* type,
37853825
const std::string& llname)
37863826
{
3787-
return builder().CreatePointerCast(val, llvm::PointerType::get(type, 0),
3788-
llname);
3827+
return builder().CreatePointerCast(val, type_ptr(type), llname);
37893828
}
37903829

37913830

@@ -3803,14 +3842,22 @@ llvm::Value*
38033842
LLVM_Util::ptr_cast(llvm::Value* val, const TypeDesc& type,
38043843
const std::string& llname)
38053844
{
3845+
#if OSL_LLVM_VERSION >= 210
3846+
return ptr_cast(val, m_llvm_type_void_ptr, llname);
3847+
#else
38063848
return ptr_cast(val, llvm::PointerType::get(llvm_type(type), 0), llname);
3849+
#endif
38073850
}
38083851

38093852

38103853
llvm::Value*
38113854
LLVM_Util::wide_ptr_cast(llvm::Value* val, const TypeDesc& type)
38123855
{
3856+
#if OSL_LLVM_VERSION >= 210
3857+
return ptr_cast(val, m_llvm_type_void_ptr);
3858+
#else
38133859
return ptr_cast(val, llvm::PointerType::get(llvm_vector_type(type), 0));
3860+
#endif
38143861
}
38153862

38163863

0 commit comments

Comments
 (0)