[mlir] Support llvm.readonly attribute on llvm pointers
authorGuray Ozen <guray.ozen@gmail.com>
Thu, 8 Dec 2022 16:59:22 +0000 (17:59 +0100)
committerGuray Ozen <guray.ozen@gmail.com>
Fri, 9 Dec 2022 09:36:59 +0000 (10:36 +0100)
The attribute is translated into LLVM's function attribute 'readonly'. The attribute can be only used for pointers.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D139641

mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
mlir/test/Target/LLVMIR/llvmir-invalid.mlir
mlir/test/Target/LLVMIR/llvmir.mlir

index 1177ee7..f8b798e 100644 (file)
@@ -37,6 +37,7 @@ def LLVM_Dialect : Dialect {
     static StringRef getDataLayoutAttrName() { return "llvm.data_layout"; }
     static StringRef getAlignAttrName() { return "llvm.align"; }
     static StringRef getNoAliasAttrName() { return "llvm.noalias"; }
+    static StringRef getReadonlyAttrName() { return "llvm.readonly"; }
     static StringRef getNoAliasScopesAttrName() { return "noalias_scopes"; }
     static StringRef getAliasScopesAttrName() { return "alias_scopes"; }
     static StringRef getLoopAttrName() { return "llvm.loop"; }
index cff547e..a4860e3 100644 (file)
@@ -2821,6 +2821,15 @@ LogicalResult LLVMDialect::verifyRegionResultAttribute(Operation *op,
                << "llvm.noalias attribute attached to non-pointer result";
       return success();
     }
+    if (name == LLVMDialect::getReadonlyAttrName()) {
+      if (!attrValue.isa<UnitAttr>())
+        return op->emitError() << "expected llvm.readonly result attribute to "
+                                  "be a unit attribute";
+      if (verifyValueType && !resTy.isa<LLVMPointerType>())
+        return op->emitError()
+               << "llvm.readonly attribute attached to non-pointer result";
+      return success();
+    }
     if (name == LLVMDialect::getNoUndefAttrName()) {
       if (!attrValue.isa<UnitAttr>())
         return op->emitError() << "expected llvm.noundef result attribute to "
index 9ea32c2..4a532ef 100644 (file)
@@ -924,6 +924,13 @@ LogicalResult ModuleTranslation::convertFunctionSignatures() {
               "llvm.noalias attribute attached to LLVM non-pointer argument");
         llvmArg.addAttr(llvm::Attribute::AttrKind::NoAlias);
       }
+      if (auto attr = function.getArgAttrOfType<UnitAttr>(
+              argIdx, LLVMDialect::getReadonlyAttrName())) {
+        if (!mlirArgTy.isa<LLVM::LLVMPointerType>())
+          return function.emitError(
+              "llvm.readonly attribute attached to LLVM non-pointer argument");
+        llvmArg.addAttr(llvm::Attribute::AttrKind::ReadOnly);
+      }
 
       if (auto attr = function.getArgAttrOfType<IntegerAttr>(
               argIdx, LLVMDialect::getAlignAttrName())) {
index 4627df8..e8571a9 100644 (file)
@@ -348,3 +348,10 @@ llvm.func @stepvector_intr_wrong_type() -> vector<7xf32> {
   %0 = llvm.intr.experimental.stepvector : vector<7xf32>
   llvm.return %0 : vector<7xf32>
 }
+
+// -----
+
+// expected-error @below{{llvm.readonly attribute attached to LLVM non-pointer argument}}
+llvm.func @wrong_readonly_attribute(%vec : f32 {llvm.readonly}) {
+  llvm.return
+}
index f973315..8a41b9d 100644 (file)
@@ -2022,3 +2022,7 @@ llvm.func @vararg_function(%arg0: i32, ...) {
 // CHECK: declare void @readnone_function() #[[ATTR:[0-9]+]]
 // CHECK: attributes #[[ATTR]] = { memory(none) }
 llvm.func @readnone_function() attributes {llvm.readnone}
+
+// -----
+// CHECK: declare void @readonly_function([[PTR:.+]] readonly)
+llvm.func @readonly_function(%arg0: !llvm.ptr<f32> {llvm.readonly})