Map types.NoneType return type to LLVM void instead of i8*#847
Open
isVoid wants to merge 5 commits into
Open
Conversation
|
Auto-sync is disabled for ready for review pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
b4296c1 to
d195553
Compare
Add NoneTypeModel for types.NoneType that returns ir.VoidType() from get_return_type() while keeping i8* for get_value_type() (since LLVM void cannot represent values). This ensures CABI device functions returning void have correct LLVM IR signatures without unnecessary return pointer arguments. Also update the Numba and CABI calling conventions to handle void return types: - Numba ABI: use a dummy i8** return slot for void functions - CABI: emit ret_void and synthesize null value for void returns Add tests verifying the data model, Numba ABI, and CABI void returns. Closes NVIDIA#845 Made-with: Cursor
d195553 to
81cb6d2
Compare
Add a note to the NoneTypeModel docstring explaining that it shadows the OpaqueModel registration for types.NoneType in default_manager via ChainMap priority in cuda_data_manager. Made-with: Cursor
NoneTypeModel in models.py (cuda_data_manager) is the single source of truth for the NoneType data model. Remove the OpaqueModel registration for types.NoneType in cuda_models.py so there is no incorrect fallback in default_manager for the standalone path. Made-with: Cursor
isVoid
commented
Apr 3, 2026
Comment on lines
+107
to
+108
| if isinstance(restype, ir.VoidType): | ||
| return ir.IntType(8).as_pointer().as_pointer() |
Contributor
Author
There was a problem hiding this comment.
We need to return a placeholder value type because void type cannot be used in declaration for argument type. This also aligns with how the rest of Numba internally passes arguments around.
Made-with: Cursor
Contributor
Author
|
/ok to test 2fffff5 |
ZzEeKkAa
reviewed
Apr 6, 2026
|
|
||
| def test_cabi_void_device_function_signature(self): | ||
| consume = cuda.declare_device( | ||
| "consume", "void(int32)", link=consume_cabi_cu, abi="c" |
Contributor
There was a problem hiding this comment.
This by itself does not guarantee that it was inlined. In fact that code used to work properly before. Could we add tests that verify ir signature both for callee and caller
gmarkall
requested changes
Apr 7, 2026
Contributor
gmarkall
left a comment
There was a problem hiding this comment.
It's not clear to me that this is a fix that should be made - see #845 (comment)
a919957 to
62e1220
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #845:
types.void/types.NoneTypewas mapped toOpaqueModel, which usedi8*for all LLVM type queries including the return type. This caused C-ABI device functions returningvoidto emiti8* foo(...)instead ofvoid foo(...), breaking ABI compatibility and LTO linking with external C/C++ device code.NoneTypeModel (
numba_cuda/numba/cuda/models.py):cuda_data_manager, which shadows the upstreamOpaqueModelfortypes.NoneTypeindefault_managerviaChainMappriority.get_return_type()returnsir.VoidType()— used when buildingir.FunctionTypefor function signatures.get_value_type()returnsi8*(opaque pointer) — LLVM void cannot represent values, soNonestill needs a concrete type for variable assignment, alloca, store/load, and boxing/unboxing.Calling convention updates (
numba_cuda/numba/cuda/core/callconv.py):CUDACallConv.get_return_type): uses a dummyi8**return slot when the data model return type is void, preserving the existingi32 func(retslot*, args...)signature.CUDACABICallConv.return_value): emitsret_voidwhen the function return type is void.CUDACABICallConv.call_function): synthesizes a nulli8*value for void call results instead of using the void instruction as a value.Cleanup (
numba_cuda/numba/cuda/datamodel/cuda_models.py):types.NoneTyperegistration fromOpaqueModelso there is no stale fallback indefault_managerfor the standalone path.Test plan
test_nonetype_model_return_type_is_void— data modelget_return_type()returnsVoidTypetest_nonetype_model_value_type_is_opaque_ptr—get_value_type()returnsPointerTypetest_cabi_void_device_function_signature— C-ABI void function links and runs correctlytest_void_device_function_numba_abi— Numba-ABI void device function compiles and runstest_void_device_function_with_side_effect— void device function with array mutation