diff --git a/mlir/include/mlir/IR/BuiltinAttributes.td b/mlir/include/mlir/IR/BuiltinAttributes.td --- a/mlir/include/mlir/IR/BuiltinAttributes.td +++ b/mlir/include/mlir/IR/BuiltinAttributes.td @@ -176,9 +176,9 @@ Examples: ```mlir - [:i8] - [:i32 10, 42] - [:f64 42., 12.] + array + array + array ``` when a specific subclass is used as argument of an operation, the declarative diff --git a/mlir/lib/AsmParser/AttributeParser.cpp b/mlir/lib/AsmParser/AttributeParser.cpp --- a/mlir/lib/AsmParser/AttributeParser.cpp +++ b/mlir/lib/AsmParser/AttributeParser.cpp @@ -71,8 +71,6 @@ // Parse an array attribute. case Token::l_square: { consumeToken(Token::l_square); - if (consumeIf(Token::colon)) - return parseDenseArrayAttr(); SmallVector elements; auto parseElt = [&]() -> ParseResult { elements.push_back(parseAttribute()); @@ -100,6 +98,10 @@ case Token::kw_dense_resource: return parseDenseResourceElementsAttr(type); + // Parse a dense array attribute. + case Token::kw_array: + return parseDenseArrayAttr(type); + // Parse a dictionary attribute. case Token::l_brace: { NamedAttrList elements; @@ -833,15 +835,19 @@ } // namespace /// Parse a dense array attribute. -Attribute Parser::parseDenseArrayAttr() { - auto typeLoc = getToken().getLoc(); - auto type = parseType(); - if (!type) +Attribute Parser::parseDenseArrayAttr(Type type) { + consumeToken(Token::kw_array); + SMLoc typeLoc = getToken().getLoc(); + if (parseToken(Token::less, "expected '<' after 'array'")) + return {}; + if (!type && + (!(type = parseType()) || + parseToken(Token::colon, "expected ':' after dense array type"))) return {}; CustomAsmParser parser(*this); Attribute result; // Check for empty list. - bool isEmptyList = getToken().is(Token::r_square); + bool isEmptyList = getToken().is(Token::greater); if (auto intType = type.dyn_cast()) { switch (type.getIntOrFloatBitWidth()) { @@ -901,10 +907,8 @@ emitError(typeLoc, "expected integer or float type, got: ") << type; return {}; } - if (!consumeIf(Token::r_square)) { - emitError("expected ']' to close an array attribute"); + if (parseToken(Token::greater, "expected '>' to close an array attribute")) return {}; - } return result; } diff --git a/mlir/lib/AsmParser/Parser.h b/mlir/lib/AsmParser/Parser.h --- a/mlir/lib/AsmParser/Parser.h +++ b/mlir/lib/AsmParser/Parser.h @@ -274,7 +274,7 @@ Attribute parseDenseResourceElementsAttr(Type attrType); /// Parse a DenseArrayAttr. - Attribute parseDenseArrayAttr(); + Attribute parseDenseArrayAttr(Type type); /// Parse a sparse elements attribute. Attribute parseSparseElementsAttr(Type attrType); diff --git a/mlir/lib/AsmParser/TokenKinds.def b/mlir/lib/AsmParser/TokenKinds.def --- a/mlir/lib/AsmParser/TokenKinds.def +++ b/mlir/lib/AsmParser/TokenKinds.def @@ -82,6 +82,7 @@ // this list and to cater to OCD. TOK_KEYWORD(affine_map) TOK_KEYWORD(affine_set) +TOK_KEYWORD(array) TOK_KEYWORD(attributes) TOK_KEYWORD(bf16) TOK_KEYWORD(ceildiv) diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp --- a/mlir/lib/IR/AsmPrinter.cpp +++ b/mlir/lib/IR/AsmPrinter.cpp @@ -1860,11 +1860,11 @@ } } else if (auto denseArrayAttr = attr.dyn_cast()) { typeElision = AttrTypeElision::Must; - os << "[:" << denseArrayAttr.getType().getElementType(); + os << "array<" << denseArrayAttr.getType().getElementType() << ":"; if (denseArrayAttr.size()) os << " "; denseArrayAttr.printWithoutBraces(os); - os << "]"; + os << ">"; } else if (auto resourceAttr = attr.dyn_cast()) { os << "dense_resource<"; printResourceHandle(resourceAttr.getRawHandle()); diff --git a/mlir/test/Dialect/LLVMIR/dynamic-gep-index.mlir b/mlir/test/Dialect/LLVMIR/dynamic-gep-index.mlir --- a/mlir/test/Dialect/LLVMIR/dynamic-gep-index.mlir +++ b/mlir/test/Dialect/LLVMIR/dynamic-gep-index.mlir @@ -6,7 +6,7 @@ // CHECK: %[[C0:.+]] = llvm.mlir.constant(0 : i32) %0 = llvm.mlir.constant(0 : i32) : i32 // CHECK: llvm.getelementptr %[[ARG0]][%[[C0]], 1, %[[ARG1]]] - %1 = "llvm.getelementptr"(%arg0, %0, %arg1) {rawConstantIndices = [:i32 -2147483648, 1, -2147483648]} : (!llvm.ptr, array<4 x i32>)>>, i32, i32) -> !llvm.ptr + %1 = "llvm.getelementptr"(%arg0, %0, %arg1) {rawConstantIndices = array} : (!llvm.ptr, array<4 x i32>)>>, i32, i32) -> !llvm.ptr llvm.return } } 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 @@ -148,7 +148,7 @@ func.func @gep_too_few_dynamic(%base : !llvm.ptr) { // expected-error@+1 {{expected as many dynamic indices as specified in 'rawConstantIndices'}} - %1 = "llvm.getelementptr"(%base) {rawConstantIndices = [:i32 -2147483648]} : (!llvm.ptr) -> !llvm.ptr + %1 = "llvm.getelementptr"(%base) {rawConstantIndices = array} : (!llvm.ptr) -> !llvm.ptr } // ----- @@ -414,7 +414,7 @@ func.func @insertvalue_invalid_type(%a : !llvm.array<1 x i32>) -> !llvm.array<1 x i32> { // expected-error@+1 {{'llvm.insertvalue' op Type mismatch: cannot insert '!llvm.array<1 x i32>' into '!llvm.array<1 x i32>'}} - %b = "llvm.insertvalue"(%a, %a) {position = [:i64 0]} : (!llvm.array<1 x i32>, !llvm.array<1 x i32>) -> !llvm.array<1 x i32> + %b = "llvm.insertvalue"(%a, %a) {position = array} : (!llvm.array<1 x i32>, !llvm.array<1 x i32>) -> !llvm.array<1 x i32> return %b : !llvm.array<1 x i32> } @@ -422,7 +422,7 @@ func.func @extractvalue_invalid_type(%a : !llvm.array<4 x vector<8xf32>>) -> !llvm.array<4 x vector<8xf32>> { // expected-error@+1 {{'llvm.extractvalue' op Type mismatch: extracting from '!llvm.array<4 x vector<8xf32>>' should produce 'vector<8xf32>' but this op returns '!llvm.array<4 x vector<8xf32>>'}} - %b = "llvm.extractvalue"(%a) {position = [:i64 1]} + %b = "llvm.extractvalue"(%a) {position = array} : (!llvm.array<4 x vector<8xf32>>) -> !llvm.array<4 x vector<8xf32>> return %b : !llvm.array<4 x vector<8xf32>> } diff --git a/mlir/test/IR/attribute.mlir b/mlir/test/IR/attribute.mlir --- a/mlir/test/IR/attribute.mlir +++ b/mlir/test/IR/attribute.mlir @@ -522,34 +522,34 @@ // CHECK-LABEL: func @dense_array_attr func.func @dense_array_attr() attributes { -// CHECK-SAME: emptyf32attr = [:f32], - emptyf32attr = [:f32], -// CHECK-SAME: emptyf64attr = [:f64], - emptyf64attr = [:f64], -// CHECK-SAME: emptyi16attr = [:i16], - emptyi16attr = [:i16], -// CHECK-SAME: emptyi1attr = [:i1], - emptyi1attr = [:i1], -// CHECK-SAME: emptyi32attr = [:i32], - emptyi32attr = [:i32], -// CHECK-SAME: emptyi64attr = [:i64], - emptyi64attr = [:i64], -// CHECK-SAME: emptyi8attr = [:i8], - emptyi8attr = [:i8], -// CHECK-SAME: f32attr = [:f32 1.024000e+03, 4.530000e+02, -6.435000e+03], - f32attr = [:f32 1024., 453., -6435.], -// CHECK-SAME: f64attr = [:f64 -1.420000e+02], - f64attr = [:f64 -142.], -// CHECK-SAME: i16attr = [:i16 3, 5, -4, 10], - i16attr = [:i16 3, 5, -4, 10], -// CHECK-SAME: i1attr = [:i1 true, false, true], - i1attr = [:i1 true, false, true], -// CHECK-SAME: i32attr = [:i32 1024, 453, -6435], - i32attr = [:i32 1024, 453, -6435], -// CHECK-SAME: i64attr = [:i64 -142], - i64attr = [:i64 -142], -// CHECK-SAME: i8attr = [:i8 1, -2, 3] - i8attr = [:i8 1, -2, 3] +// CHECK-SAME: emptyf32attr = array, + emptyf32attr = array, +// CHECK-SAME: emptyf64attr = array, + emptyf64attr = array, +// CHECK-SAME: emptyi16attr = array, + emptyi16attr = array, +// CHECK-SAME: emptyi1attr = array, + emptyi1attr = array, +// CHECK-SAME: emptyi32attr = array, + emptyi32attr = array, +// CHECK-SAME: emptyi64attr = array, + emptyi64attr = array, +// CHECK-SAME: emptyi8attr = array, + emptyi8attr = array, +// CHECK-SAME: f32attr = array, + f32attr = array, +// CHECK-SAME: f64attr = array, + f64attr = array, +// CHECK-SAME: i16attr = array, + i16attr = array, +// CHECK-SAME: i1attr = array, + i1attr = array, +// CHECK-SAME: i32attr = array, + i32attr = array, +// CHECK-SAME: i64attr = array, + i64attr = array, +// CHECK-SAME: i8attr = array + i8attr = array } { // CHECK: test.dense_array_attr test.dense_array_attr diff --git a/mlir/test/IR/elements-attr-interface.mlir b/mlir/test/IR/elements-attr-interface.mlir --- a/mlir/test/IR/elements-attr-interface.mlir +++ b/mlir/test/IR/elements-attr-interface.mlir @@ -28,19 +28,19 @@ arith.constant dense<> : tensor<0xi64> // expected-error@below {{Test iterating `bool`: true, false, true, false, true, false}} -arith.constant [:i1 true, false, true, false, true, false] +arith.constant array // expected-error@below {{Test iterating `int8_t`: 10, 11, -12, 13, 14}} -arith.constant [:i8 10, 11, -12, 13, 14] +arith.constant array // expected-error@below {{Test iterating `int16_t`: 10, 11, -12, 13, 14}} -arith.constant [:i16 10, 11, -12, 13, 14] +arith.constant array // expected-error@below {{Test iterating `int32_t`: 10, 11, -12, 13, 14}} -arith.constant [:i32 10, 11, -12, 13, 14] +arith.constant array // expected-error@below {{Test iterating `int64_t`: 10, 11, -12, 13, 14}} -arith.constant [:i64 10, 11, -12, 13, 14] +arith.constant array // expected-error@below {{Test iterating `float`: 10.00, 11.00, -12.00, 13.00, 14.00}} -arith.constant [:f32 10., 11., -12., 13., 14.] +arith.constant array // expected-error@below {{Test iterating `double`: 10.00, 11.00, -12.00, 13.00, 14.00}} -arith.constant [:f64 10., 11., -12., 13., 14.] +arith.constant array // Check that we handle an external constant parsed from the config. // expected-error@below {{Test iterating `int64_t`: unable to iterate type}}