Llvm.memmove instruction question

Can you please explain the warning message shown below ? Should I modify the kernel function to work around the issue ?


warning: [Computecpp:CC0035]: Intrinsic llvm.memmove.p3i8.p1i8.i64 has been generated in function
SYCL_class_kernel which is illegal in SPIR and may result in a compilation failure

Hey zjin,

Yes, you should consider getting rid of the warning in order to guarantee a healthier and safer compilation of your project.

In short, the SPIR spec only allows for memset and memcpy intrinsics to be used and anything else is technically illegal and could cause issues with the OpenCL implementation.

Basically what the llvm.memmove intrinsic does, similarly to llvm.memcpy, is to move a block of memory from the source location to the destination location. But where it differs from llvm.memcpy, which is supported by SPIR, is that it allows both memory locations to overlap (used to handle overlapping memory transfers).
If you go on the SPIR (1.2) specification - page 21 (section 3.4) you can see which are the LLVM supported intrinsic functions.

Although memory regions may be overlapping on hardware level (in physical memory), OpenCL treats a memory region as a (logically) distinct address space (private, local, global, constant), thus overlapping in OpenCL device memory is not allowed.

So, even if your code compiles correctly, there is no guarantee it behaves as it should and in fact, even if it does, this may only be the case for the OpenCL implementation that you are using. Therefore, cross-platform support is not guaranteed and ComputeCpp reports this message to warn the developers for illegal *mem operation. You can read more about this kind of warning on our Compiler (compute++) guide page.

If you are not aware of the cause of this warning in your code base, I would suggest you to may be debug your program and investigate the generated SPIR output and then try and narrow down the specific location of the operation. You can compile the program by outputting the IR (without linking and generating the executable binary), by adding the -emit-llvm flag when calling the compute++. For reference, you can compile with the following command:

/path/to/computecpp/bin/compute++ -std=<cpp_version> -O<level> -sycl -emit-llvm -I /path/to/computecpp/include -o <program_name>.cpp.bc -c <program_name>.cpp

Or you may use Oclgrind by calling on the already compiled binary that you’ve got with the --dump-spir flag which dumps out compiled OpenCL program objects in SPIR form to a temporary file (for debugging purposes). The easiest installation is apt-get install oclgrind (not the latest version).

You can try this approach and see where it goes from there. Let me know what you find out what is the problem or there’s anything that’s not clear.


Thanks again for your great explanation.