Skip to content

Commit 2164723

Browse files
committed
Fix CABI return type mismatch when calling Numba-ABI subroutines
In `user_function`, `return_status_propagate` was called with the callee's calling convention (`fndesc.call_conv`). When a CABI function called a Numba-ABI subroutine (e.g. an overloaded function compiled via `compile_subroutine`), the Numba-ABI convention emitted `ret i32 <status>` inside a function whose declared return type was the user type (e.g. `i8*` for NoneType), producing invalid LLVM IR and an NVVM `ERROR_INVALID_IR` verification failure. Use the caller's calling convention (`context.fndesc.call_conv`) instead, which correctly delegates to `CUDACABICallConv. return_status_propagate` (a no-op, since C ABI has no error-status channel). Closes #841 Made-with: Cursor
1 parent 7928b8b commit 2164723

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

numba_cuda/numba/cuda/core/imputils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,9 @@ def imp(context, builder, sig, args, fndesc=fndesc):
222222

223223
if status is not None:
224224
with cgutils.if_unlikely(builder, status.is_error):
225-
fndesc.call_conv.return_status_propagate(builder, status)
225+
context.fndesc.call_conv.return_status_propagate(
226+
builder, status
227+
)
226228

227229
assert sig.return_type == fndesc.restype
228230

numba_cuda/numba/cuda/tests/cudapy/test_compiler.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import os
55
from math import sqrt
66
from numba import cuda
7-
from numba.core.extending import intrinsic
7+
from numba.core.extending import intrinsic, overload
88

99
from numba.cuda import float32, int16, int32, int64, types, uint32, void
1010
from numba.cuda import (
@@ -837,6 +837,34 @@ def wrapper_func(x):
837837
wrapper_func, types.int32(types.int32), output="ltoir", abi="c"
838838
)
839839

840+
def test_compile_CABI_calling_overloaded_function(self):
841+
# Reproducer from gh-841
842+
# https://github.com/NVIDIA/numba-cuda/issues/841
843+
#
844+
# When a CABI function calls an overloaded function (compiled as a
845+
# Numba-ABI subroutine), the error-status return path must use the
846+
# caller's calling convention. Previously the callee's Numba-ABI
847+
# convention was used, emitting `ret i32` (the status code) inside a
848+
# function whose declared return type did not match, producing invalid
849+
# LLVM IR.
850+
851+
def _my_func(x):
852+
pass
853+
854+
@overload(_my_func)
855+
def _ov_my_func(x):
856+
if isinstance(x, types.IntegerLiteral):
857+
858+
def impl(x):
859+
return int32(0)
860+
861+
return impl
862+
863+
def caller():
864+
_my_func(0)
865+
866+
cuda.compile(caller, (), abi_info={"abi_name": "caller"}, abi="c")
867+
840868
def test_compile_complex_div_c_abi(self):
841869
# Reproducer from gh-789
842870
# https://github.com/NVIDIA/numba-cuda/issues/789

0 commit comments

Comments
 (0)