Skip to content

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

@Calandracas606

Description

@Calandracas606

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions