Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++ for OpenCL: Unresolved external reference to _Z13get_global_idj #2908

Open
Calandracas606 opened this issue Dec 5, 2024 · 1 comment

Comments

@Calandracas606
Copy link

The translator is generating spirv with function calls which should be treated as builtins.

This is only occurring when clang is run with the C++ for OpenCL mode.

When run in clc++ mode, clang generates a !opencl.cxx.version = !{!3} entry, which seems to be causing some issues.

Here is an easy way to reproduce:

kernel.cl:

// this sample doesn't use any C++ for OpenCL features
__kernel void sample(write_only image2d_t img) {

  const int col = get_global_id(0);
  const int row = get_global_id(1);
  int2 coord;
  coord.x = col;
  coord.y = row;

  float4 px = {0, 0, 0, 1};

  write_imagef(img, coord, px);
}

run:
clang -target spirv64 -cl-std=clc++ kernel.cl
error: 0: Unresolved external reference to "_Z13get_global_idj".

Examine the generated spirv:
clang -c -target spirv64 -cl-std=clc++ -emit-llvm -o - kernel.cl | llvm-spirv -o - | spirv-dis
Notice how the spirv contains some odd OpFunctionCall:

         %22 = OpFunctionCall %ulong %_Z13get_global_idj %uint_0
         %23 = OpUConvert %uint %22
         %25 = OpFunctionCall %ulong %_Z13get_global_idj %uint_1
         %26 = OpUConvert %uint %25
         %28 = OpCompositeInsert %v2uint %23 %27 0
         %29 = OpCompositeInsert %v2uint %26 %28 1
         %33 = OpFunctionCall %void %_Z12write_imagef14ocl_image2d_woDv2_iDv4_f %19 %29 %32

Looking at the llvm generated by clang:
clang -c -target spirv64 -cl-std=clc++ -emit-llvm -o - kernel.cl | llvm-dis
Notice the !opencl.cxx.version = !{!3}

If I edit the llvm, and pass it back through llvm-spirv:

clang -c -target spirv64 -cl-std=clc++ -emit-llvm -o - kernel.cl \
     | llvm-dis -o - \
     | sed '/!opencl.cxx.version/d' \
     | llvm-as -o - \
     | llvm-spirv -o - \
     | spirv-dis

The output appears normal:

         %12 = OpLoad %v3ulong %__spirv_BuiltInGlobalInvocationId Aligned 32
         %13 = OpCompositeExtract %ulong %12 0
         %15 = OpUConvert %uint %13
         %16 = OpLoad %v3ulong %__spirv_BuiltInGlobalInvocationId Aligned 32
         %17 = OpCompositeExtract %ulong %16 1
         %18 = OpUConvert %uint %17
         %21 = OpCompositeInsert %v2uint %15 %20 0
         %22 = OpCompositeInsert %v2uint %18 %21 1
                     OpImageWrite %10 %22 %27

We can verify that this links correctly by running spirv-link.

Repeating the same processes, but running clang without -cl-std=clc++ results in no errors. The only meaningful difference in the generated llvm is the !opencl.cxx.version = !{!3} tag

related issue: llvm/llvm-project#118576

@svenvh
Copy link
Member

svenvh commented Dec 11, 2024

Thanks for reporting; this highlights a long-standing problem that doesn't have a trivial solution unfortunately. See e.g. the attempt reverted by #2508.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants