GH-51245: [C++][Compute][Gandiva] Add support for LLVM 23.1 - #51266
GH-51245: [C++][Compute][Gandiva] Add support for LLVM 23.1#51266HuaHuaY wants to merge 4 commits into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The LLVM>=23 JITLink lambda in engine.cc does not capture memory_manager, which should fail to compile.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds Arrow C++/Gandiva compatibility updates for LLVM 23.1, including JITLink integration adjustments, fixing scalar cast template instantiation for date/timestamp types, and ensuring generated/embedded bitcode is host-appropriate at runtime.
Changes:
- Add LLVM 23.1 to supported versions and relax Gandiva conda env LLVM pinning.
- Update Gandiva JITLink configuration and strip build-target function attributes from embedded bitcode before JIT-compiling.
- Fix
CastImpltemplate constraints for date/timestamp casts and add targeted unit tests; removestaticfrom several header template helpers to avoid LLVM/Clang-related linkage issues.
File summaries
| File | Description |
|---|---|
| cpp/src/gandiva/engine.cc | Adjust JITLink layer creation for LLVM 23+ and remove target CPU/features attrs from embedded bitcode before linking. |
| cpp/src/arrow/util/future.h | Remove static from a header template helper to avoid problematic linkage/instantiation behavior. |
| cpp/src/arrow/util/bit_block_counter.h | Remove static from header template visitors. |
| cpp/src/arrow/util/async_generator.h | Remove static from header template generator factories. |
| cpp/src/arrow/scalar.cc | Fix date/timestamp cast template constraints to match type-based dispatch. |
| cpp/src/arrow/scalar_test.cc | Add unit tests covering Date32/Date64/Timestamp CastTo paths. |
| cpp/src/arrow/compute/kernels/vector_hash.cc | Attempt to suppress unused warnings in a templated observer overload. |
| cpp/src/arrow/compute/kernels/codegen_internal.h | Remove static from header template helpers used in kernel codegen. |
| cpp/src/arrow/compute/function_internal.h | Remove static from a header template specialization for list scalar conversion. |
| cpp/src/arrow/compute/exec.cc | Remove an unused internal helper template (no longer referenced). |
| cpp/CMakeLists.txt | Add LLVM 23.1 to ARROW_LLVM_VERSIONS. |
| ci/conda_env_gandiva.txt | Unpin llvmdev to allow LLVM 23.x in the Gandiva conda environment. |
Review details
- Files reviewed: 12/12 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
HuaHuaY
left a comment
There was a problem hiding this comment.
To assist the reviewer with the review process, I submit some explanatory notes.
| template <typename T, typename VisitFunc, typename NullFunc> | ||
| requires std::is_void_v<std::invoke_result_t<VisitFunc, typename GetViewType<T>::T>> | ||
| static void VisitArrayValuesInline(const ArraySpan& arr, VisitFunc&& valid_func, | ||
| void VisitArrayValuesInline(const ArraySpan& arr, VisitFunc&& valid_func, |
There was a problem hiding this comment.
LLVM 23 added -Wunused-template to -Wall.
https://releases.llvm.org/23.1.0/tools/clang/docs/ReleaseNotes.html
-Wunused-template is now part of -Wunused (which is enabled by -Wall). It diagnoses unused function and variable templates with internal linkage, which in a header is a latent ODR hazard. It can be disabled with -Wno-unused-template. (#202945)
I don't think there's any harm in removing static. Template functions are inherently similar to inline functions, and ODR issues won't arise.
| const FunctionOptions* options_; | ||
| }; | ||
|
|
||
| template <typename ExecutorType, |
There was a problem hiding this comment.
It's a template function which doesn't have any callers.
| // date to date | ||
| template <typename To> | ||
| enable_if_t<std::is_same<To, Date64Scalar>::value, Result<std::shared_ptr<Scalar>>> | ||
| enable_if_t<std::is_same<To, Date64Type>::value, Result<std::shared_ptr<Scalar>>> |
There was a problem hiding this comment.
This is another issue exposed by -Wunused-template. The template instantiation type was incorrect here, causing the function that was supposed to execute this path to fall through to the "NotImplemented" exception instead. A unit test has been added.
| arrow::Result<T> AsArrowResult(llvm::Expected<T>& expected, | ||
| const std::string& error_context) { | ||
| if (!expected) { | ||
| // NOTE: llvm::handleAllErrors() fails linking with RTTI-disabled LLVM builds |
There was a problem hiding this comment.
This comment was supposed to be moved here from line 425 during a previous code refactoring, but it was overlooked.
| if (maybe_use_jit_link.ok()) { | ||
| ARROW_ASSIGN_OR_RAISE(static auto memory_manager, CreateMemmoryManager()); | ||
| # if LLVM_VERSION_MAJOR >= 21 | ||
| # if LLVM_VERSION_MAJOR >= 23 |
There was a problem hiding this comment.
llvm/llvm-project#192214 added one more parameter.
|
|
||
| // Built-in bitcode is JIT-compiled on the runtime host. Do not retain the target | ||
| // selected by Clang when the bitcode was built. | ||
| RemoveBuildTargetAttributes(*src_ir_module); |
There was a problem hiding this comment.
The requirements for inlining have become stricter in LLVM 23.
https://releases.llvm.org/23.1.0/docs/ReleaseNotes.html#changes-to-the-llvm-ir
alwaysinline no longer bypasses inlining compatibility checks based on target features. Inlining will only be performed if it is safe to do so.
There was a problem hiding this comment.
🟡 Changes recommended
There are a few concrete build/CI and warning-suppression issues (typoed helper name, incorrect [[maybe_unused]] placement, and unbounded LLVM conda dependency) that should be corrected before approval.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (4)
Previously missed (2) — in code that hasn't changed since the last review.
cpp/src/gandiva/engine.cc:135
- The NOTE mentions
llvm::handleAllErrors()but this function doesn't call it directly (it callsllvm::toString(...)). Rewording avoids confusion about what is actually being avoided here.
cpp/src/gandiva/engine.cc:204 - Typo in helper name:
CreateMemmoryManagershould beCreateMemoryManager(double 'm' in Memory). This is easy to miss and will propagate to the call site below.
This issue also appears on line 218 of the same file.
cpp/src/gandiva/engine.cc:222
- Call site should match the corrected helper name (
CreateMemoryManager).
});
# else
ARROW_ASSIGN_OR_RAISE(static auto memory_manager, CreateMemmoryManager());
# if LLVM_VERSION_MAJOR >= 21
jit_builder.setObjectLinkingLayerCreator([&](llvm::orc::ExecutionSession& ES) {
cpp/src/arrow/compute/kernels/vector_hash.cc:141
[[maybe_unused]]is applied to the function here, but the unused entity is the parameterindex. If-Wunused-parameteris enabled, this won't suppress the warning. Prefer applying the attribute to the parameter (or useARROW_UNUSED(index)in the body).
template <class Index>
[[maybe_unused]] void ObserveNullNotFound(Index index) {
ARROW_LOG(FATAL) << "ObserveNullNotFound without err_status should not be called";
}
- Files reviewed: 12/12 changed files
- Comments generated: 1
- Review effort level: Lite
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟢 Approval recommended
The changes are consistent with the stated LLVM 23.1 support goal, are localized, and include targeted unit coverage for the fixed scalar casting behavior.
Review details
- Files reviewed: 12/12 changed files
- Comments generated: 0 new
- Review effort level: Lite
There was a problem hiding this comment.
🟡 Changes recommended
There are correctness/build issues in the updated code paths (notably unused-warning suppression and external bitcode handling consistency) that should be addressed before merging.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
cpp/src/arrow/compute/kernels/vector_hash.cc:140
[[maybe_unused]]is applied to the function, but the warning being addressed is the unused parameterindex. This doesn’t suppress-Wunused-parameter(and may not fix the build with-Werror). Apply the attribute to the parameter instead (or explicitly ignore it).
template <class Index>
[[maybe_unused]] void ObserveNullNotFound(Index index) {
ARROW_LOG(FATAL) << "ObserveNullNotFound without err_status should not be called";
- Files reviewed: 12/12 changed files
- Comments generated: 1
- Review effort level: Lite
| auto llvm_memory_buffer_ref = AsLLVMMemoryBuffer(*buffer); | ||
| auto module_or_error = llvm::parseBitcodeFile(llvm_memory_buffer_ref, *context()); | ||
| ARROW_RETURN_NOT_OK(VerifyAndLinkModule(*module_, std::move(module_or_error))); | ||
| ARROW_ASSIGN_OR_RAISE( | ||
| auto src_ir_module, | ||
| AsArrowResult(module_or_error, "Failed to verify and link module: ")); | ||
| ARROW_RETURN_NOT_OK(VerifyAndLinkModule(*module_, std::move(src_ir_module))); |
There was a problem hiding this comment.
This comment by Copilot is wrong, isn't it? Or should we actually force the precompiled bitcode's build target attributes to the same ones as the function registry?
pitrou
left a comment
There was a problem hiding this comment.
LGTM except for the latest Copilot comment which I'm not sure about
I'm also not sure about that whether we should modify the build target attributes of external precompiled bitcode. But even if we disregard this Copilot recommendation, the only difference lies in whether LLVM decides to inline the code or not. It does not fail our unit tests. |
|
Right. Perhaps we can just ping some Gandiva maintainer so that they later run benchmarks and see if anything needs fixing. |
|
Well, some Gandiva tests have failed on the Conda C++ CI build (which uses LLVM 23.1)... |
I couldn't reproduce the issue with simply running the tests in my local environment (macOS, debug mode). I'll look into the CI failures tomorrow. |
Rationale for this change
Add support for LLVM 23.1.
What changes are included in this PR?
staticfrom some template functions in header files.CastImpltemplate instantiation aboutDateandTimestampdata types, and add a unit test.Are these changes tested?
Yes.
Are there any user-facing changes?
Yes.