Description
LibCLC uses the Asm labels feature to directly call LLVM intrinsic functions from OpenCL code.
For an example overloads of __clc_round
llvm-project/libclc/generic/lib/math/round.cl
Lines 3 to 6 in 1b6340d
would look roughly like the following after preprocessing:
__attribute__((overloadable)) half8 __clc_round(half8 d) __asm("llvm.round.v8f16");
For many (all?) intrinsics that are called like this Clang has builtins that lower to the same llvm intrinsics. For the above example __builtin_round
or __builtin_elementwise_round
could be used instead.
This might be problem because Clang will emit different IR when it knows it's calling an intrinsic and not a real function. Such unusual IR might need to be worked around in the LLVM backends of targets.
As an example for the SPIR-V target function calls receive the spir_func
calling convention by default, while intrinsic calls will not. Demonstration on Compiler Explorer
EDIT: Technically the IR generated by clang even has UB according to LangRef:
LLVM functions, calls and invokes can all have an optional calling convention specified for the call. The calling convention of any pair of dynamic caller/callee must match, or the behavior of the program is undefined.