From 359c064da762824fa8cfffca645e8996ddb85d53 Mon Sep 17 00:00:00 2001 From: Guray Ozen Date: Thu, 8 Dec 2022 17:59:22 +0100 Subject: [PATCH] [mlir] Support llvm.readonly attribute on llvm pointers 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 | 1 + mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 9 +++++++++ mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 7 +++++++ mlir/test/Target/LLVMIR/llvmir-invalid.mlir | 7 +++++++ mlir/test/Target/LLVMIR/llvmir.mlir | 4 ++++ 5 files changed, 28 insertions(+) diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td index 1177ee7..f8b798e 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td @@ -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"; } diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp index cff547e..a4860e3 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -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()) + return op->emitError() << "expected llvm.readonly result attribute to " + "be a unit attribute"; + if (verifyValueType && !resTy.isa()) + return op->emitError() + << "llvm.readonly attribute attached to non-pointer result"; + return success(); + } if (name == LLVMDialect::getNoUndefAttrName()) { if (!attrValue.isa()) return op->emitError() << "expected llvm.noundef result attribute to " diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index 9ea32c2..4a532ef 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -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( + argIdx, LLVMDialect::getReadonlyAttrName())) { + if (!mlirArgTy.isa()) + return function.emitError( + "llvm.readonly attribute attached to LLVM non-pointer argument"); + llvmArg.addAttr(llvm::Attribute::AttrKind::ReadOnly); + } if (auto attr = function.getArgAttrOfType( argIdx, LLVMDialect::getAlignAttrName())) { diff --git a/mlir/test/Target/LLVMIR/llvmir-invalid.mlir b/mlir/test/Target/LLVMIR/llvmir-invalid.mlir index 4627df8..e8571a9 100644 --- a/mlir/test/Target/LLVMIR/llvmir-invalid.mlir +++ b/mlir/test/Target/LLVMIR/llvmir-invalid.mlir @@ -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 +} diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir index f973315..8a41b9d 100644 --- a/mlir/test/Target/LLVMIR/llvmir.mlir +++ b/mlir/test/Target/LLVMIR/llvmir.mlir @@ -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 {llvm.readonly}) -- 2.7.4