Skip to content

Commit 5fd5b8a

Browse files
authored
[OpenCL] Emit opencl.cxx.version metadata for C++ (#92140)
Currently there is no way to tell whether an IR module was generated using `-cl-std=cl3.0` or `-cl-std=clc++2021`, i.e., whether the origin was a OpenCL C or C++ for OpenCL source. Add new `opencl.cxx.version` named metadata when compiling C++. Keep the `opencl.ocl.version` metadata to convey the compatible OpenCL C version. Fixes #91912
1 parent bcb7c38 commit 5fd5b8a

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,17 +1399,25 @@ void CodeGenModule::Release() {
13991399
void CodeGenModule::EmitOpenCLMetadata() {
14001400
// SPIR v2.0 s2.13 - The OpenCL version used by the module is stored in the
14011401
// opencl.ocl.version named metadata node.
1402-
// C++ for OpenCL has a distinct mapping for versions compatibile with OpenCL.
1403-
auto Version = LangOpts.getOpenCLCompatibleVersion();
1404-
llvm::Metadata *OCLVerElts[] = {
1405-
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
1406-
Int32Ty, Version / 100)),
1407-
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
1408-
Int32Ty, (Version % 100) / 10))};
1409-
llvm::NamedMDNode *OCLVerMD =
1410-
TheModule.getOrInsertNamedMetadata("opencl.ocl.version");
1411-
llvm::LLVMContext &Ctx = TheModule.getContext();
1412-
OCLVerMD->addOperand(llvm::MDNode::get(Ctx, OCLVerElts));
1402+
// C++ for OpenCL has a distinct mapping for versions compatible with OpenCL.
1403+
auto CLVersion = LangOpts.getOpenCLCompatibleVersion();
1404+
1405+
auto EmitVersion = [this](StringRef MDName, int Version) {
1406+
llvm::Metadata *OCLVerElts[] = {
1407+
llvm::ConstantAsMetadata::get(
1408+
llvm::ConstantInt::get(Int32Ty, Version / 100)),
1409+
llvm::ConstantAsMetadata::get(
1410+
llvm::ConstantInt::get(Int32Ty, (Version % 100) / 10))};
1411+
llvm::NamedMDNode *OCLVerMD = TheModule.getOrInsertNamedMetadata(MDName);
1412+
llvm::LLVMContext &Ctx = TheModule.getContext();
1413+
OCLVerMD->addOperand(llvm::MDNode::get(Ctx, OCLVerElts));
1414+
};
1415+
1416+
EmitVersion("opencl.ocl.version", CLVersion);
1417+
if (LangOpts.OpenCLCPlusPlus) {
1418+
// In addition to the OpenCL compatible version, emit the C++ version.
1419+
EmitVersion("opencl.cxx.version", LangOpts.OpenCLCPlusPlusVersion);
1420+
}
14131421
}
14141422

14151423
void CodeGenModule::EmitBackendOptionsMetadata(
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %clang_cc1 %s -triple "spir64-unknown-unknown" -emit-llvm -o - -cl-std=CL2.0 | FileCheck %s --check-prefix=CHECK-NO-CXX
2+
3+
// RUN: %clang_cc1 %s -triple "spir64-unknown-unknown" -emit-llvm -o - -cl-std=clc++1.0 | FileCheck %s --check-prefix=CHECK-CXX100
4+
// RUN: %clang_cc1 %s -triple "spir64-unknown-unknown" -emit-llvm -o - -cl-std=clc++2021 | FileCheck %s --check-prefix=CHECK-CXX2021
5+
6+
// This test checks that opencl.cxx.version metadata is emitted accordingly.
7+
// It avoids any C++ features to enable checking that the metadata is not emitted in non-C++ mode.
8+
9+
kernel void foo() {}
10+
11+
// CHECK-NO-CXX-NOT: opencl.cxx.version
12+
13+
// CHECK-CXX100-DAG: !opencl.ocl.version = !{[[OCL:![0-9]+]]}
14+
// CHECK-CXX100-DAG: !opencl.cxx.version = !{[[CXX:![0-9]+]]}
15+
// CHECK-CXX100-DAG: [[OCL]] = !{i32 2, i32 0}
16+
// CHECK-CXX100-DAG: [[CXX]] = !{i32 1, i32 0}
17+
18+
// CHECK-CXX2021-DAG: !opencl.ocl.version = !{[[OCL:![0-9]+]]}
19+
// CHECK-CXX2021-DAG: !opencl.cxx.version = !{[[CXX:![0-9]+]]}
20+
// CHECK-CXX2021-DAG: [[OCL]] = !{i32 3, i32 0}
21+
// CHECK-CXX2021-DAG: [[CXX]] = !{i32 2021, i32 0}

0 commit comments

Comments
 (0)