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

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

Merged
merged 1 commit into from
Jul 3, 2024

Conversation

svenvh
Copy link
Member

@svenvh svenvh commented May 14, 2024

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

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
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen labels May 14, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented May 14, 2024

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-codegen

Author: Sven van Haastregt (svenvh)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/92140.diff

2 Files Affected:

  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+19-11)
  • (added) clang/test/CodeGenOpenCLCXX/version.clcpp (+21)
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}

@svenvh svenvh added the OpenCL label May 14, 2024
@haonanya
Copy link

haonanya commented Jul 3, 2024

Hi, @AnastasiaStulova, can you please take a look? Related to #91912. Thanks very much.

Copy link
Contributor

@AnastasiaStulova AnastasiaStulova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense! Thanks.

@svenvh svenvh merged commit 5fd5b8a into llvm:main Jul 3, 2024
8 checks passed
@svenvh svenvh deleted the cxxversion-metadata branch July 3, 2024 11:24
kirillpyasecky pushed a commit to kirillpyasecky/llvm-project that referenced this pull request Jul 3, 2024
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
kbluck pushed a commit to kbluck/llvm-project that referenced this pull request Jul 6, 2024
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen clang Clang issues not falling into any other category OpenCL
Projects
None yet
Development

Successfully merging this pull request may close these issues.

opencl.ocl.version can not reflect opencl cpp source
4 participants