[mlir] add verifiers for NVVM and ROCDL kernel attributes
authorAlex Zinenko <zinenko@google.com>
Tue, 16 Feb 2021 17:05:47 +0000 (18:05 +0100)
committerAlex Zinenko <zinenko@google.com>
Tue, 16 Feb 2021 17:06:54 +0000 (18:06 +0100)
Make sure they can only be attached to LLVM functions as a result of converting
GPU functions to the LLVM Dialect.

mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
mlir/include/mlir/Dialect/LLVMIR/ROCDLOps.td
mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
mlir/lib/Dialect/LLVMIR/IR/ROCDLDialect.cpp
mlir/lib/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.cpp
mlir/lib/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.cpp
mlir/test/Dialect/LLVMIR/nvvm.mlir
mlir/test/Dialect/LLVMIR/rocdl.mlir

index de7fd01..203a0b2 100644 (file)
@@ -24,6 +24,7 @@ def NVVM_Dialect : Dialect {
   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
index cfb08ff..1b45e51 100644 (file)
@@ -24,6 +24,7 @@ def ROCDL_Dialect : Dialect {
   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
index 06e7378..3b6d239 100644 (file)
@@ -145,5 +145,17 @@ void NVVMDialect::initialize() {
   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"
index 1cdceaf..f54fcdb 100644 (file)
@@ -91,5 +91,17 @@ void ROCDLDialect::initialize() {
   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"
index fdc9add..a0eb87e 100644 (file)
@@ -47,10 +47,7 @@ LogicalResult mlir::NVVMDialectLLVMIRTranslationInterface::amendOperation(
     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[] = {
index 7b34f80..9288af1 100644 (file)
@@ -54,9 +54,7 @@ LogicalResult mlir::ROCDLDialectLLVMIRTranslationInterface::amendOperation(
     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.
index 545364d..1e3d6dc 100644 (file)
@@ -1,4 +1,4 @@
-// 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
@@ -68,3 +68,8 @@ func @nvvm_mma(%a0 : vector<2xf16>, %a1 : vector<2xf16>,
   %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 }
index 31a56be..e9a3a59 100644 (file)
@@ -1,4 +1,4 @@
-// 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
@@ -167,3 +167,7 @@ llvm.func @rocdl.mubuf(%rsrc : vector<4xi32>, %vindex : i32,
   llvm.return
 }
 
+// -----
+
+// expected-error@below {{attribute attached to unexpected op}}
+func private @expected_llvm_func() attributes { rocdl.kernel }