[Mlir-commits] [mlir] 851a897 - [mlir][llvm] Purge struct_attr
Christian Ulmann
llvmlistbot at llvm.org
Thu Feb 9 00:42:32 PST 2023
Author: Christian Ulmann
Date: 2023-02-09T09:41:43+01:00
New Revision: 851a89715cadf411bd66a7cbb9d7567580f08f4c
URL: https://github.com/llvm/llvm-project/commit/851a89715cadf411bd66a7cbb9d7567580f08f4c
DIFF: https://github.com/llvm/llvm-project/commit/851a89715cadf411bd66a7cbb9d7567580f08f4c.diff
LOG: [mlir][llvm] Purge struct_attr
This commit removes the `llvm.struct_attr` which was used to bundle
result attributes that were previously attached to multiple results.
This extension isn't part of LLVM as result attribute semantics cannot
be supported on a struct field granularity.
Furthermore, many usages promoted result attributes to argument
attributes but this does not necessary preserve the semantics.
Reviewed By: gysit
Differential Revision: https://reviews.llvm.org/D143473
Added:
Modified:
mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-callers.mlir
mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-functions.mlir
mlir/test/Dialect/LLVMIR/invalid.mlir
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
index f0b735cf9e48f..4fd758639ba15 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
@@ -39,7 +39,6 @@ def LLVM_Dialect : Dialect {
static StringRef getAliasScopesAttrName() { return "alias_scopes"; }
static StringRef getLoopAttrName() { return "llvm.loop"; }
static StringRef getAccessGroupsAttrName() { return "access_groups"; }
- static StringRef getStructAttrsAttrName() { return "llvm.struct_attrs"; }
static StringRef getTBAAAttrName() { return "llvm.tbaa"; }
/// Names of llvm parameter attributes.
@@ -72,10 +71,6 @@ def LLVM_Dialect : Dialect {
/// effect when lowering to the LLVMDialect.
static StringRef getReadnoneAttrName() { return "llvm.readnone"; }
- /// Verifies if the attribute is a well-formed value for "llvm.struct_attrs"
- static LogicalResult verifyStructAttr(
- Operation *op, Attribute attr, Type annotatedType);
-
/// Verifies if the given string is a well-formed data layout descriptor.
/// Uses `reportError` to report errors.
static LogicalResult verifyDataLayoutString(
diff --git a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
index 6ff52566dee3f..f70cb469f3f38 100644
--- a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
+++ b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
@@ -78,54 +78,26 @@ static void filterFuncAttributes(func::FuncOp func, bool filterArgAndResAttrs,
}
}
-/// Helper function for wrapping all attributes into a single DictionaryAttr
-static auto wrapAsStructAttrs(OpBuilder &b, ArrayAttr attrs) {
- return DictionaryAttr::get(
- b.getContext(),
- b.getNamedAttr(LLVM::LLVMDialect::getStructAttrsAttrName(), attrs));
-}
+/// Adds a an empty set of argument attributes for the newly added argument in
+/// front of the existing ones.
+static void prependEmptyArgAttr(OpBuilder &builder,
+ SmallVectorImpl<NamedAttribute> &newFuncAttrs,
+ func::FuncOp func) {
+ auto argAttrs = func.getArgAttrs();
+ // Nothing to do when there were no arg attrs beforehand.
+ if (!argAttrs)
+ return;
-/// Combines all result attributes into a single DictionaryAttr
-/// and prepends to argument attrs.
-/// This is intended to be used to format the attributes for a C wrapper
-/// function when the result(s) is converted to the first function argument
-/// (in the multiple return case, all returns get wrapped into a single
-/// argument). The total number of argument attributes should be equal to
-/// (number of function arguments) + 1.
-static void
-prependResAttrsToArgAttrs(OpBuilder &builder,
- SmallVectorImpl<NamedAttribute> &attributes,
- func::FuncOp func) {
size_t numArguments = func.getNumArguments();
- auto allAttrs = SmallVector<Attribute>(
- numArguments + 1, DictionaryAttr::get(builder.getContext()));
- NamedAttribute *argAttrs = nullptr;
- for (auto *it = attributes.begin(); it != attributes.end();) {
- if (it->getName() == func.getArgAttrsAttrName()) {
- auto arrayAttrs = it->getValue().cast<ArrayAttr>();
- assert(arrayAttrs.size() == numArguments &&
- "Number of arg attrs and args should match");
- std::copy(arrayAttrs.begin(), arrayAttrs.end(), allAttrs.begin() + 1);
- argAttrs = it;
- } else if (it->getName() == func.getResAttrsAttrName()) {
- auto arrayAttrs = it->getValue().cast<ArrayAttr>();
- assert(!arrayAttrs.empty() && "expected array to be non-empty");
- allAttrs[0] = (arrayAttrs.size() == 1)
- ? arrayAttrs[0]
- : wrapAsStructAttrs(builder, arrayAttrs);
- it = attributes.erase(it);
- continue;
- }
- it++;
- }
-
- auto newArgAttrs = builder.getNamedAttr(func.getArgAttrsAttrName(),
- builder.getArrayAttr(allAttrs));
- if (!argAttrs) {
- attributes.emplace_back(newArgAttrs);
- return;
- }
- *argAttrs = newArgAttrs;
+ SmallVector<Attribute> newArgAttrs;
+ newArgAttrs.reserve(numArguments + 1);
+ // Insert empty dictionary for the new argument.
+ newArgAttrs.push_back(builder.getDictionaryAttr({}));
+
+ llvm::append_range(newArgAttrs, *argAttrs);
+ auto newNamedAttr = builder.getNamedAttr(func.getArgAttrsAttrName(),
+ builder.getArrayAttr(newArgAttrs));
+ newFuncAttrs.push_back(newNamedAttr);
}
/// Creates an auxiliary function with pointer-to-memref-descriptor-struct
@@ -141,12 +113,16 @@ static void wrapForExternalCallers(OpBuilder &rewriter, Location loc,
func::FuncOp funcOp,
LLVM::LLVMFuncOp newFuncOp) {
auto type = funcOp.getFunctionType();
- SmallVector<NamedAttribute, 4> attributes;
- filterFuncAttributes(funcOp, /*filterArgAndResAttrs=*/false, attributes);
auto [wrapperFuncType, resultIsNowArg] =
typeConverter.convertFunctionTypeCWrapper(type);
+
+ SmallVector<NamedAttribute, 4> attributes;
+ // Only modify the argument and result attributes when the result is now an
+ // argument.
if (resultIsNowArg)
- prependResAttrsToArgAttrs(rewriter, attributes, funcOp);
+ prependEmptyArgAttr(rewriter, attributes, funcOp);
+ filterFuncAttributes(funcOp, /*filterArgAndResAttrs=*/resultIsNowArg,
+ attributes);
auto wrapperFuncOp = rewriter.create<LLVM::LLVMFuncOp>(
loc, llvm::formatv("_mlir_ciface_{0}", funcOp.getName()).str(),
wrapperFuncType, LLVM::Linkage::External, /*dsoLocal*/ false,
@@ -207,10 +183,13 @@ static void wrapExternalFunction(OpBuilder &builder, Location loc,
assert(wrapperType && "unexpected type conversion failure");
SmallVector<NamedAttribute, 4> attributes;
- filterFuncAttributes(funcOp, /*filterArgAndResAttrs=*/false, attributes);
-
+ // Only modify the argument and result attributes when the result is now an
+ // argument.
if (resultIsNowArg)
- prependResAttrsToArgAttrs(builder, attributes, funcOp);
+ prependEmptyArgAttr(builder, attributes, funcOp);
+ filterFuncAttributes(funcOp, /*filterArgAndResAttrs=*/resultIsNowArg,
+ attributes);
+
// Create the auxiliary function.
auto wrapperFunc = builder.create<LLVM::LLVMFuncOp>(
loc, llvm::formatv("_mlir_ciface_{0}", funcOp.getName()).str(),
@@ -312,8 +291,7 @@ struct FuncOpConversionBase : public ConvertOpToLLVMPattern<func::FuncOp> {
auto newResAttrDicts =
(funcOp.getNumResults() == 1)
? resAttrDicts
- : rewriter.getArrayAttr(
- {wrapAsStructAttrs(rewriter, resAttrDicts)});
+ : rewriter.getArrayAttr(rewriter.getDictionaryAttr({}));
attributes.push_back(
rewriter.getNamedAttr(funcOp.getResAttrsAttrName(), newResAttrDicts));
}
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 8eb861c477cb8..79e39e18cbc0e 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -3018,12 +3018,6 @@ LogicalResult LLVMDialect::verifyOperationAttribute(Operation *op,
}
}
- if (attr.getName() == LLVMDialect::getStructAttrsAttrName()) {
- return op->emitOpError()
- << "'" << LLVM::LLVMDialect::getStructAttrsAttrName()
- << "' is permitted only in argument or result attributes";
- }
-
// If the data layout attribute is present, it must use the LLVM data layout
// syntax. Try parsing it and report errors in case of failure. Users of this
// attribute may assume it is well-formed and can pass it to the (asserting)
@@ -3040,46 +3034,6 @@ LogicalResult LLVMDialect::verifyOperationAttribute(Operation *op,
<< "' to be a string attributes";
}
-LogicalResult LLVMDialect::verifyStructAttr(Operation *op, Attribute attr,
- Type annotatedType) {
- auto structType = annotatedType.dyn_cast<LLVMStructType>();
- if (!structType) {
- const auto emitIncorrectAnnotatedType = [&op]() {
- return op->emitError()
- << "expected '" << LLVMDialect::getStructAttrsAttrName()
- << "' to annotate '!llvm.struct' or '!llvm.ptr<struct<...>>'";
- };
- const auto ptrType = annotatedType.dyn_cast<LLVMPointerType>();
- if (!ptrType)
- return emitIncorrectAnnotatedType();
- structType = ptrType.getElementType().dyn_cast<LLVMStructType>();
- if (!structType)
- return emitIncorrectAnnotatedType();
- }
-
- const auto arrAttrs = attr.dyn_cast<ArrayAttr>();
- if (!arrAttrs)
- return op->emitError() << "expected '"
- << LLVMDialect::getStructAttrsAttrName()
- << "' to be an array attribute";
-
- if (structType.getBody().size() != arrAttrs.size())
- return op->emitError()
- << "size of '" << LLVMDialect::getStructAttrsAttrName()
- << "' must match the size of the annotated '!llvm.struct'";
- return success();
-}
-
-static LogicalResult verifyFuncOpInterfaceStructAttr(Operation *op,
- Attribute attr,
- Type annotatedType) {
- if (isa<FunctionOpInterface>(op))
- return LLVMDialect::verifyStructAttr(op, attr, annotatedType);
- return op->emitError() << "expected '"
- << LLVMDialect::getStructAttrsAttrName()
- << "' to be used on function-like operations";
-}
-
LogicalResult LLVMDialect::verifyParameterAttribute(Operation *op,
Type paramType,
NamedAttribute paramAttr) {
@@ -3131,10 +3085,6 @@ LogicalResult LLVMDialect::verifyParameterAttribute(Operation *op,
return success();
};
- // Note: The struct parameter attributes are not lowered to LLVM IR.
- if (name == LLVMDialect::getStructAttrsAttrName())
- return verifyFuncOpInterfaceStructAttr(op, paramAttr.getValue(), paramType);
-
// Check a unit attribute that is attached to a pointer value.
if (name == LLVMDialect::getNoAliasAttrName() ||
name == LLVMDialect::getReadonlyAttrName() ||
diff --git a/mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-callers.mlir b/mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-callers.mlir
index 8b9360a099001..826ca9540ae56 100644
--- a/mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-callers.mlir
+++ b/mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-callers.mlir
@@ -2,7 +2,7 @@
// CHECK: llvm.func @res_attrs_with_memref_return() -> (!llvm.struct{{.*}} {test.returnOne})
// CHECK-LABEL: llvm.func @_mlir_ciface_res_attrs_with_memref_return
-// CHECK: %{{.*}}: !llvm.ptr{{.*}} {test.returnOne}
+// CHECK-NOT: test.returnOne
func.func @res_attrs_with_memref_return() -> (memref<f32> {test.returnOne}) {
%0 = memref.alloc() : memref<f32>
return %0 : memref<f32>
@@ -10,24 +10,30 @@ func.func @res_attrs_with_memref_return() -> (memref<f32> {test.returnOne}) {
// CHECK: llvm.func @res_attrs_with_value_return() -> (f32 {test.returnOne = 1 : i64})
// CHECK-LABEL: llvm.func @_mlir_ciface_res_attrs_with_value_return
-// CHECK: -> (f32 {test.returnOne = 1 : i64})
+// CHECK-SAME: -> (f32 {test.returnOne = 1 : i64})
func.func @res_attrs_with_value_return() -> (f32 {test.returnOne = 1}) {
%0 = arith.constant 1.00 : f32
return %0 : f32
}
-// CHECK: llvm.func @multiple_return() -> (!llvm.struct<{{.*}}> {llvm.struct_attrs = [{test.returnOne = 1 : i64}, {test.returnThree = 3 : i64, test.returnTwo = 2 : i64}]})
+// CHECK: llvm.func @multiple_return() -> !llvm.struct<{{.*}}>
// CHECK-LABEL: llvm.func @_mlir_ciface_multiple_return
-// CHECK: (%{{.*}}: !llvm.ptr<{{.*}}> {llvm.struct_attrs = [{test.returnOne = 1 : i64}, {test.returnThree = 3 : i64, test.returnTwo = 2 : i64}]})
+// CHECK-SAME: !llvm.ptr
+// CHECK-NOT: test.returnOne
+// CHECK-NOT: test.returnTwo
+// CHECK-NOT: test.returnThree
func.func @multiple_return() -> (memref<f32> {test.returnOne = 1}, f32 {test.returnTwo = 2, test.returnThree = 3}) {
%0 = memref.alloc() : memref<f32>
%1 = arith.constant 1.00 : f32
return %0, %1 : memref<f32>, f32
}
-// CHECK: llvm.func @multiple_return_missing_res_attr() -> (!llvm.struct<{{.*}}> {llvm.struct_attrs = [{test.returnOne = 1 : i64}, {}, {test.returnThree = 3 : i64, test.returnTwo = 2 : i64}]})
+// CHECK: llvm.func @multiple_return_missing_res_attr() -> !llvm.struct<{{.*}}>
// CHECK-LABEL: llvm.func @_mlir_ciface_multiple_return_missing_res_attr
-// CHECK: (%{{.*}}: !llvm.ptr<{{.*}}> {llvm.struct_attrs = [{test.returnOne = 1 : i64}, {}, {test.returnThree = 3 : i64, test.returnTwo = 2 : i64}]})
+// CHECK-SAME: !llvm.ptr
+// CHECK-NOT: test.returnOne
+// CHECK-NOT: test.returnTwo
+// CHECK-NOT: test.returnThree
func.func @multiple_return_missing_res_attr() -> (memref<f32> {test.returnOne = 1}, i64, f32 {test.returnTwo = 2, test.returnThree = 3}) {
%0 = memref.alloc() : memref<f32>
%1 = arith.constant 2 : i64
@@ -37,7 +43,9 @@ func.func @multiple_return_missing_res_attr() -> (memref<f32> {test.returnOne =
// CHECK: llvm.func @one_arg_attr_no_res_attrs_with_memref_return({{.*}}) -> !llvm.struct{{.*}}
// CHECK-LABEL: llvm.func @_mlir_ciface_one_arg_attr_no_res_attrs_with_memref_return
-// CHECK: %{{.*}}: !llvm.ptr<{{.*}}>, %{{.*}}: !llvm.ptr<{{.*}}> {test.argOne = 1 : i64}
+// CHECK-SAME: !llvm.ptr
+// CHECK-SAME: !llvm.ptr
+// CHECK-SAME: {test.argOne = 1 : i64})
func.func @one_arg_attr_no_res_attrs_with_memref_return(%arg0: memref<f32> {test.argOne = 1}) -> memref<f32> {
%0 = memref.alloc() : memref<f32>
return %0 : memref<f32>
@@ -45,7 +53,10 @@ func.func @one_arg_attr_no_res_attrs_with_memref_return(%arg0: memref<f32> {test
// CHECK: llvm.func @one_arg_attr_one_res_attr_with_memref_return({{.*}}) -> (!llvm.struct<{{.*}}> {test.returnOne = 1 : i64})
// CHECK-LABEL: llvm.func @_mlir_ciface_one_arg_attr_one_res_attr_with_memref_return
-// CHECK: (%{{.*}}: !llvm.ptr<{{.*}}> {test.returnOne = 1 : i64}, %{{.*}}: !llvm.ptr<{{.*}}> {test.argOne = 1 : i64}
+// CHECK-SAME: !llvm.ptr
+// CHECK-NOT: test.returnOne
+// CHECK-SAME: !llvm.ptr
+// CHECK-SAME: {test.argOne = 1 : i64})
func.func @one_arg_attr_one_res_attr_with_memref_return(%arg0: memref<f32> {test.argOne = 1}) -> (memref<f32> {test.returnOne = 1}) {
%0 = memref.alloc() : memref<f32>
return %0 : memref<f32>
@@ -53,15 +64,23 @@ func.func @one_arg_attr_one_res_attr_with_memref_return(%arg0: memref<f32> {test
// CHECK: llvm.func @one_arg_attr_one_res_attr_with_value_return({{.*}}) -> (f32 {test.returnOne = 1 : i64})
// CHECK-LABEL: llvm.func @_mlir_ciface_one_arg_attr_one_res_attr_with_value_return
-// CHECK: (%{{.*}}: !llvm.ptr<{{.*}}> {test.argOne = 1 : i64}) -> (f32 {test.returnOne = 1 : i64})
+// CHECK-SAME: !llvm.ptr
+// CHECK-SAME: {test.argOne = 1 : i64})
+// CHECK-SAME: -> (f32 {test.returnOne = 1 : i64})
func.func @one_arg_attr_one_res_attr_with_value_return(%arg0: memref<f32> {test.argOne = 1}) -> (f32 {test.returnOne = 1}) {
%0 = arith.constant 1.00 : f32
return %0 : f32
}
-// CHECK: llvm.func @multiple_arg_attr_multiple_res_attr({{.*}}) -> (!llvm.struct<{{.*}}> {llvm.struct_attrs = [{}, {test.returnOne = 1 : i64}, {test.returnTwo = 2 : i64}]})
+// CHECK: llvm.func @multiple_arg_attr_multiple_res_attr({{.*}}) -> !llvm.struct<{{.*}}>
// CHECK-LABEL: llvm.func @_mlir_ciface_multiple_arg_attr_multiple_res_attr
-// CHECK: (%{{.*}}: !llvm.ptr<{{.*}}> {llvm.struct_attrs = [{}, {test.returnOne = 1 : i64}, {test.returnTwo = 2 : i64}]}, %{{.*}}: !llvm.ptr<{{.*}}> {test.argZero = 0 : i64}, %{{.*}}: f32, %{{.*}}: i32 {test.argTwo = 2 : i64}
+// CHECK-SAME: !llvm.ptr
+// CHECK-NOT: test.returnOne
+// CHECK-NOT: test.returnTwo
+// CHECK-SAME: !llvm.ptr
+// CHECK-SAME: {test.argZero = 0 : i64}
+// CHECK-SAME: f32
+// CHECK-SAME: i32 {test.argTwo = 2 : i64})
func.func @multiple_arg_attr_multiple_res_attr(%arg0: memref<f32> {test.argZero = 0}, %arg1: f32, %arg2: i32 {test.argTwo = 2}) -> (f32, memref<i32> {test.returnOne = 1}, i32 {test.returnTwo = 2}) {
%0 = arith.constant 1.00 : f32
%1 = memref.alloc() : memref<i32>
@@ -71,8 +90,8 @@ func.func @multiple_arg_attr_multiple_res_attr(%arg0: memref<f32> {test.argZero
// CHECK: llvm.func @drop_linkage_attr() -> (!llvm.struct{{.*}} {test.returnOne})
// CHECK-LABEL: llvm.func @_mlir_ciface_drop_linkage_attr
+// CHECK-SAME: !llvm.ptr
// CHECK-NOT: llvm.linkage
-// CHECK: %{{.*}}: !llvm.ptr{{.*}} {test.returnOne}
func.func @drop_linkage_attr() -> (memref<f32> {test.returnOne}) attributes { llvm.linkage = #llvm.linkage<external> } {
%0 = memref.alloc() : memref<f32>
return %0 : memref<f32>
diff --git a/mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-functions.mlir b/mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-functions.mlir
index 9d73072aab9d5..f43c23773d9de 100644
--- a/mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-functions.mlir
+++ b/mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-functions.mlir
@@ -2,46 +2,64 @@
// CHECK: llvm.func @res_attrs_with_memref_return() -> (!llvm.struct{{.*}} {test.returnOne})
// CHECK-LABEL: llvm.func @_mlir_ciface_res_attrs_with_memref_return
-// CHECK: !llvm.ptr{{.*}} {test.returnOne}
+// CHECK-SAME: !llvm.ptr
+// CHECK-NOT: test.returnOne
func.func private @res_attrs_with_memref_return() -> (memref<f32> {test.returnOne})
// CHECK: llvm.func @res_attrs_with_value_return() -> (f32 {test.returnOne = 1 : i64})
// CHECK-LABEL: llvm.func @_mlir_ciface_res_attrs_with_value_return
-// CHECK: -> (f32 {test.returnOne = 1 : i64})
+// CHECK-SAME: -> (f32 {test.returnOne = 1 : i64})
func.func private @res_attrs_with_value_return() -> (f32 {test.returnOne = 1})
-// CHECK: llvm.func @multiple_return() -> (!llvm.struct<{{.*}}> {llvm.struct_attrs = [{test.returnOne = 1 : i64}, {test.returnThree = 3 : i64, test.returnTwo = 2 : i64}]})
+// CHECK: llvm.func @multiple_return() -> !llvm.struct<{{.*}}>
// CHECK-LABEL: llvm.func @_mlir_ciface_multiple_return
-// CHECK: (!llvm.ptr<{{.*}}> {llvm.struct_attrs = [{test.returnOne = 1 : i64}, {test.returnThree = 3 : i64, test.returnTwo = 2 : i64}]})
+// CHECK-NOT: test.returnOne
+// CHECK-NOT: test.returnTwo
+// CHECK-NOT: test.returnThree
func.func private @multiple_return() -> (memref<f32> {test.returnOne = 1}, f32 {test.returnTwo = 2, test.returnThree = 3})
-// CHECK: llvm.func @multiple_return_missing_res_attr() -> (!llvm.struct<{{.*}}> {llvm.struct_attrs = [{test.returnOne = 1 : i64}, {}, {test.returnThree = 3 : i64, test.returnTwo = 2 : i64}]})
+// CHECK: llvm.func @multiple_return_missing_res_attr() -> !llvm.struct<{{.*}}>
// CHECK-LABEL: llvm.func @_mlir_ciface_multiple_return_missing_res_attr
-// CHECK: (!llvm.ptr<{{.*}}> {llvm.struct_attrs = [{test.returnOne = 1 : i64}, {}, {test.returnThree = 3 : i64, test.returnTwo = 2 : i64}]})
+// CHECK-NOT: test.returnOne
+// CHECK-NOT: test.returnTwo
+// CHECK-NOT: test.returnThree
func.func private @multiple_return_missing_res_attr() -> (memref<f32> {test.returnOne = 1}, i64, f32 {test.returnTwo = 2, test.returnThree = 3})
// CHECK: llvm.func @one_arg_attr_no_res_attrs_with_memref_return({{.*}}) -> !llvm.struct{{.*}}
// CHECK-LABEL: llvm.func @_mlir_ciface_one_arg_attr_no_res_attrs_with_memref_return
-// CHECK: !llvm.ptr<{{.*}}>, !llvm.ptr<{{.*}}> {test.argOne = 1 : i64}
+// CHECK-SAME: !llvm.ptr
+// CHECK-SAME: !llvm.ptr
+// CHECK-SAME: {test.argOne = 1 : i64})
func.func private @one_arg_attr_no_res_attrs_with_memref_return(%arg0: memref<f32> {test.argOne = 1}) -> memref<f32>
// CHECK: llvm.func @one_arg_attr_one_res_attr_with_memref_return({{.*}}) -> (!llvm.struct<{{.*}}> {test.returnOne = 1 : i64})
// CHECK-LABEL: llvm.func @_mlir_ciface_one_arg_attr_one_res_attr_with_memref_return
-// CHECK: (!llvm.ptr<{{.*}}> {test.returnOne = 1 : i64}, !llvm.ptr<{{.*}}> {test.argOne = 1 : i64}
+// CHECK-SAME: !llvm.ptr
+// CHECK-NOT: test.returnOne
+// CHECK-SAME: !llvm.ptr
+// CHECK-SAME: {test.argOne = 1 : i64})
func.func private @one_arg_attr_one_res_attr_with_memref_return(%arg0: memref<f32> {test.argOne = 1}) -> (memref<f32> {test.returnOne = 1})
// CHECK: llvm.func @one_arg_attr_one_res_attr_with_value_return({{.*}}) -> (f32 {test.returnOne = 1 : i64})
// CHECK-LABEL: llvm.func @_mlir_ciface_one_arg_attr_one_res_attr_with_value_return
-// CHECK: (!llvm.ptr<{{.*}}> {test.argOne = 1 : i64}) -> (f32 {test.returnOne = 1 : i64})
+// CHECK-SAME: !llvm.ptr
+// CHECK-SAME: {test.argOne = 1 : i64}
+// CHECK-SAME: -> (f32 {test.returnOne = 1 : i64})
func.func private @one_arg_attr_one_res_attr_with_value_return(%arg0: memref<f32> {test.argOne = 1}) -> (f32 {test.returnOne = 1})
-// CHECK: llvm.func @multiple_arg_attr_multiple_res_attr({{.*}}) -> (!llvm.struct<{{.*}}> {llvm.struct_attrs = [{}, {test.returnOne = 1 : i64}, {test.returnTwo = 2 : i64}]})
+// CHECK: llvm.func @multiple_arg_attr_multiple_res_attr({{.*}}) -> !llvm.struct<{{.*}}>
// CHECK-LABEL: llvm.func @_mlir_ciface_multiple_arg_attr_multiple_res_attr
-// CHECK: (!llvm.ptr<{{.*}}> {llvm.struct_attrs = [{}, {test.returnOne = 1 : i64}, {test.returnTwo = 2 : i64}]}, !llvm.ptr<{{.*}}> {test.argZero = 0 : i64}, f32, i32 {test.argTwo = 2 : i64}
+// CHECK-SAME: !llvm.ptr
+// CHECK-NOT: test.returnOne
+// CHECK-NOT: test.returnTwo
+// CHECK-SAME: !llvm.ptr
+// CHECK-SAME: {test.argZero = 0 : i64}
+// CHECK-SAME: f32
+// CHECK-SAME: i32 {test.argTwo = 2 : i64})
func.func private @multiple_arg_attr_multiple_res_attr(%arg0: memref<f32> {test.argZero = 0}, %arg1: f32, %arg2: i32 {test.argTwo = 2}) -> (f32, memref<i32> {test.returnOne = 1}, i32 {test.returnTwo = 2})
// CHECK: llvm.func weak @drop_linkage_attr() -> (!llvm.struct{{.*}} {test.returnOne})
// CHECK-LABEL: llvm.func @_mlir_ciface_drop_linkage_attr
+// CHECK-SAME: !llvm.ptr
// CHECK-NOT: llvm.linkage
-// CHECK: !llvm.ptr{{.*}} {test.returnOne}
func.func private @drop_linkage_attr() -> (memref<f32> {test.returnOne}) attributes { llvm.linkage = #llvm.linkage<weak> }
diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir
index a425b240ba549..4547d13dc38b3 100644
--- a/mlir/test/Dialect/LLVMIR/invalid.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid.mlir
@@ -1247,69 +1247,6 @@ llvm.mlir.global internal @side_effecting_global() : !llvm.struct<(i8)> {
// -----
-// expected-error at +1 {{'llvm.struct_attrs' is permitted only in argument or result attributes}}
-func.func @struct_attrs_in_op() attributes {llvm.struct_attrs = []} {
- return
-}
-
-// -----
-
-// expected-error at +1 {{expected 'llvm.struct_attrs' to annotate '!llvm.struct' or '!llvm.ptr<struct<...>>'}}
-func.func @invalid_struct_attr_arg_type(%arg0 : i32 {llvm.struct_attrs = []}) {
- return
-}
-
-// -----
-
-// expected-error at +1 {{expected 'llvm.struct_attrs' to annotate '!llvm.struct' or '!llvm.ptr<struct<...>>'}}
-func.func @invalid_struct_attr_pointer_arg_type(%arg0 : !llvm.ptr<i32> {llvm.struct_attrs = []}) {
- return
-}
-
-// -----
-
-// expected-error at +1 {{expected 'llvm.struct_attrs' to be an array attribute}}
-func.func @invalid_arg_struct_attr_value(%arg0 : !llvm.struct<(i32)> {llvm.struct_attrs = {}}) {
- return
-}
-
-// -----
-
-// expected-error at +1 {{size of 'llvm.struct_attrs' must match the size of the annotated '!llvm.struct'}}
-func.func @invalid_arg_struct_attr_size(%arg0 : !llvm.struct<(i32)> {llvm.struct_attrs = []}) {
- return
-}
-
-// -----
-
-// expected-error at +1 {{expected 'llvm.struct_attrs' to annotate '!llvm.struct' or '!llvm.ptr<struct<...>>'}}
-func.func @invalid_struct_attr_res_type(%arg0 : i32) -> (i32 {llvm.struct_attrs = []}) {
- return %arg0 : i32
-}
-
-// -----
-
-// expected-error at +1 {{expected 'llvm.struct_attrs' to annotate '!llvm.struct' or '!llvm.ptr<struct<...>>'}}
-func.func @invalid_struct_attr_pointer_res_type(%arg0 : !llvm.ptr<i32>) -> (!llvm.ptr<i32> {llvm.struct_attrs = []}) {
- return %arg0 : !llvm.ptr<i32>
-}
-
-// -----
-
-// expected-error at +1 {{expected 'llvm.struct_attrs' to be an array attribute}}
-func.func @invalid_res_struct_attr_value(%arg0 : !llvm.struct<(i32)>) -> (!llvm.struct<(i32)> {llvm.struct_attrs = {}}) {
- return %arg0 : !llvm.struct<(i32)>
-}
-
-// -----
-
-// expected-error at +1 {{size of 'llvm.struct_attrs' must match the size of the annotated '!llvm.struct'}}
-func.func @invalid_res_struct_attr_size(%arg0 : !llvm.struct<(i32)>) -> (!llvm.struct<(i32)> {llvm.struct_attrs = []}) {
- return %arg0 : !llvm.struct<(i32)>
-}
-
-// -----
-
func.func @insert_vector_invalid_source_vector_size(%arg0 : vector<16385xi8>, %arg1 : vector<[16]xi8>) {
// expected-error at +1 {{op failed to verify that vectors are not bigger than 2^17 bits.}}
%0 = llvm.intr.vector.insert %arg0, %arg1[0] : vector<16385xi8> into vector<[16]xi8>
More information about the Mlir-commits
mailing list