let name = "nvvm";
let cppNamespace = "::mlir::NVVM";
let dependentDialects = ["LLVM::LLVMDialect"];
+ let hasOperationAttrVerify = 1;
let extraClassDeclaration = [{
/// Get the name of the attribute used to annotate external kernel
let name = "rocdl";
let cppNamespace = "::mlir::ROCDL";
let dependentDialects = ["LLVM::LLVMDialect"];
+ let hasOperationAttrVerify = 1;
let extraClassDeclaration = [{
/// Get the name of the attribute used to annotate external kernel
allowUnknownOperations();
}
+LogicalResult NVVMDialect::verifyOperationAttribute(Operation *op,
+ NamedAttribute attr) {
+ // Kernel function attribute should be attached to functions.
+ if (attr.first == NVVMDialect::getKernelFuncAttrName()) {
+ if (!isa<LLVM::LLVMFuncOp>(op)) {
+ return op->emitError() << "'" << NVVMDialect::getKernelFuncAttrName()
+ << "' attribute attached to unexpected op";
+ }
+ }
+ return success();
+}
+
#define GET_OP_CLASSES
#include "mlir/Dialect/LLVMIR/NVVMOps.cpp.inc"
allowUnknownOperations();
}
+LogicalResult ROCDLDialect::verifyOperationAttribute(Operation *op,
+ NamedAttribute attr) {
+ // Kernel function attribute should be attached to functions.
+ if (attr.first == ROCDLDialect::getKernelFuncAttrName()) {
+ if (!isa<LLVM::LLVMFuncOp>(op)) {
+ return op->emitError() << "'" << ROCDLDialect::getKernelFuncAttrName()
+ << "' attribute attached to unexpected op";
+ }
+ }
+ return success();
+}
+
#define GET_OP_CLASSES
#include "mlir/Dialect/LLVMIR/ROCDLOps.cpp.inc"
Operation *op, NamedAttribute attribute,
LLVM::ModuleTranslation &moduleTranslation) const {
if (attribute.first == NVVM::NVVMDialect::getKernelFuncAttrName()) {
- auto func = dyn_cast<LLVM::LLVMFuncOp>(op);
- if (!func)
- return failure();
-
+ auto func = cast<LLVM::LLVMFuncOp>(op);
llvm::LLVMContext &llvmContext = moduleTranslation.getLLVMContext();
llvm::Function *llvmFunc = moduleTranslation.lookupFunction(func.getName());
llvm::Metadata *llvmMetadata[] = {
Operation *op, NamedAttribute attribute,
LLVM::ModuleTranslation &moduleTranslation) const {
if (attribute.first == ROCDL::ROCDLDialect::getKernelFuncAttrName()) {
- auto func = dyn_cast<LLVM::LLVMFuncOp>(op);
- if (!func)
- return failure();
+ auto func = cast<LLVM::LLVMFuncOp>(op);
// For GPU kernels,
// 1. Insert AMDGPU_KERNEL calling convention.
-// RUN: mlir-opt %s | FileCheck %s
+// RUN: mlir-opt %s -split-input-file -verify-diagnostics | FileCheck %s
func @nvvm_special_regs() -> i32 {
// CHECK: nvvm.read.ptx.sreg.tid.x : i32
%0 = nvvm.mma.sync %a0, %a1, %b0, %b1, %c0, %c1, %c2, %c3, %c4, %c5, %c6, %c7 {alayout="row", blayout="col"} : (vector<2xf16>, vector<2xf16>, vector<2xf16>, vector<2xf16>, f32, f32, f32, f32, f32, f32, f32, f32) -> !llvm.struct<(f32, f32, f32, f32, f32, f32, f32, f32)>
llvm.return %0 : !llvm.struct<(f32, f32, f32, f32, f32, f32, f32, f32)>
}
+
+// -----
+
+// expected-error@below {{attribute attached to unexpected op}}
+func private @expected_llvm_func() attributes { nvvm.kernel }
-// RUN: mlir-opt %s | FileCheck %s
+// RUN: mlir-opt %s -split-input-file -verify-diagnostics | FileCheck %s
func @rocdl_special_regs() -> i32 {
// CHECK-LABEL: rocdl_special_regs
llvm.return
}
+// -----
+
+// expected-error@below {{attribute attached to unexpected op}}
+func private @expected_llvm_func() attributes { rocdl.kernel }