https://github.com/Men-cotton created 
https://github.com/llvm/llvm-project/pull/199530

Add a CIR attribute that carries OpenCL kernel argument metadata in source 
argument order. Verify that each metadata field has the expected element type 
and that all present arrays describe the same number of arguments.

>From 9c9c9aaa48b05a0bf833bb8e2111a8e0163385a0 Mon Sep 17 00:00:00 2001
From: mencotton <[email protected]>
Date: Sun, 24 May 2026 00:49:55 +0900
Subject: [PATCH] [CIR][OpenCL] Add kernel argument metadata attribute

Add a CIR attribute that carries OpenCL kernel argument metadata in source 
argument order. Verify that each metadata field has the expected element type 
and that all present arrays describe the same number of arguments.
---
 .../include/clang/CIR/Dialect/IR/CIRAttrs.td  |  1 +
 .../clang/CIR/Dialect/IR/CIRDialect.td        |  1 +
 .../clang/CIR/Dialect/IR/CIROpenCLAttrs.td    | 46 +++++++++++
 clang/lib/CIR/Dialect/IR/CIROpenCLAttrs.cpp   | 60 ++++++++++++++
 clang/lib/CIR/Dialect/IR/CMakeLists.txt       |  1 +
 .../IR/invalid-opencl-kernel-arg-metadata.cir | 78 +++++++++++++++++++
 .../CIR/IR/opencl-kernel-arg-metadata.cir     | 27 +++++++
 7 files changed, 214 insertions(+)
 create mode 100644 clang/include/clang/CIR/Dialect/IR/CIROpenCLAttrs.td
 create mode 100644 clang/lib/CIR/Dialect/IR/CIROpenCLAttrs.cpp
 create mode 100644 clang/test/CIR/IR/invalid-opencl-kernel-arg-metadata.cir
 create mode 100644 clang/test/CIR/IR/opencl-kernel-arg-metadata.cir

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 4032d8219fff3..19a0c25c8b10e 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -1687,6 +1687,7 @@ def CIR_AnnotationArrayAttr
     : TypedArrayAttrBase<CIR_AnnotationAttr,
                          "array of cir.annotation attributes">;
 
+include "clang/CIR/Dialect/IR/CIROpenCLAttrs.td"
 include "clang/CIR/Dialect/IR/CIRCUDAAttrs.td"
 
 #endif // CLANG_CIR_DIALECT_IR_CIRATTRS_TD
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td 
b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
index aaa7b48262c80..c20af04f97a1a 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
@@ -82,6 +82,7 @@ def CIR_Dialect : Dialect {
 
     static llvm::StringRef getAMDGPUCodeObjectVersionAttrName() { return 
"cir.amdhsa_code_object_version"; }
     static llvm::StringRef getAMDGPUPrintfKindAttrName() { return 
"cir.amdgpu_printf_kind"; }
+    static llvm::StringRef getOpenCLKernelArgMetadataAttrName() { return 
"cir.cl.kernel_arg_metadata"; }
 
     void registerAttributes();
     void registerTypes();
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROpenCLAttrs.td 
b/clang/include/clang/CIR/Dialect/IR/CIROpenCLAttrs.td
new file mode 100644
index 0000000000000..c0ec9c7f28f85
--- /dev/null
+++ b/clang/include/clang/CIR/Dialect/IR/CIROpenCLAttrs.td
@@ -0,0 +1,46 @@
+//===- CIROpenCLAttrs.td - CIR dialect attrs for OpenCL ----*- tablegen 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the CIR dialect attributes for OpenCL.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CIR_DIALECT_IR_CIROPENCLATTRS_TD
+#define CLANG_CIR_DIALECT_IR_CIROPENCLATTRS_TD
+
+//===----------------------------------------------------------------------===//
+// OpenCLKernelArgMetadataAttr
+//===----------------------------------------------------------------------===//
+
+def CIR_OpenCLKernelArgMetadataAttr
+    : CIR_Attr<"OpenCLKernelArgMetadata", "cl.kernel_arg_metadata"> {
+  let summary = "OpenCL kernel argument metadata";
+  let description = [{
+    Stores the OpenCL kernel argument metadata emitted to LLVM IR as
+    `kernel_arg_*` metadata.
+
+    All parameters are arrays containing the argument information in source
+    order. The `name` field is optional and is emitted only when requested by
+    `-cl-kernel-arg-info`.
+  }];
+
+  let parameters = (ins
+    "::mlir::ArrayAttr":$addr_space,
+    "::mlir::ArrayAttr":$access_qual,
+    "::mlir::ArrayAttr":$type,
+    "::mlir::ArrayAttr":$base_type,
+    "::mlir::ArrayAttr":$type_qual,
+    OptionalParameter<"::mlir::ArrayAttr">:$name
+  );
+
+  let assemblyFormat = "`<` struct(params) `>`";
+  let genVerifyDecl = 1;
+  let canHaveIllegalCXXABIType = 0;
+}
+
+#endif // CLANG_CIR_DIALECT_IR_CIROPENCLATTRS_TD
diff --git a/clang/lib/CIR/Dialect/IR/CIROpenCLAttrs.cpp 
b/clang/lib/CIR/Dialect/IR/CIROpenCLAttrs.cpp
new file mode 100644
index 0000000000000..57692cd4783b8
--- /dev/null
+++ b/clang/lib/CIR/Dialect/IR/CIROpenCLAttrs.cpp
@@ -0,0 +1,60 @@
+//===- CIROpenCLAttrs.cpp - OpenCL specific attributes in CIR 
-------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the OpenCL-specific attrs in the CIR dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CIR/Dialect/IR/CIRAttrs.h"
+
+#include "mlir/IR/Attributes.h"
+#include "mlir/IR/Diagnostics.h"
+#include "llvm/ADT/STLExtras.h"
+
+using namespace mlir;
+using namespace cir;
+
+//===----------------------------------------------------------------------===//
+// OpenCLKernelArgMetadataAttr definitions
+//===----------------------------------------------------------------------===//
+
+LogicalResult OpenCLKernelArgMetadataAttr::verify(
+    function_ref<InFlightDiagnostic()> emitError, ArrayAttr addrSpaces,
+    ArrayAttr accessQuals, ArrayAttr types, ArrayAttr baseTypes,
+    ArrayAttr typeQuals, ArrayAttr argNames) {
+  auto isIntArray = [](ArrayAttr attr) {
+    return llvm::all_of(
+        attr, [](Attribute elem) { return mlir::isa<IntegerAttr>(elem); });
+  };
+  auto isStrArray = [](ArrayAttr attr) {
+    return llvm::all_of(
+        attr, [](Attribute elem) { return mlir::isa<StringAttr>(elem); });
+  };
+
+  if (!isIntArray(addrSpaces))
+    return emitError() << "addr_space must be an integer array";
+  if (!isStrArray(accessQuals))
+    return emitError() << "access_qual must be a string array";
+  if (!isStrArray(types))
+    return emitError() << "type must be a string array";
+  if (!isStrArray(baseTypes))
+    return emitError() << "base_type must be a string array";
+  if (!isStrArray(typeQuals))
+    return emitError() << "type_qual must be a string array";
+  if (argNames && !isStrArray(argNames))
+    return emitError() << "name must be a string array";
+
+  if (!llvm::all_of(ArrayRef<ArrayAttr>{addrSpaces, accessQuals, types,
+                                        baseTypes, typeQuals, argNames},
+                    [&](ArrayAttr attr) {
+                      return !attr || attr.size() == addrSpaces.size();
+                    }))
+    return emitError() << "all arrays must have the same number of elements";
+
+  return success();
+}
diff --git a/clang/lib/CIR/Dialect/IR/CMakeLists.txt 
b/clang/lib/CIR/Dialect/IR/CMakeLists.txt
index 98575941035f2..c8205ebeabf6c 100644
--- a/clang/lib/CIR/Dialect/IR/CMakeLists.txt
+++ b/clang/lib/CIR/Dialect/IR/CMakeLists.txt
@@ -4,6 +4,7 @@ add_clang_library(MLIRCIR
   CIRMemorySlot.cpp
   CIRTypes.cpp
   CIRDataLayout.cpp
+  CIROpenCLAttrs.cpp
 
   DEPENDS
   MLIRCIROpsIncGen
diff --git a/clang/test/CIR/IR/invalid-opencl-kernel-arg-metadata.cir 
b/clang/test/CIR/IR/invalid-opencl-kernel-arg-metadata.cir
new file mode 100644
index 0000000000000..23c62c09100f5
--- /dev/null
+++ b/clang/test/CIR/IR/invalid-opencl-kernel-arg-metadata.cir
@@ -0,0 +1,78 @@
+// RUN: cir-opt %s -verify-diagnostics -split-input-file
+
+// expected-error @below {{addr_space must be an integer array}}
+#attr = #cir.cl.kernel_arg_metadata<
+  addr_space = ["none"],
+  access_qual = ["none"],
+  type = ["uint*"],
+  base_type = ["uint*"],
+  type_qual = [""]
+>
+
+// -----
+
+// expected-error @below {{access_qual must be a string array}}
+#attr = #cir.cl.kernel_arg_metadata<
+  addr_space = [0 : i32],
+  access_qual = [42 : i32],
+  type = ["uint*"],
+  base_type = ["uint*"],
+  type_qual = [""]
+>
+
+// -----
+
+// expected-error @below {{type must be a string array}}
+#attr = #cir.cl.kernel_arg_metadata<
+  addr_space = [0 : i32],
+  access_qual = ["none"],
+  type = [42 : i32],
+  base_type = ["uint*"],
+  type_qual = [""]
+>
+
+// -----
+
+// expected-error @below {{base_type must be a string array}}
+#attr = #cir.cl.kernel_arg_metadata<
+  addr_space = [0 : i32],
+  access_qual = ["none"],
+  type = ["uint*"],
+  base_type = [42 : i32],
+  type_qual = [""]
+>
+
+// -----
+
+// expected-error @below {{type_qual must be a string array}}
+#attr = #cir.cl.kernel_arg_metadata<
+  addr_space = [0 : i32],
+  access_qual = ["none"],
+  type = ["uint*"],
+  base_type = ["uint*"],
+  type_qual = [42 : i32]
+>
+
+// -----
+
+// expected-error @below {{name must be a string array}}
+#attr = #cir.cl.kernel_arg_metadata<
+  addr_space = [0 : i32],
+  access_qual = ["none"],
+  type = ["uint*"],
+  base_type = ["uint*"],
+  type_qual = [""],
+  name = [33 : i32]
+>
+
+// -----
+
+// expected-error @below {{all arrays must have the same number of elements}}
+#attr = #cir.cl.kernel_arg_metadata<
+  addr_space = [0 : i32],
+  access_qual = ["none"],
+  type = ["uint*", "myunsignedint*"],
+  base_type = ["uint*", "uint*"],
+  type_qual = [""],
+  name = ["foo"]
+>
diff --git a/clang/test/CIR/IR/opencl-kernel-arg-metadata.cir 
b/clang/test/CIR/IR/opencl-kernel-arg-metadata.cir
new file mode 100644
index 0000000000000..89b3f0722d6f6
--- /dev/null
+++ b/clang/test/CIR/IR/opencl-kernel-arg-metadata.cir
@@ -0,0 +1,27 @@
+// RUN: cir-opt %s --verify-roundtrip | FileCheck %s
+
+module {
+  cir.func @without_names() attributes {cir.cl.kernel_arg_metadata = 
#cir.cl.kernel_arg_metadata<addr_space = [1 : i32, 0 : i32], access_qual = 
["none", "none"], type = ["uint*", "int"], base_type = ["uint*", "int"], 
type_qual = ["restrict", ""]>} {
+    cir.return
+  }
+
+  cir.func @with_names() attributes {cir.cl.kernel_arg_metadata = 
#cir.cl.kernel_arg_metadata<addr_space = [1 : i32, 0 : i32], access_qual = 
["none", "none"], type = ["uint*", "int"], base_type = ["uint*", "int"], 
type_qual = ["restrict", ""], name = ["data", "count"]>} {
+    cir.return
+  }
+}
+
+// CHECK-LABEL: cir.func @without_names()
+// CHECK-SAME: cir.cl.kernel_arg_metadata = #cir.cl.kernel_arg_metadata
+// CHECK-SAME: addr_space = [1 : i32, 0 : i32]
+// CHECK-SAME: type = ["uint*", "int"]
+// CHECK-SAME: base_type = ["uint*", "int"]
+// CHECK-SAME: type_qual = ["restrict", ""]
+// CHECK-NOT: name =
+
+// CHECK-LABEL: cir.func @with_names()
+// CHECK-SAME: cir.cl.kernel_arg_metadata = #cir.cl.kernel_arg_metadata
+// CHECK-SAME: addr_space = [1 : i32, 0 : i32]
+// CHECK-SAME: type = ["uint*", "int"]
+// CHECK-SAME: base_type = ["uint*", "int"]
+// CHECK-SAME: type_qual = ["restrict", ""]
+// CHECK-SAME: name = ["data", "count"]

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to