diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td @@ -40,7 +40,6 @@ 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. @@ -73,10 +72,6 @@ /// 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 --- a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp +++ b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp @@ -78,54 +78,26 @@ } } -/// 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 &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 &attributes, - func::FuncOp func) { size_t numArguments = func.getNumArguments(); - auto allAttrs = SmallVector( - 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(); - 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(); - 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 newArgAttrs; + newArgAttrs.reserve(numArguments + 1); + // Insert empty dictionary for the new argument. + newArgAttrs.push_back(builder.getDictionaryAttr({})); + + llvm::copy(argAttrs.value(), std::back_inserter(newArgAttrs)); + 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 @@ func::FuncOp funcOp, LLVM::LLVMFuncOp newFuncOp) { auto type = funcOp.getFunctionType(); - SmallVector attributes; - filterFuncAttributes(funcOp, /*filterArgAndResAttrs=*/false, attributes); auto [wrapperFuncType, resultIsNowArg] = typeConverter.convertFunctionTypeCWrapper(type); + + SmallVector 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( loc, llvm::formatv("_mlir_ciface_{0}", funcOp.getName()).str(), wrapperFuncType, LLVM::Linkage::External, /*dsoLocal*/ false, @@ -207,10 +183,13 @@ assert(wrapperType && "unexpected type conversion failure"); SmallVector 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( loc, llvm::formatv("_mlir_ciface_{0}", funcOp.getName()).str(), @@ -312,8 +291,7 @@ 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 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -3018,12 +3018,6 @@ } } - 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 @@ << "' to be a string attributes"; } -LogicalResult LLVMDialect::verifyStructAttr(Operation *op, Attribute attr, - Type annotatedType) { - auto structType = annotatedType.dyn_cast(); - if (!structType) { - const auto emitIncorrectAnnotatedType = [&op]() { - return op->emitError() - << "expected '" << LLVMDialect::getStructAttrsAttrName() - << "' to annotate '!llvm.struct' or '!llvm.ptr>'"; - }; - const auto ptrType = annotatedType.dyn_cast(); - if (!ptrType) - return emitIncorrectAnnotatedType(); - structType = ptrType.getElementType().dyn_cast(); - if (!structType) - return emitIncorrectAnnotatedType(); - } - - const auto arrAttrs = attr.dyn_cast(); - 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(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 @@ 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 --- 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-SAME: (%{{.*}}: !llvm.ptr{{.*}}) func.func @res_attrs_with_memref_return() -> (memref {test.returnOne}) { %0 = memref.alloc() : memref return %0 : memref @@ -10,24 +10,24 @@ // 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<{{.*}}>) func.func @multiple_return() -> (memref {test.returnOne = 1}, f32 {test.returnTwo = 2, test.returnThree = 3}) { %0 = memref.alloc() : memref %1 = arith.constant 1.00 : f32 return %0, %1 : memref, 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<{{.*}}>) func.func @multiple_return_missing_res_attr() -> (memref {test.returnOne = 1}, i64, f32 {test.returnTwo = 2, test.returnThree = 3}) { %0 = memref.alloc() : memref %1 = arith.constant 2 : i64 @@ -37,7 +37,7 @@ // 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<{{.*}}>, %{{.*}}: !llvm.ptr<{{.*}}> {test.argOne = 1 : i64}) func.func @one_arg_attr_no_res_attrs_with_memref_return(%arg0: memref {test.argOne = 1}) -> memref { %0 = memref.alloc() : memref return %0 : memref @@ -45,7 +45,7 @@ // 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<{{.*}}>, %{{.*}}: !llvm.ptr<{{.*}}> {test.argOne = 1 : i64}) func.func @one_arg_attr_one_res_attr_with_memref_return(%arg0: memref {test.argOne = 1}) -> (memref {test.returnOne = 1}) { %0 = memref.alloc() : memref return %0 : memref @@ -53,15 +53,15 @@ // 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<{{.*}}> {test.argOne = 1 : i64}) -> (f32 {test.returnOne = 1 : i64}) func.func @one_arg_attr_one_res_attr_with_value_return(%arg0: memref {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<{{.*}}>, %{{.*}}: !llvm.ptr<{{.*}}> {test.argZero = 0 : i64}, %{{.*}}: f32, %{{.*}}: i32 {test.argTwo = 2 : i64}) func.func @multiple_arg_attr_multiple_res_attr(%arg0: memref {test.argZero = 0}, %arg1: f32, %arg2: i32 {test.argTwo = 2}) -> (f32, memref {test.returnOne = 1}, i32 {test.returnTwo = 2}) { %0 = arith.constant 1.00 : f32 %1 = memref.alloc() : memref @@ -71,8 +71,8 @@ // 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 {test.returnOne}) attributes { llvm.linkage = #llvm.linkage } { %0 = memref.alloc() : memref return %0 : memref 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 --- 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,46 @@ // 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{{.*}}) func.func private @res_attrs_with_memref_return() -> (memref {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-SAME: (!llvm.ptr<{{.*}}>) func.func private @multiple_return() -> (memref {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-SAME: (!llvm.ptr<{{.*}}>) func.func private @multiple_return_missing_res_attr() -> (memref {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<{{.*}}>, !llvm.ptr<{{.*}}> {test.argOne = 1 : i64}) func.func private @one_arg_attr_no_res_attrs_with_memref_return(%arg0: memref {test.argOne = 1}) -> memref // 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<{{.*}}>, !llvm.ptr<{{.*}}> {test.argOne = 1 : i64}) func.func private @one_arg_attr_one_res_attr_with_memref_return(%arg0: memref {test.argOne = 1}) -> (memref {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<{{.*}}> {test.argOne = 1 : i64}) -> (f32 {test.returnOne = 1 : i64}) func.func private @one_arg_attr_one_res_attr_with_value_return(%arg0: memref {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<{{.*}}>, !llvm.ptr<{{.*}}> {test.argZero = 0 : i64}, f32, i32 {test.argTwo = 2 : i64}) func.func private @multiple_arg_attr_multiple_res_attr(%arg0: memref {test.argZero = 0}, %arg1: f32, %arg2: i32 {test.argTwo = 2}) -> (f32, memref {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 {test.returnOne}) attributes { llvm.linkage = #llvm.linkage } diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir --- a/mlir/test/Dialect/LLVMIR/invalid.mlir +++ b/mlir/test/Dialect/LLVMIR/invalid.mlir @@ -1247,69 +1247,6 @@ // ----- -// expected-error@+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@+1 {{expected 'llvm.struct_attrs' to annotate '!llvm.struct' or '!llvm.ptr>'}} -func.func @invalid_struct_attr_arg_type(%arg0 : i32 {llvm.struct_attrs = []}) { - return -} - -// ----- - -// expected-error@+1 {{expected 'llvm.struct_attrs' to annotate '!llvm.struct' or '!llvm.ptr>'}} -func.func @invalid_struct_attr_pointer_arg_type(%arg0 : !llvm.ptr {llvm.struct_attrs = []}) { - return -} - -// ----- - -// expected-error@+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@+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@+1 {{expected 'llvm.struct_attrs' to annotate '!llvm.struct' or '!llvm.ptr>'}} -func.func @invalid_struct_attr_res_type(%arg0 : i32) -> (i32 {llvm.struct_attrs = []}) { - return %arg0 : i32 -} - -// ----- - -// expected-error@+1 {{expected 'llvm.struct_attrs' to annotate '!llvm.struct' or '!llvm.ptr>'}} -func.func @invalid_struct_attr_pointer_res_type(%arg0 : !llvm.ptr) -> (!llvm.ptr {llvm.struct_attrs = []}) { - return %arg0 : !llvm.ptr -} - -// ----- - -// expected-error@+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@+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@+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>