-
Notifications
You must be signed in to change notification settings - Fork 11.1k
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
[OpenCL] Emit opencl.cxx.version metadata for C++ #92140
Conversation
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 llvm#91912
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: Sven van Haastregt (svenvh) ChangesCurrently there is no way to tell whether an IR module was generated using Add new Fixes #91912 Full diff: https://github.com/llvm/llvm-project/pull/92140.diff 2 Files Affected:
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 489c08a4d4819..028ae9c5915db 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -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(
diff --git a/clang/test/CodeGenOpenCLCXX/version.clcpp b/clang/test/CodeGenOpenCLCXX/version.clcpp
new file mode 100644
index 0000000000000..2f2aa022afab2
--- /dev/null
+++ b/clang/test/CodeGenOpenCLCXX/version.clcpp
@@ -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}
|
Hi, @AnastasiaStulova, can you please take a look? Related to #91912. Thanks very much. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense! Thanks.
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 llvm#91912
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 llvm#91912
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 theopencl.ocl.version
metadata to convey the compatible OpenCL C version.Fixes #91912