1// RUN: mlir-tblgen -gen-op-decls -I %S/../../include %s | FileCheck %s --check-prefix=DECL 2// RUN: mlir-tblgen -gen-op-defs -I %S/../../include %s | FileCheck %s --check-prefix=DEF 3// RUN: mlir-tblgen -print-records -I %S/../../include %s | FileCheck %s --check-prefix=RECORD 4 5include "mlir/IR/AttrTypeBase.td" 6include "mlir/IR/EnumAttr.td" 7include "mlir/IR/OpBase.td" 8 9def Test_Dialect : Dialect { 10 let name = "test"; 11 let cppNamespace = "foobar"; 12 let usePropertiesForAttributes = 0; 13} 14class NS_Op<string mnemonic, list<Trait> traits> : 15 Op<Test_Dialect, mnemonic, traits>; 16 17def SomeAttr : Attr<CPred<"some-condition">, "some attribute kind"> { 18 let storageType = "some-attr-kind"; 19 let returnType = "some-return-type"; 20 let convertFromStorage = "$_self.some-convert-from-storage()"; 21 let constBuilderCall = "some-const-builder-call($_builder, $0)"; 22} 23 24def SomeAttrDef : AttrDef<Test_Dialect, "SomeAttr"> { 25 let attrName = "test.some_attr"; 26} 27 28 29// Test required, optional, default-valued attributes 30// --- 31 32def AOp : NS_Op<"a_op", []> { 33 let arguments = (ins 34 SomeAttr:$aAttr, 35 DefaultValuedAttr<SomeAttr, "4.2">:$bAttr, 36 OptionalAttr<SomeAttr>:$cAttr, 37 DefaultValuedOptionalAttr<SomeAttr, "4.2">:$dAttr 38 ); 39} 40 41// DECL-LABEL: AOp declarations 42 43// Test attribute name methods 44// --- 45 46// DECL: static ::llvm::ArrayRef<::llvm::StringRef> getAttributeNames() 47// DECL-NEXT: static ::llvm::StringRef attrNames[] = 48// DECL-SAME: {::llvm::StringRef("aAttr"), ::llvm::StringRef("bAttr"), ::llvm::StringRef("cAttr"), ::llvm::StringRef("dAttr")}; 49// DECL-NEXT: return ::llvm::ArrayRef(attrNames); 50 51// DECL: ::mlir::StringAttr getAAttrAttrName() 52// DECL-NEXT: return getAttributeNameForIndex(0); 53// DECL: ::mlir::StringAttr getAAttrAttrName(::mlir::OperationName name) 54// DECL-NEXT: return getAttributeNameForIndex(name, 0); 55 56// DECL: ::mlir::StringAttr getBAttrAttrName() 57// DECL-NEXT: return getAttributeNameForIndex(1); 58// DECL: ::mlir::StringAttr getBAttrAttrName(::mlir::OperationName name) 59// DECL-NEXT: return getAttributeNameForIndex(name, 1); 60 61// DECL: ::mlir::StringAttr getCAttrAttrName() 62// DECL-NEXT: return getAttributeNameForIndex(2); 63// DECL: ::mlir::StringAttr getCAttrAttrName(::mlir::OperationName name) 64// DECL-NEXT: return getAttributeNameForIndex(name, 2); 65 66// DEF-LABEL: AOp definitions 67 68// Test verify method 69// --- 70 71// DEF: ::llvm::LogicalResult AOpAdaptor::verify 72// DEF: ::mlir::Attribute tblgen_aAttr; 73// DEF: while (true) { 74// DEF-NEXT: if (namedAttrIt == namedAttrRange.end()) 75// DEF-NEXT: return emitError(loc, "'test.a_op' op ""requires attribute 'aAttr'"); 76// DEF-NEXT: if (namedAttrIt->getName() == AOp::getAAttrAttrName(*odsOpName)) { 77// DEF-NEXT: tblgen_aAttr = namedAttrIt->getValue(); 78// DEF-NEXT: break; 79// DEF: ::mlir::Attribute tblgen_bAttr; 80// DEF-NEXT: ::mlir::Attribute tblgen_cAttr; 81// DEF-NEXT: ::mlir::Attribute tblgen_dAttr; 82// DEF-NEXT: while (true) { 83// DEF-NEXT: if (namedAttrIt == namedAttrRange.end()) 84// DEF-NEXT: break; 85// DEF: if (namedAttrIt->getName() == AOp::getBAttrAttrName(*odsOpName)) 86// DEF-NEXT: tblgen_bAttr = namedAttrIt->getValue(); 87// DEF: if (namedAttrIt->getName() == AOp::getCAttrAttrName(*odsOpName)) 88// DEF-NEXT: tblgen_cAttr = namedAttrIt->getValue(); 89// DEF: if (tblgen_aAttr && !((some-condition))) 90// DEF-NEXT: return emitError(loc, "'test.a_op' op ""attribute 'aAttr' failed to satisfy constraint: some attribute kind"); 91// DEF: if (tblgen_bAttr && !((some-condition))) 92// DEF-NEXT: return emitError(loc, "'test.a_op' op ""attribute 'bAttr' failed to satisfy constraint: some attribute kind"); 93// DEF: if (tblgen_cAttr && !((some-condition))) 94// DEF-NEXT: return emitError(loc, "'test.a_op' op ""attribute 'cAttr' failed to satisfy constraint: some attribute kind"); 95// DEF: if (tblgen_dAttr && !((some-condition))) 96// DEF-NEXT: return emitError(loc, "'test.a_op' op ""attribute 'dAttr' failed to satisfy constraint: some attribute kind"); 97 98// Test getter methods 99// --- 100 101// DECL: some-attr-kind getAAttrAttr() 102// DECL-NEXT: ::llvm::cast<some-attr-kind>(::mlir::impl::getAttrFromSortedRange((*this)->getAttrs().begin() + 0, (*this)->getAttrs().end() - 0, getAAttrAttrName())) 103// DEF: some-return-type AOp::getAAttr() { 104// DEF-NEXT: auto attr = getAAttrAttr() 105// DEF-NEXT: return attr.some-convert-from-storage(); 106 107// DECL: some-attr-kind getBAttrAttr() 108// DECL-NEXT: ::llvm::dyn_cast_or_null<some-attr-kind>(::mlir::impl::getAttrFromSortedRange((*this)->getAttrs().begin() + 1, (*this)->getAttrs().end() - 0, getBAttrAttrName())) 109// DEF: some-return-type AOp::getBAttr() { 110// DEF-NEXT: auto attr = getBAttrAttr(); 111// DEF-NEXT: return attr.some-convert-from-storage(); 112 113// DECL: some-attr-kind getCAttrAttr() 114// DECL-NEXT: ::llvm::dyn_cast_or_null<some-attr-kind>(::mlir::impl::getAttrFromSortedRange((*this)->getAttrs().begin() + 1, (*this)->getAttrs().end() - 0, getCAttrAttrName())) 115// DEF: ::std::optional<some-return-type> AOp::getCAttr() { 116// DEF-NEXT: auto attr = getCAttrAttr() 117// DEF-NEXT: return attr ? ::std::optional<some-return-type>(attr.some-convert-from-storage()) : (::std::nullopt); 118 119// DECL: some-attr-kind getDAttrAttr() 120// DECL-NEXT: ::llvm::dyn_cast_or_null<some-attr-kind>(::mlir::impl::getAttrFromSortedRange((*this)->getAttrs().begin() + 1, (*this)->getAttrs().end() - 0, getDAttrAttrName())) 121// DEF: some-return-type AOp::getDAttr() { 122// DEF-NEXT: auto attr = getDAttrAttr(); 123// DEF-NEXT: if (!attr) 124// DEF-NEXT: return some-const-builder-call(::mlir::Builder((*this)->getContext()), 4.2).some-convert-from-storage(); 125// DEF-NEXT: return attr.some-convert-from-storage(); 126 127// Test setter methods 128// --- 129 130// DECL: void setAAttrAttr(some-attr-kind attr) { 131// DECL-NEXT: (*this)->setAttr(getAAttrAttrName(), attr); 132// DEF: void AOp::setAAttr(some-return-type attrValue) { 133// DEF-NEXT: (*this)->setAttr(getAAttrAttrName(), some-const-builder-call(::mlir::Builder((*this)->getContext()), attrValue)); 134// DECL: void setBAttrAttr(some-attr-kind attr) { 135// DECL-NEXT: (*this)->setAttr(getBAttrAttrName(), attr); 136// DEF: void AOp::setBAttr(some-return-type attrValue) { 137// DEF-NEXT: (*this)->setAttr(getBAttrAttrName(), some-const-builder-call(::mlir::Builder((*this)->getContext()), attrValue)); 138// DECL: void setCAttrAttr(some-attr-kind attr) { 139// DECL-NEXT: (*this)->setAttr(getCAttrAttrName(), attr); 140// DEF: void AOp::setCAttr(::std::optional<some-return-type> attrValue) { 141// DEF-NEXT: if (attrValue) 142// DEF-NEXT: return (*this)->setAttr(getCAttrAttrName(), some-const-builder-call(::mlir::Builder((*this)->getContext()), *attrValue)); 143// DEF-NEXT: (*this)->removeAttr(getCAttrAttrName()); 144 145// Test remove methods 146// --- 147 148// DECL: ::mlir::Attribute removeCAttrAttr() { 149// DECL-NEXT: return (*this)->removeAttr(getCAttrAttrName()); 150 151// Test build methods 152// --- 153 154// DEF: void AOp::build( 155// DEF: odsState.addAttribute(getAAttrAttrName(odsState.name), aAttr); 156// DEF: odsState.addAttribute(getBAttrAttrName(odsState.name), bAttr); 157// DEF: if (cAttr) { 158// DEF-NEXT: odsState.addAttribute(getCAttrAttrName(odsState.name), cAttr); 159 160// DEF: odsState.addAttribute(getAAttrAttrName(odsState.name), some-const-builder-call(odsBuilder, aAttr)); 161// DEF-NEXT: odsState.addAttribute(getBAttrAttrName(odsState.name), some-const-builder-call(odsBuilder, bAttr)); 162// DEF-NEXT: if (cAttr) { 163// DEF-NEXT: odsState.addAttribute(getCAttrAttrName(odsState.name), cAttr); 164// DEF-NEXT: } 165// DEF-NOT: if (dAttr) 166// DEF: odsState.addAttribute(getDAttrAttrName(odsState.name), some-const-builder-call(odsBuilder, dAttr)); 167 168// DEF: void AOp::build( 169// DEF: some-return-type aAttr, some-return-type bAttr, /*optional*/some-attr-kind cAttr 170// DEF: odsState.addAttribute(getAAttrAttrName(odsState.name), some-const-builder-call(odsBuilder, aAttr)); 171 172// DEF: void AOp::build( 173// DEF: ::llvm::ArrayRef<::mlir::NamedAttribute> attributes 174// DEF: odsState.addAttributes(attributes); 175 176// DEF: void AOp::populateDefaultAttrs 177 178// Test the above but with prefix. 179 180def Test2_Dialect : Dialect { 181 let name = "test2"; 182 let cppNamespace = "foobar2"; 183 let usePropertiesForAttributes = 0; 184} 185def AgetOp : Op<Test2_Dialect, "a_get_op", []> { 186 let arguments = (ins 187 SomeAttr:$aAttr, 188 DefaultValuedOptionalAttr<SomeAttr, "4.2">:$bAttr, 189 OptionalAttr<SomeAttr>:$cAttr 190 ); 191} 192 193// DECL-LABEL: AgetOp declarations 194 195// Test attribute name methods 196// --- 197 198// DECL: static ::llvm::ArrayRef<::llvm::StringRef> getAttributeNames() 199// DECL-NEXT: static ::llvm::StringRef attrNames[] = 200// DECL-SAME: {::llvm::StringRef("aAttr"), ::llvm::StringRef("bAttr"), ::llvm::StringRef("cAttr")}; 201// DECL-NEXT: return ::llvm::ArrayRef(attrNames); 202 203// DECL: ::mlir::StringAttr getAAttrAttrName() 204// DECL-NEXT: return getAttributeNameForIndex(0); 205// DECL: ::mlir::StringAttr getAAttrAttrName(::mlir::OperationName name) 206// DECL-NEXT: return getAttributeNameForIndex(name, 0); 207 208// DECL: ::mlir::StringAttr getBAttrAttrName() 209// DECL-NEXT: return getAttributeNameForIndex(1); 210// DECL: ::mlir::StringAttr getBAttrAttrName(::mlir::OperationName name) 211// DECL-NEXT: return getAttributeNameForIndex(name, 1); 212 213// DECL: ::mlir::StringAttr getCAttrAttrName() 214// DECL-NEXT: return getAttributeNameForIndex(2); 215// DECL: ::mlir::StringAttr getCAttrAttrName(::mlir::OperationName name) 216// DECL-NEXT: return getAttributeNameForIndex(name, 2); 217 218// DEF-LABEL: AgetOp definitions 219 220// Test verify method 221// --- 222 223// DEF: ::llvm::LogicalResult AgetOpAdaptor::verify 224// DEF: ::mlir::Attribute tblgen_aAttr; 225// DEF: while (true) 226// DEF: ::mlir::Attribute tblgen_bAttr; 227// DEF-NEXT: ::mlir::Attribute tblgen_cAttr; 228// DEF: while (true) 229// DEF: if (tblgen_aAttr && !((some-condition))) 230// DEF-NEXT: return emitError(loc, "'test2.a_get_op' op ""attribute 'aAttr' failed to satisfy constraint: some attribute kind"); 231// DEF: if (tblgen_bAttr && !((some-condition))) 232// DEF-NEXT: return emitError(loc, "'test2.a_get_op' op ""attribute 'bAttr' failed to satisfy constraint: some attribute kind"); 233// DEF: if (tblgen_cAttr && !((some-condition))) 234// DEF-NEXT: return emitError(loc, "'test2.a_get_op' op ""attribute 'cAttr' failed to satisfy constraint: some attribute kind"); 235 236// Test getter methods 237// --- 238 239// DECL: some-attr-kind getAAttrAttr() 240// DECL-NEXT: ::llvm::cast<some-attr-kind>(::mlir::impl::getAttrFromSortedRange({{.*}})) 241// DEF: some-return-type AgetOp::getAAttr() { 242// DEF-NEXT: auto attr = getAAttrAttr() 243// DEF-NEXT: return attr.some-convert-from-storage(); 244 245// DECL: some-attr-kind getBAttrAttr() 246// DECL-NEXT: return ::llvm::dyn_cast_or_null<some-attr-kind>(::mlir::impl::getAttrFromSortedRange({{.*}})) 247// DEF: some-return-type AgetOp::getBAttr() { 248// DEF-NEXT: auto attr = getBAttrAttr(); 249// DEF-NEXT: if (!attr) 250// DEF-NEXT: return some-const-builder-call(::mlir::Builder((*this)->getContext()), 4.2).some-convert-from-storage(); 251// DEF-NEXT: return attr.some-convert-from-storage(); 252 253// DECL: some-attr-kind getCAttrAttr() 254// DECL-NEXT: return ::llvm::dyn_cast_or_null<some-attr-kind>(::mlir::impl::getAttrFromSortedRange({{.*}})) 255// DEF: ::std::optional<some-return-type> AgetOp::getCAttr() { 256// DEF-NEXT: auto attr = getCAttrAttr() 257// DEF-NEXT: return attr ? ::std::optional<some-return-type>(attr.some-convert-from-storage()) : (::std::nullopt); 258 259// Test setter methods 260// --- 261 262// DECL: void setAAttrAttr(some-attr-kind attr) { 263// DECL-NEXT: (*this)->setAttr(getAAttrAttrName(), attr); 264// DECL: void setBAttrAttr(some-attr-kind attr) { 265// DECL-NEXT: (*this)->setAttr(getBAttrAttrName(), attr); 266// DECL: void setCAttrAttr(some-attr-kind attr) { 267// DECL-NEXT: (*this)->setAttr(getCAttrAttrName(), attr); 268 269// Test remove methods 270// --- 271 272// DECL: ::mlir::Attribute removeCAttrAttr() { 273// DECL-NEXT: return (*this)->removeAttr(getCAttrAttrName()); 274 275// Test build methods 276// --- 277 278// DEF: void AgetOp::build( 279// DEF: odsState.addAttribute(getAAttrAttrName(odsState.name), aAttr); 280// DEF: odsState.addAttribute(getBAttrAttrName(odsState.name), bAttr); 281// DEF: if (cAttr) { 282// DEF-NEXT: odsState.addAttribute(getCAttrAttrName(odsState.name), cAttr); 283 284// DEF: void AgetOp::build( 285// DEF: some-return-type aAttr, /*optional*/some-return-type bAttr, /*optional*/some-attr-kind cAttr 286// DEF: odsState.addAttribute(getAAttrAttrName(odsState.name), some-const-builder-call(odsBuilder, aAttr)); 287 288// DEF: void AgetOp::build( 289// DEF: ::llvm::ArrayRef<::mlir::NamedAttribute> attributes 290// DEF: odsState.addAttributes(attributes); 291 292// Test the above but using properties. 293def ApropOp : NS_Op<"a_prop_op", []> { 294 let arguments = (ins 295 Property<"unsigned">:$aAttr, 296 DefaultValuedAttr<SomeAttr, "4.2">:$bAttr 297 ); 298} 299 300// DEF-LABEL: ApropOp definitions 301// DEF: void ApropOp::populateDefaultProperties 302 303def SomeTypeAttr : TypeAttrBase<"SomeType", "some type attribute">; 304 305def BOp : NS_Op<"b_op", []> { 306 let arguments = (ins 307 AnyAttr:$any_attr, 308 BoolAttr:$bool_attr, 309 I32Attr:$i32_attr, 310 I64Attr:$i64_attr, 311 F32Attr:$f32_attr, 312 F64Attr:$f64_attr, 313 StrAttr:$str_attr, 314 ElementsAttr:$elements_attr, 315 FlatSymbolRefAttr:$function_attr, 316 SomeTypeAttr:$some_type_attr, 317 ArrayAttr:$array_attr, 318 TypedArrayAttrBase<SomeAttr, "SomeAttr array">:$some_attr_array, 319 TypeAttr:$type_attr 320 ); 321} 322 323 324// Test common attribute kinds' constraints 325// --- 326 327// DEF-LABEL: BOpAdaptor::verify 328// DEF: if (tblgen_any_attr && !((true))) 329// DEF: if (tblgen_bool_attr && !((::llvm::isa<::mlir::BoolAttr>(tblgen_bool_attr)))) 330// DEF: if (tblgen_i32_attr && !(((::llvm::isa<::mlir::IntegerAttr>(tblgen_i32_attr))) && ((::llvm::cast<::mlir::IntegerAttr>(tblgen_i32_attr).getType().isSignlessInteger(32))))) 331// DEF: if (tblgen_i64_attr && !(((::llvm::isa<::mlir::IntegerAttr>(tblgen_i64_attr))) && ((::llvm::cast<::mlir::IntegerAttr>(tblgen_i64_attr).getType().isSignlessInteger(64))))) 332// DEF: if (tblgen_f32_attr && !(((::llvm::isa<::mlir::FloatAttr>(tblgen_f32_attr))) && ((::llvm::cast<::mlir::FloatAttr>(tblgen_f32_attr).getType().isF32())))) 333// DEF: if (tblgen_f64_attr && !(((::llvm::isa<::mlir::FloatAttr>(tblgen_f64_attr))) && ((::llvm::cast<::mlir::FloatAttr>(tblgen_f64_attr).getType().isF64())))) 334// DEF: if (tblgen_str_attr && !((::llvm::isa<::mlir::StringAttr>(tblgen_str_attr)))) 335// DEF: if (tblgen_elements_attr && !((::llvm::isa<::mlir::ElementsAttr>(tblgen_elements_attr)))) 336// DEF: if (tblgen_function_attr && !((::llvm::isa<::mlir::FlatSymbolRefAttr>(tblgen_function_attr)))) 337// DEF: if (tblgen_some_type_attr && !(((::llvm::isa<::mlir::TypeAttr>(tblgen_some_type_attr))) && ((::llvm::isa<SomeType>(::llvm::cast<::mlir::TypeAttr>(tblgen_some_type_attr).getValue()))) && ((true)))) 338// DEF: if (tblgen_array_attr && !((::llvm::isa<::mlir::ArrayAttr>(tblgen_array_attr)))) 339// DEF: if (tblgen_some_attr_array && !(((::llvm::isa<::mlir::ArrayAttr>(tblgen_some_attr_array))) && (::llvm::all_of(::llvm::cast<::mlir::ArrayAttr>(tblgen_some_attr_array), [&](::mlir::Attribute attr) { return attr && ((some-condition)); })))) 340// DEF: if (tblgen_type_attr && !(((::llvm::isa<::mlir::TypeAttr>(tblgen_type_attr))) && ((::llvm::isa<::mlir::Type>(::llvm::cast<::mlir::TypeAttr>(tblgen_type_attr).getValue()))) && ((true)))) 341 342// Test common attribute kind getters' return types 343// --- 344 345// DEF: ::mlir::Attribute BOp::getAnyAttr() 346// DEF: bool BOp::getBoolAttr() 347// DEF: uint32_t BOp::getI32Attr() 348// DEF: uint64_t BOp::getI64Attr() 349// DEF: ::llvm::APFloat BOp::getF32Attr() 350// DEF: ::llvm::APFloat BOp::getF64Attr() 351// DEF: ::llvm::StringRef BOp::getStrAttr() 352// DEF: ::mlir::ElementsAttr BOp::getElementsAttr() 353// DEF: ::llvm::StringRef BOp::getFunctionAttr() 354// DEF: SomeType BOp::getSomeTypeAttr() 355// DEF: ::mlir::ArrayAttr BOp::getArrayAttr() 356// DEF: ::mlir::ArrayAttr BOp::getSomeAttrArray() 357// DEF: ::mlir::Type BOp::getTypeAttr() 358 359// Test building constant values for array attribute kinds 360// --- 361 362def COp : NS_Op<"c_op", []> { 363 let arguments = (ins 364 DefaultValuedOptionalAttr<I32ArrayAttr, "{1, 2}">:$i32_array_attr, 365 DefaultValuedOptionalAttr<I64ArrayAttr, "{3, 4}">:$i64_array_attr, 366 DefaultValuedOptionalAttr<F32ArrayAttr, "{5.f, 6.f}">:$f32_array_attr, 367 DefaultValuedOptionalAttr<F64ArrayAttr, "{7., 8.}">:$f64_array_attr, 368 DefaultValuedOptionalAttr<StrArrayAttr, "{\"a\", \"b\"}">:$str_array_attr 369 ); 370} 371 372// DEF-LABEL: COp definitions 373// DEF: ::mlir::Builder((*this)->getContext()).getI32ArrayAttr({1, 2}) 374// DEF: ::mlir::Builder((*this)->getContext()).getI64ArrayAttr({3, 4}) 375// DEF: ::mlir::Builder((*this)->getContext()).getF32ArrayAttr({5.f, 6.f}) 376// DEF: ::mlir::Builder((*this)->getContext()).getF64ArrayAttr({7., 8.}) 377// DEF: ::mlir::Builder((*this)->getContext()).getStrArrayAttr({"a", "b"}) 378 379 380// Test builder method which takes unwrapped values for attributes 381// --- 382 383def I32Case5: I32EnumAttrCase<"case5", 5>; 384def I32Case10: I32EnumAttrCase<"case10", 10>; 385 386def SomeI32Enum: I32EnumAttr< 387 "SomeI32Enum", "", [I32Case5, I32Case10]>; 388 389def DOp : NS_Op<"d_op", []> { 390 let arguments = (ins 391 I32Attr:$i32_attr, 392 F64Attr:$f64_attr, 393 StrAttr:$str_attr, 394 BoolAttr:$bool_attr, 395 SomeI32Enum:$enum_attr, 396 DefaultValuedAttr<I32Attr, "42">:$dv_i32_attr, 397 DefaultValuedAttr<F64Attr, "8.">:$dv_f64_attr, 398 DefaultValuedStrAttr<StrAttr, "abc">:$dv_str_attr, 399 DefaultValuedAttr<BoolAttr, "true">:$dv_bool_attr, 400 DefaultValuedAttr<SomeI32Enum, "::SomeI32Enum::case5">:$dv_enum_attr 401 ); 402} 403 404// DECL-LABEL: DOp declarations 405// DECL: static void build({{.*}}, uint32_t i32_attr, ::llvm::APFloat f64_attr, ::llvm::StringRef str_attr, bool bool_attr, ::SomeI32Enum enum_attr, uint32_t dv_i32_attr, ::llvm::APFloat dv_f64_attr, ::llvm::StringRef dv_str_attr = "abc", bool dv_bool_attr = true, ::SomeI32Enum dv_enum_attr = ::SomeI32Enum::case5) 406 407// DEF-LABEL: DOp definitions 408// DEF: odsState.addAttribute(getStrAttrAttrName(odsState.name), odsBuilder.getStringAttr(str_attr)); 409// DEF: odsState.addAttribute(getDvStrAttrAttrName(odsState.name), odsBuilder.getStringAttr(dv_str_attr)); 410 411 412// Test default dictionary attribute. 413// --- 414 415def DefaultDictAttrOp : NS_Op<"default_dict_attr_op", []> { 416 let arguments = (ins 417 DefaultValuedAttr<DictionaryAttr, "{}">:$empty, 418 DefaultValuedAttr<DictionaryAttr, "getDefaultDictAttrs($_builder)">:$non_empty 419 ); 420} 421 422// DEF-LABEL: DefaultDictAttrOp definitions 423// DEF: if (!attributes.get(attrNames[0])) 424// DEF: attributes.append(attrNames[0], odsBuilder.getDictionaryAttr({})); 425// DEF: if (!attributes.get(attrNames[1])) 426// DEF: attributes.append(attrNames[1], odsBuilder.getDictionaryAttr(getDefaultDictAttrs(odsBuilder))); 427 428// DECL-LABEL: DefaultDictAttrOp declarations 429// DECL: build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::DictionaryAttr empty = nullptr, ::mlir::DictionaryAttr non_empty = nullptr) 430 431 432// Test derived type attr. 433// --- 434def DerivedTypeAttrOp : NS_Op<"derived_type_attr_op", []> { 435 let results = (outs AnyTensor:$output); 436 DerivedTypeAttr element_dtype = DerivedTypeAttr<"return output().getType();">; 437} 438 439// DECL: class DerivedTypeAttrOp : public ::mlir::Op 440// DECL-SAME: DerivedAttributeOpInterface::Trait 441// DECL: static bool isDerivedAttribute 442// DEF: bool DerivedTypeAttrOp::isDerivedAttribute(::llvm::StringRef name) { 443// DEF: if (name == "element_dtype") return true; 444// DEF: return false; 445// DEF: } 446// DEF: DerivedTypeAttrOp::materializeDerivedAttributes 447 448// Test that only default valued attributes at the end of the arguments 449// list get default values in the builder signature 450// --- 451 452def EOp : NS_Op<"e_op", []> { 453 let arguments = (ins 454 I32Attr:$i32_attr, 455 DefaultValuedAttr<I32Attr, "42">:$dv_i32_attr, 456 F64Attr:$f64_attr, 457 DefaultValuedAttr<F64Attr, "8.">:$dv_f64_attr, 458 StrAttr:$str_attr, 459 DefaultValuedStrAttr<StrAttr, "abc">:$dv_str_attr, 460 BoolAttr:$bool_attr, 461 DefaultValuedAttr<BoolAttr, "true">:$dv_bool_attr, 462 SomeI32Enum:$enum_attr, 463 DefaultValuedAttr<SomeI32Enum, "::SomeI32Enum::case5">:$dv_enum_attr 464 ); 465} 466 467// DECL-LABEL: EOp declarations 468// DECL: static void build({{.*}}, uint32_t i32_attr, uint32_t dv_i32_attr, ::llvm::APFloat f64_attr, ::llvm::APFloat dv_f64_attr, ::llvm::StringRef str_attr, ::llvm::StringRef dv_str_attr, bool bool_attr, bool dv_bool_attr, ::SomeI32Enum enum_attr, ::SomeI32Enum dv_enum_attr = ::SomeI32Enum::case5) 469 470 471// Test proper namespacing for AttrDef 472// --- 473 474def NamespaceOp : NS_Op<"namespace_op", []> { 475 let arguments = (ins 476 SomeAttrDef:$AttrDef 477 ); 478} 479 480// Test mixing operands and attributes in arbitrary order 481// --- 482 483def MixOperandsAndAttrs : NS_Op<"mix_operands_and_attrs", []> { 484 let arguments = (ins F32Attr:$attr, F32:$operand, F32Attr:$otherAttr, F32:$otherArg); 485} 486 487// DECL-LABEL: MixOperandsAndAttrs declarations 488// DECL-DAG: ::mlir::TypedValue<::mlir::FloatType> getOperand() 489// DECL-DAG: ::mlir::TypedValue<::mlir::FloatType> getOtherArg() 490 491// DECL-LABEL: NamespaceOp declarations 492// DECL: foobar::SomeAttrAttr getAttrDef() 493 494 495def OpWithDefaultAndRegion : NS_Op<"default_with_region", []> { 496 let arguments = (ins 497 DefaultValuedAttr<BoolAttr, "true">:$dv_bool_attr 498 ); 499 let regions = (region VariadicRegion<AnyRegion>:$region); 500} 501 502// We should not have a default attribute in this case. 503 504// DECL-LABEL: OpWithDefaultAndRegion declarations 505// DECL: static void build({{.*}}, bool dv_bool_attr, unsigned regionCount) 506 507def OpWithDefaultAndSuccessor : NS_Op<"default_with_succ", []> { 508 let arguments = (ins 509 DefaultValuedAttr<BoolAttr, "true">:$dv_bool_attr 510 ); 511 let successors = (successor VariadicSuccessor<AnySuccessor>:$succ); 512} 513 514// We should not have a default attribute in this case. 515 516// DECL-LABEL: OpWithDefaultAndSuccessor declarations 517// DECL-DAG: static void build({{.*}}, bool dv_bool_attr, ::mlir::BlockRange succ) 518 519// DEF-LABEL: MixOperandsAndAttrs definitions 520// DEF-DAG: void MixOperandsAndAttrs::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::FloatAttr attr, ::mlir::Value operand, ::mlir::FloatAttr otherAttr, ::mlir::Value otherArg) 521// DEF-DAG: ::llvm::APFloat MixOperandsAndAttrs::getAttr() 522// DEF-DAG: ::llvm::APFloat MixOperandsAndAttrs::getOtherAttr() 523 524// Test unit attributes. 525// --- 526 527def UnitAttrOp : NS_Op<"unit_attr_op", []> { 528 let arguments = (ins UnitAttr:$attr); 529} 530 531// DEF-LABEL: UnitAttrOp definitions 532// DEF: bool UnitAttrOp::getAttr() { 533// DEF: return {{.*}} != nullptr 534 535 536// DEF: build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, /*optional*/::mlir::UnitAttr attr) 537// DEF: build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, /*optional*/bool attr) 538 539// DECL-LABEL: UnitAttrOp declarations 540// DECL: ::mlir::Attribute removeAttrAttr() { 541// DECL-NEXT: (*this)->removeAttr(getAttrAttrName()); 542// DECL: build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, /*optional*/bool attr = false) 543 544 545// Test elementAttr field of TypedArrayAttr. 546// --- 547 548def SomeTypedArrayAttr : TypedArrayAttrBase<SomeAttr, "SomeAttr array">; 549 550// RECORD-LABEL: def SomeTypedArrayAttr 551// RECORD: Attr elementAttr = SomeAttr; 552