Skip to content

[OpenCL] Emit opencl.cxx.version metadata for C++ #92140

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

Merged
merged 1 commit into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 19 additions & 11 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1394,17 +1394,25 @@ void CodeGenModule::Release() {
void CodeGenModule::EmitOpenCLMetadata() {
// SPIR v2.0 s2.13 - The OpenCL version used by the module is stored in the
// opencl.ocl.version named metadata node.
// C++ for OpenCL has a distinct mapping for versions compatibile with OpenCL.
auto Version = LangOpts.getOpenCLCompatibleVersion();
llvm::Metadata *OCLVerElts[] = {
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
Int32Ty, Version / 100)),
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
Int32Ty, (Version % 100) / 10))};
llvm::NamedMDNode *OCLVerMD =
TheModule.getOrInsertNamedMetadata("opencl.ocl.version");
llvm::LLVMContext &Ctx = TheModule.getContext();
OCLVerMD->addOperand(llvm::MDNode::get(Ctx, OCLVerElts));
// C++ for OpenCL has a distinct mapping for versions compatible with OpenCL.
auto CLVersion = LangOpts.getOpenCLCompatibleVersion();

auto EmitVersion = [this](StringRef MDName, int Version) {
llvm::Metadata *OCLVerElts[] = {
llvm::ConstantAsMetadata::get(
llvm::ConstantInt::get(Int32Ty, Version / 100)),
llvm::ConstantAsMetadata::get(
llvm::ConstantInt::get(Int32Ty, (Version % 100) / 10))};
llvm::NamedMDNode *OCLVerMD = TheModule.getOrInsertNamedMetadata(MDName);
llvm::LLVMContext &Ctx = TheModule.getContext();
OCLVerMD->addOperand(llvm::MDNode::get(Ctx, OCLVerElts));
};

EmitVersion("opencl.ocl.version", CLVersion);
if (LangOpts.OpenCLCPlusPlus) {
// In addition to the OpenCL compatible version, emit the C++ version.
EmitVersion("opencl.cxx.version", LangOpts.OpenCLCPlusPlusVersion);
}
}

void CodeGenModule::EmitBackendOptionsMetadata(
Expand Down
21 changes: 21 additions & 0 deletions clang/test/CodeGenOpenCLCXX/version.clcpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// RUN: %clang_cc1 %s -triple "spir64-unknown-unknown" -emit-llvm -o - -cl-std=CL2.0 | FileCheck %s --check-prefix=CHECK-NO-CXX

// RUN: %clang_cc1 %s -triple "spir64-unknown-unknown" -emit-llvm -o - -cl-std=clc++1.0 | FileCheck %s --check-prefix=CHECK-CXX100
// RUN: %clang_cc1 %s -triple "spir64-unknown-unknown" -emit-llvm -o - -cl-std=clc++2021 | FileCheck %s --check-prefix=CHECK-CXX2021

// This test checks that opencl.cxx.version metadata is emitted accordingly.
// It avoids any C++ features to enable checking that the metadata is not emitted in non-C++ mode.

kernel void foo() {}

// CHECK-NO-CXX-NOT: opencl.cxx.version

// CHECK-CXX100-DAG: !opencl.ocl.version = !{[[OCL:![0-9]+]]}
// CHECK-CXX100-DAG: !opencl.cxx.version = !{[[CXX:![0-9]+]]}
// CHECK-CXX100-DAG: [[OCL]] = !{i32 2, i32 0}
// CHECK-CXX100-DAG: [[CXX]] = !{i32 1, i32 0}

// CHECK-CXX2021-DAG: !opencl.ocl.version = !{[[OCL:![0-9]+]]}
// CHECK-CXX2021-DAG: !opencl.cxx.version = !{[[CXX:![0-9]+]]}
// CHECK-CXX2021-DAG: [[OCL]] = !{i32 3, i32 0}
// CHECK-CXX2021-DAG: [[CXX]] = !{i32 2021, i32 0}
Loading