[mlir][OpFormatGen] Add support for optional enum attributes

The check for formatting enum attributes was missing a call to get the base attribute, which is necessary to strip off the top-level OptionalAttr<> wrapper.

Differential Revision: https://reviews.llvm.org/D92713
This commit is contained in:
River Riddle 2020-12-04 20:54:23 -08:00
parent 24333481cb
commit 7924fb34f3
4 changed files with 21 additions and 5 deletions

View File

@ -1350,7 +1350,7 @@ llvm.func @useInlineAsm(%arg0: !llvm.i32) {
%3 = llvm.inline_asm is_align_stack "foo", "=r,r,r" %arg0, %arg0 : (!llvm.i32, !llvm.i32) -> !llvm.i8
// CHECK-NEXT: call i8 asm inteldialect "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}}), !dbg !13
%4 = llvm.inline_asm asm_dialect = 1 "foo", "=r,r,r" %arg0, %arg0 : (!llvm.i32, !llvm.i32) -> !llvm.i8
%4 = llvm.inline_asm asm_dialect = "intel" "foo", "=r,r,r" %arg0, %arg0 : (!llvm.i32, !llvm.i32) -> !llvm.i8
// CHECK-NEXT: call { i8, i8 } asm "foo", "=r,=r,r"(i32 {{.*}}), !dbg !14
%5 = llvm.inline_asm "foo", "=r,=r,r" %arg0 : (!llvm.i32) -> !llvm.struct<(i8, i8)>

View File

@ -1592,6 +1592,11 @@ def FormatOptionalUnitAttrNoElide
let assemblyFormat = "($is_optional^)? attr-dict";
}
def FormatOptionalEnumAttr : TEST_Op<"format_optional_enum_attr"> {
let arguments = (ins OptionalAttr<SomeI64Enum>:$attr);
let assemblyFormat = "($attr^)? attr-dict";
}
//===----------------------------------------------------------------------===//
// Custom Directives

View File

@ -185,6 +185,13 @@ test.format_optional_unit_attribute
// CHECK: test.format_optional_unit_attribute_no_elide unit
test.format_optional_unit_attribute_no_elide unit
// CHECK: test.format_optional_enum_attr "case5"
test.format_optional_enum_attr "case5"
// CHECK: test.format_optional_enum_attr
// CHECK-NOT: "case5"
test.format_optional_enum_attr
//===----------------------------------------------------------------------===//
// Format optional operands and results
//===----------------------------------------------------------------------===//

View File

@ -462,7 +462,8 @@ struct OperationFormat {
/// Returns true if we can format the given attribute as an EnumAttr in the
/// parser format.
static bool canFormatEnumAttr(const NamedAttribute *attr) {
const EnumAttr *enumAttr = dyn_cast<EnumAttr>(&attr->attr);
Attribute baseAttr = attr->attr.getBaseAttr();
const EnumAttr *enumAttr = dyn_cast<EnumAttr>(&baseAttr);
if (!enumAttr)
return false;
@ -1107,7 +1108,8 @@ void OperationFormat::genElementParser(Element *element, OpMethodBody &body,
// Check to see if we can parse this as an enum attribute.
if (canFormatEnumAttr(var)) {
const EnumAttr &enumAttr = cast<EnumAttr>(var->attr);
Attribute baseAttr = var->attr.getBaseAttr();
const EnumAttr &enumAttr = cast<EnumAttr>(baseAttr);
// Generate the code for building an attribute for this enum.
std::string attrBuilderStr;
@ -1682,9 +1684,11 @@ void OperationFormat::genElementPrinter(Element *element, OpMethodBody &body,
// If we are formatting as an enum, symbolize the attribute as a string.
if (canFormatEnumAttr(var)) {
const EnumAttr &enumAttr = cast<EnumAttr>(var->attr);
Attribute baseAttr = var->attr.getBaseAttr();
const EnumAttr &enumAttr = cast<EnumAttr>(baseAttr);
body << " p << '\"' << " << enumAttr.getSymbolToStringFnName() << "("
<< var->name << "()) << '\"';\n";
<< (var->attr.isOptional() ? "*" : "") << var->name
<< "()) << '\"';\n";
return;
}