[Mlir-commits] [flang] [mlir] [MLIR][ODS] Print prop-dict fields with custom printers (PR #217589)
Mehdi Amini
llvmlistbot at llvm.org
Tue Aug 25 15:53:45 PDT 2026
https://github.com/joker-eph updated https://github.com/llvm/llvm-project/pull/217589
>From 4b690d4f93e31245564e443af32b8b641e637e72 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Wed, 19 Aug 2026 09:04:44 -0700
Subject: [PATCH] [MLIR][ODS] Print prop-dict fields with custom printers
Generate a key-value prop-dict printer that dispatches each field to its ODS
printer while retaining attribute conversion for non-compositional default
parsers.
Keep operation-specific property printer hooks ahead of the generated
implementation and preserve legacy input compatibility.
Update the OpenACC cache checks for the generated custom property spelling.
Assisted-by: Codex
---
flang/test/Lower/OpenACC/acc-cache.f90 | 6 +-
mlir/docs/DefiningDialects/Operations.md | 5 +-
mlir/include/mlir/Dialect/LLVMIR/XeVMOps.td | 2 +
.../include/mlir/Dialect/XeGPU/IR/XeGPUOps.td | 2 +
mlir/include/mlir/IR/OpBase.td | 5 +
mlir/include/mlir/IR/OpDefinition.h | 22 ++-
mlir/include/mlir/TableGen/Operator.h | 3 +
mlir/lib/TableGen/Operator.cpp | 4 +
.../Conversion/AMDGPUToROCDL/dot-gfx11.mlir | 6 +-
.../Conversion/AMDGPUToROCDL/dot-gfx9.mlir | 6 +-
.../Conversion/AMDGPUToROCDL/wmma-gfx11.mlir | 12 +-
.../Conversion/AMDGPUToROCDL/wmma-gfx12.mlir | 12 +-
.../AMDGPUToROCDL/wmma-gfx1250.mlir | 2 +-
.../Conversion/GPUToROCDL/gpu-to-rocdl.mlir | 4 +-
.../memref-to-emitc-alloc-copy.mlir | 8 +-
.../memref-to-emitc-alloc-dealloc.mlir | 16 +-
.../memref-to-emitc-alloc-load-store.mlir | 8 +-
.../MemRefToEmitC/memref-to-emitc-copy.mlir | 2 +-
.../memref-with-custom-types.mlir | 3 +-
.../Dialect/EmitC/member_call_opaque.mlir | 4 +-
mlir/test/Dialect/LLVMIR/rocdl.mlir | 28 ++--
mlir/test/Dialect/OpenACC/ops-cg.mlir | 6 +-
mlir/test/Dialect/OpenACC/ops.mlir | 14 +-
mlir/test/IR/enum-attr-roundtrip.mlir | 8 +-
mlir/test/IR/properties.mlir | 38 +++--
mlir/test/Target/LLVMIR/Import/intrinsic.ll | 2 +-
mlir/test/lib/Dialect/Test/TestOps.td | 28 ++++
.../op-format-custom-properties-printer.td | 32 ++++
mlir/test/mlir-tblgen/op-format.mlir | 12 +-
mlir/tools/mlir-tblgen/OpFormatGen.cpp | 138 +++++++++++++++++-
30 files changed, 335 insertions(+), 103 deletions(-)
create mode 100644 mlir/test/mlir-tblgen/op-format-custom-properties-printer.td
diff --git a/flang/test/Lower/OpenACC/acc-cache.f90 b/flang/test/Lower/OpenACC/acc-cache.f90
index d8273c745cc64..2205936b457ce 100644
--- a/flang/test/Lower/OpenACC/acc-cache.f90
+++ b/flang/test/Lower/OpenACC/acc-cache.f90
@@ -41,7 +41,7 @@ subroutine test_cache_readonly()
end do
! CHECK: acc.loop
-! CHECK: %[[CACHE:.*]] = acc.cache varPtr(%{{.*}} : !fir.ref<!fir.array<10xf32>>) structured(false) name("b") <{modifiers = #acc<data_clause_modifier readonly>}> -> !fir.ref<!fir.array<10xf32>>
+! CHECK: %[[CACHE:.*]] = acc.cache varPtr(%{{.*}} : !fir.ref<!fir.array<10xf32>>) structured(false) name("b") <modifiers = readonly> -> !fir.ref<!fir.array<10xf32>>
! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[CACHE]](%{{.*}}) {uniq_name = "_QFtest_cache_readonlyEb"}
! Loop body uses the cached readonly reference
! CHECK: %[[ELEM:.*]] = hlfir.designate %[[DECL]]#0 (%{{.*}}) : (!fir.ref<!fir.array<10xf32>>, i64) -> !fir.ref<f32>
@@ -605,7 +605,7 @@ subroutine test_cache_derived_type_readonly()
! CHECK: acc.loop
! CHECK: %[[ARRAY_COORD:.*]] = hlfir.designate %{{.*}}{"array"} shape %{{.*}} : (!fir.ref<!fir.type<_QFtest_cache_derived_type_readonlyTdt{array:!fir.array<100xf32>}>>, !fir.shape<1>) -> !fir.ref<!fir.array<100xf32>>
! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%{{.*}} : index) startIdx(%{{.*}} : index)
-! CHECK: %[[CACHE:.*]] = acc.cache varPtr(%[[ARRAY_COORD]] : !fir.ref<!fir.array<100xf32>>) bounds(%[[BOUND]]) structured(false) name("data%array(i-4_4:i+4_4)") <{modifiers = #acc<data_clause_modifier readonly>}> -> !fir.ref<!fir.array<100xf32>>
+! CHECK: %[[CACHE:.*]] = acc.cache varPtr(%[[ARRAY_COORD]] : !fir.ref<!fir.array<100xf32>>) bounds(%[[BOUND]]) structured(false) name("data%array(i-4_4:i+4_4)") <modifiers = readonly> -> !fir.ref<!fir.array<100xf32>>
! CHECK: acc.yield
end subroutine
@@ -761,7 +761,7 @@ subroutine test_cache_temp_in_designator(data, a)
! CHECK: %[[ELEMENTAL:.*]] = hlfir.elemental
! CHECK: %[[MAXLOC:.*]] = hlfir.maxloc %[[ELEMENTAL]]
! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound({{.*}}) upperbound({{.*}})
-! CHECK: %[[CACHE:.*]] = acc.cache varPtr(%{{.*}}) bounds(%[[BOUND]]) structured(false) name("data(1:maxloc(a+a,dim=1_4))") <{modifiers = #acc<data_clause_modifier readonly>}> -> !fir.ref<!fir.array<100xf32>>
+! CHECK: %[[CACHE:.*]] = acc.cache varPtr(%{{.*}}) bounds(%[[BOUND]]) structured(false) name("data(1:maxloc(a+a,dim=1_4))") <modifiers = readonly> -> !fir.ref<!fir.array<100xf32>>
! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[CACHE]]
! CHECK: hlfir.destroy %[[ELEMENTAL]]
! CHECK: hlfir.designate %[[DECL]]#0
diff --git a/mlir/docs/DefiningDialects/Operations.md b/mlir/docs/DefiningDialects/Operations.md
index 75ddd92492642..ee427d45c3780 100644
--- a/mlir/docs/DefiningDialects/Operations.md
+++ b/mlir/docs/DefiningDialects/Operations.md
@@ -768,7 +768,10 @@ The available directives are as follows:
`FieldParser` specialization is available or when the selected
specialization declares `isKeyValueCompositional = false`.
- The legacy `<{key = attribute, ...}>` dictionary spelling is also
- accepted when parsing and is used by the generated printer.
+ accepted when parsing. The generated printer uses the key-value
+ spelling and the same custom-printer or attribute-conversion choice.
+ Operations that provide a custom `printProperties` hook should set
+ `hasCustomPropertiesPrinter` to suppress the shadowed generated helper.
- Any property or inherent attribute that is not used elsewhere in the
format is parsed and printed as part of this list.
- If present, the `attr-dict` will not contain any inherent attributes.
diff --git a/mlir/include/mlir/Dialect/LLVMIR/XeVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/XeVMOps.td
index 10a78d3866655..65e35aa6163d1 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/XeVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/XeVMOps.td
@@ -48,6 +48,8 @@ class XeVM_Attr<string attrName, string attrMnemonic, list<Trait> traits = []>
class XeVM_Op<string mnemonic, list<Trait> traits = []>
: LLVM_OpBase<XeVM_Dialect, mnemonic, traits> {
+ let hasCustomPropertiesPrinter = 1;
+
code extraBaseClassDeclaration = [{
void printProperties(::mlir::MLIRContext *ctx,
::mlir::OpAsmPrinter &p, const Properties &prop,
diff --git a/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUOps.td b/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUOps.td
index d1d337699671b..cb39e25142c46 100644
--- a/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUOps.td
+++ b/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUOps.td
@@ -26,6 +26,8 @@ include "mlir/Interfaces/ViewLikeInterface.td"
class XeGPU_Op<string mnemonic, list<Trait> traits = []>:
Op<XeGPU_Dialect, mnemonic, traits> {
+ let hasCustomPropertiesPrinter = 1;
+
code extraBaseClassDeclaration = [{
void printProperties(::mlir::MLIRContext *ctx,
::mlir::OpAsmPrinter &p, const Properties &prop,
diff --git a/mlir/include/mlir/IR/OpBase.td b/mlir/include/mlir/IR/OpBase.td
index 0d0669e90c3f7..a130d5847a1c7 100644
--- a/mlir/include/mlir/IR/OpBase.td
+++ b/mlir/include/mlir/IR/OpBase.td
@@ -408,6 +408,11 @@ class Op<Dialect dialect, string mnemonic, list<Trait> props = []> {
/// * void print(OpAsmPrinter &p)
bit hasCustomAssemblyFormat = 0;
+ /// This field indicates that the operation provides a custom
+ /// `printProperties` hook. Setting it avoids generating the default
+ /// per-field `prop-dict` printer that the hook would shadow.
+ bit hasCustomPropertiesPrinter = 0;
+
// A bit indicating if the operation has additional invariants that need to
// verified (aside from those verified by other ODS constructs). If set to `1`,
// an additional `LogicalResult verify()` declaration will be generated on the
diff --git a/mlir/include/mlir/IR/OpDefinition.h b/mlir/include/mlir/IR/OpDefinition.h
index 075d39194ed97..d92a93746bf54 100644
--- a/mlir/include/mlir/IR/OpDefinition.h
+++ b/mlir/include/mlir/IR/OpDefinition.h
@@ -1864,6 +1864,18 @@ class Op : public OpState, public Traits<ConcreteType>... {
using detect_has_print_properties =
llvm::is_detected<has_print_properties, T>;
+ /// Trait to check if T provides a generated printer for the key-value
+ /// spelling of `prop-dict`.
+ template <typename T, typename... Args>
+ using has_print_properties_as_key_value_list =
+ decltype(T::_odsPrintPropertiesAsKeyValueList(
+ std::declval<MLIRContext *>(), std::declval<OpAsmPrinter &>(),
+ std::declval<const typename PropertiesSelector<T>::type &>(),
+ std::declval<ArrayRef<StringRef>>()));
+ template <typename T>
+ using detect_has_print_properties_as_key_value_list =
+ llvm::is_detected<has_print_properties_as_key_value_list, T>;
+
/// Trait to check if parseProperties(OpAsmParser, T) exist
template <typename T, typename... Args>
using has_parse_properties = decltype(parseProperties(
@@ -2036,15 +2048,19 @@ class Op : public OpState, public Traits<ConcreteType>... {
InferredProperties<T> &properties) {}
/// Print the operation properties with names not included within
- /// 'elidedProps'. Unless overridden, this method will try to dispatch to a
- /// `printProperties` free-function if it exists, and otherwise by converting
- /// the properties to an Attribute.
+ /// 'elidedProps'. Unless overridden, this method first tries to dispatch to a
+ /// `printProperties` free-function, then to the generated per-field printer,
+ /// and finally converts the properties to an Attribute.
template <typename T>
static void printProperties(MLIRContext *ctx, OpAsmPrinter &p,
const T &properties,
ArrayRef<StringRef> elidedProps = {}) {
if constexpr (detect_has_print_properties<T>::value)
return printProperties(p, properties, elidedProps);
+ if constexpr (detect_has_print_properties_as_key_value_list<
+ ConcreteType>::value)
+ return ConcreteType::_odsPrintPropertiesAsKeyValueList(ctx, p, properties,
+ elidedProps);
genericPrintProperties(
p, ConcreteType::getPropertiesAsAttr(ctx, properties), elidedProps);
}
diff --git a/mlir/include/mlir/TableGen/Operator.h b/mlir/include/mlir/TableGen/Operator.h
index f0514d8e61748..4c0ba2a1db9ec 100644
--- a/mlir/include/mlir/TableGen/Operator.h
+++ b/mlir/include/mlir/TableGen/Operator.h
@@ -143,6 +143,9 @@ class Operator {
/// Returns true if default builders should not be generated.
bool skipDefaultBuilders() const;
+ /// Returns true if the operation provides a custom properties printer.
+ bool hasCustomPropertiesPrinter() const;
+
/// Op result iterators.
const_value_iterator result_begin() const;
const_value_iterator result_end() const;
diff --git a/mlir/lib/TableGen/Operator.cpp b/mlir/lib/TableGen/Operator.cpp
index 82dfbcbfa4d4f..148c3408b707d 100644
--- a/mlir/lib/TableGen/Operator.cpp
+++ b/mlir/lib/TableGen/Operator.cpp
@@ -186,6 +186,10 @@ bool Operator::skipDefaultBuilders() const {
return def.getValueAsBit("skipDefaultBuilders");
}
+bool Operator::hasCustomPropertiesPrinter() const {
+ return def.getValueAsBit("hasCustomPropertiesPrinter");
+}
+
auto Operator::result_begin() const -> const_value_iterator {
return results.begin();
}
diff --git a/mlir/test/Conversion/AMDGPUToROCDL/dot-gfx11.mlir b/mlir/test/Conversion/AMDGPUToROCDL/dot-gfx11.mlir
index 02d8525e15977..a87227884dc2a 100644
--- a/mlir/test/Conversion/AMDGPUToROCDL/dot-gfx11.mlir
+++ b/mlir/test/Conversion/AMDGPUToROCDL/dot-gfx11.mlir
@@ -32,21 +32,21 @@ func.func @dot_sdot4_gfx11_uniform_sign(%a: vector<4xi8>, %b: vector<4xi8>, %c:
// CHECK-LABEL: @dot_sudot4_signA_unsignedB
func.func @dot_sudot4_signA_unsignedB(%a: vector<4xi8>, %b: vector<4xi8>, %c: i32) -> i32 {
- // CHECK: rocdl.sudot4 %{{.+}}, %{{.+}}, %{{.+}} <{signA = true}> : (i32, i32, i32) -> i32
+ // CHECK: rocdl.sudot4 %{{.+}}, %{{.+}}, %{{.+}} <signA = true> : (i32, i32, i32) -> i32
%r = amdgpu.dot %a * %b + %c unsignedB : vector<4xi8>, vector<4xi8>, i32
func.return %r : i32
}
// CHECK-LABEL: @dot_sudot4_unsignedA_signB_clamp
func.func @dot_sudot4_unsignedA_signB_clamp(%a: vector<4xi8>, %b: vector<4xi8>, %c: i32) -> i32 {
- // CHECK: rocdl.sudot4 %{{.+}}, %{{.+}}, %{{.+}} <{clamp = true, signB = true}> : (i32, i32, i32) -> i32
+ // CHECK: rocdl.sudot4 %{{.+}}, %{{.+}}, %{{.+}} <signB = true, clamp = true> : (i32, i32, i32) -> i32
%r = amdgpu.dot %a * %b + %c unsignedA clamp : vector<4xi8>, vector<4xi8>, i32
func.return %r : i32
}
// CHECK-LABEL: @dot_sudot8
func.func @dot_sudot8(%a: vector<8xi4>, %b: vector<8xi4>, %c: i32) -> i32 {
- // CHECK: rocdl.sudot8 %{{.+}}, %{{.+}}, %{{.+}} <{signA = true}> : (i32, i32, i32) -> i32
+ // CHECK: rocdl.sudot8 %{{.+}}, %{{.+}}, %{{.+}} <signA = true> : (i32, i32, i32) -> i32
%r = amdgpu.dot %a * %b + %c unsignedB : vector<8xi4>, vector<8xi4>, i32
func.return %r : i32
}
diff --git a/mlir/test/Conversion/AMDGPUToROCDL/dot-gfx9.mlir b/mlir/test/Conversion/AMDGPUToROCDL/dot-gfx9.mlir
index d2c5b26a8d50d..e13a9976974dc 100644
--- a/mlir/test/Conversion/AMDGPUToROCDL/dot-gfx9.mlir
+++ b/mlir/test/Conversion/AMDGPUToROCDL/dot-gfx9.mlir
@@ -9,7 +9,7 @@ func.func @dot_fdot2(%a: vector<2xf16>, %b: vector<2xf16>, %c: f32) -> f32 {
// CHECK-LABEL: @dot_fdot2_clamp
func.func @dot_fdot2_clamp(%a: vector<2xf16>, %b: vector<2xf16>, %c: f32) -> f32 {
- // CHECK: rocdl.fdot2 %{{.+}}, %{{.+}}, %{{.+}} <{clamp = true}> : (vector<2xf16>, vector<2xf16>, f32) -> f32
+ // CHECK: rocdl.fdot2 %{{.+}}, %{{.+}}, %{{.+}} <clamp = true> : (vector<2xf16>, vector<2xf16>, f32) -> f32
%r = amdgpu.dot %a * %b + %c clamp : vector<2xf16>, vector<2xf16>, f32
func.return %r : f32
}
@@ -23,7 +23,7 @@ func.func @dot_sdot2(%a: vector<2xi16>, %b: vector<2xi16>, %c: i32) -> i32 {
// CHECK-LABEL: @dot_udot2_clamp
func.func @dot_udot2_clamp(%a: vector<2xi16>, %b: vector<2xi16>, %c: i32) -> i32 {
- // CHECK: rocdl.udot2 %{{.+}}, %{{.+}}, %{{.+}} <{clamp = true}> : (vector<2xi16>, vector<2xi16>, i32) -> i32
+ // CHECK: rocdl.udot2 %{{.+}}, %{{.+}}, %{{.+}} <clamp = true> : (vector<2xi16>, vector<2xi16>, i32) -> i32
%r = amdgpu.dot %a * %b + %c unsignedA unsignedB clamp : vector<2xi16>, vector<2xi16>, i32
func.return %r : i32
}
@@ -39,7 +39,7 @@ func.func @dot_sdot4(%a: vector<4xi8>, %b: vector<4xi8>, %c: i32) -> i32 {
// CHECK-LABEL: @dot_udot4_clamp
func.func @dot_udot4_clamp(%a: vector<4xi8>, %b: vector<4xi8>, %c: i32) -> i32 {
- // CHECK: rocdl.udot4 %{{.+}}, %{{.+}}, %{{.+}} <{clamp = true}> : (i32, i32, i32) -> i32
+ // CHECK: rocdl.udot4 %{{.+}}, %{{.+}}, %{{.+}} <clamp = true> : (i32, i32, i32) -> i32
%r = amdgpu.dot %a * %b + %c unsignedA unsignedB clamp : vector<4xi8>, vector<4xi8>, i32
func.return %r : i32
}
diff --git a/mlir/test/Conversion/AMDGPUToROCDL/wmma-gfx11.mlir b/mlir/test/Conversion/AMDGPUToROCDL/wmma-gfx11.mlir
index 95bb88b02b4cd..08fd68dfe158d 100644
--- a/mlir/test/Conversion/AMDGPUToROCDL/wmma-gfx11.mlir
+++ b/mlir/test/Conversion/AMDGPUToROCDL/wmma-gfx11.mlir
@@ -13,23 +13,23 @@ func.func @wmma_to_rocdl(%arg0 : vector<16xf16>, %arg1 : vector<8xf32>, %arg2 :
amdgpu.wmma 16x16x16 %arg3 * %arg3 + %arg1 : vector<16xbf16>, vector<16xbf16>, vector<8xf32>
// CHECK: rocdl.wmma.f32.16x16x16.bf16{{.*}}: (vector<16xi16>, vector<16xi16>, vector<4xf32>) -> vector<4xf32>
amdgpu.wmma 16x16x16 %arg3 * %arg3 + %arg2 : vector<16xbf16>, vector<16xbf16>, vector<4xf32>
- // CHECK: rocdl.wmma.f16.16x16x16.f16 {{.*}} <{opsel = true}> : (vector<16xf16>, vector<16xf16>, vector<16xf16>) -> vector<16xf16>
+ // CHECK: rocdl.wmma.f16.16x16x16.f16 {{.*}} <opsel = true> : (vector<16xf16>, vector<16xf16>, vector<16xf16>) -> vector<16xf16>
amdgpu.wmma 16x16x16 %arg0 * %arg0 + %arg0 subwordOffset(1) : vector<16xf16>, vector<16xf16>, vector<16xf16>
// CHECK: rocdl.wmma.f16.16x16x16.f16 {{.*}} : (vector<16xf16>, vector<16xf16>, vector<8xf16>) -> vector<8xf16>
amdgpu.wmma 16x16x16 %arg0 * %arg0 + %arg4 : vector<16xf16>, vector<16xf16>, vector<8xf16>
- // CHECK: %[[raw_bf16x16:.+]] = rocdl.wmma.bf16.16x16x16.bf16 {{.*}} <{opsel = true}> : (vector<16xi16>, vector<16xi16>, vector<16xi16>) -> vector<16xi16>
+ // CHECK: %[[raw_bf16x16:.+]] = rocdl.wmma.bf16.16x16x16.bf16 {{.*}} <opsel = true> : (vector<16xi16>, vector<16xi16>, vector<16xi16>) -> vector<16xi16>
// CHECK-NEXT: llvm.bitcast %[[raw_bf16x16]] : vector<16xi16> to vector<16xbf16>
amdgpu.wmma 16x16x16 %arg3 * %arg3 + %arg3 subwordOffset(1) : vector<16xbf16>, vector<16xbf16>, vector<16xbf16>
// CHECK: %[[raw_bf16x8:.+]] = rocdl.wmma.bf16.16x16x16.bf16 {{.*}} : (vector<16xi16>, vector<16xi16>, vector<8xi16>) -> vector<8xi16>
// CHECK-NEXT: llvm.bitcast %[[raw_bf16x8]] : vector<8xi16> to vector<8xbf16>
amdgpu.wmma 16x16x16 %arg3 * %arg3 + %arg5 : vector<16xbf16>, vector<16xbf16>, vector<8xbf16>
- // CHECK: rocdl.wmma.i32.16x16x16.iu8{{.*}} <{clamp = true, signA = true, signB = true}> : (vector<4xi32>, vector<4xi32>, vector<8xi32>) -> vector<8xi32>
+ // CHECK: rocdl.wmma.i32.16x16x16.iu8{{.*}} <signA = true, signB = true, clamp = true> : (vector<4xi32>, vector<4xi32>, vector<8xi32>) -> vector<8xi32>
amdgpu.wmma 16x16x16 %arg6 * %arg6 + %arg7 clamp : vector<16xi8>, vector<16xi8>, vector<8xi32>
- // CHECK: rocdl.wmma.i32.16x16x16.iu8{{.*}} <{clamp = true}> : (vector<4xi32>, vector<4xi32>, vector<4xi32>) -> vector<4xi32>
+ // CHECK: rocdl.wmma.i32.16x16x16.iu8{{.*}} <clamp = true> : (vector<4xi32>, vector<4xi32>, vector<4xi32>) -> vector<4xi32>
amdgpu.wmma 16x16x16 %arg9 * %arg9 + %arg8 unsignedA unsignedB clamp : vector<16xui8>, vector<16xui8>, vector<4xi32>
- // CHECK: rocdl.wmma.i32.16x16x16.iu4{{.*}} <{clamp = true, signA = true, signB = true}> : (vector<2xi32>, vector<2xi32>, vector<8xi32>) -> vector<8xi32>
+ // CHECK: rocdl.wmma.i32.16x16x16.iu4{{.*}} <signA = true, signB = true, clamp = true> : (vector<2xi32>, vector<2xi32>, vector<8xi32>) -> vector<8xi32>
amdgpu.wmma 16x16x16 %arg10 * %arg10 + %arg7 clamp : vector<16xi4>, vector<16xi4>, vector<8xi32>
- // CHECK: rocdl.wmma.i32.16x16x16.iu4{{.*}} <{clamp = true, signA = true, signB = true}> : (i32, i32, vector<4xi32>) -> vector<4xi32>
+ // CHECK: rocdl.wmma.i32.16x16x16.iu4{{.*}} <signA = true, signB = true, clamp = true> : (i32, i32, vector<4xi32>) -> vector<4xi32>
amdgpu.wmma 16x16x16 %arg11 * %arg11 + %arg8 clamp : vector<8xi4>, vector<8xi4>, vector<4xi32>
return
diff --git a/mlir/test/Conversion/AMDGPUToROCDL/wmma-gfx12.mlir b/mlir/test/Conversion/AMDGPUToROCDL/wmma-gfx12.mlir
index 5de44882eff11..1dac83946fc4c 100644
--- a/mlir/test/Conversion/AMDGPUToROCDL/wmma-gfx12.mlir
+++ b/mlir/test/Conversion/AMDGPUToROCDL/wmma-gfx12.mlir
@@ -51,19 +51,19 @@ func.func @wmma_to_rocdl(%arg0 : vector<8xf16>, %arg1 : vector<4xf16>,
// CHECK: rocdl.wmma.f32.16x16x16.bf8_fp8{{.*}}: (i32, i32, vector<4xf32>) -> vector<4xf32>
amdgpu.wmma 16x16x16 %arg9 * %arg7 + %arg3 : vector<4xf8E5M2>, vector<4xf8E4M3FN>, vector<4xf32>
- // CHECK: rocdl.wmma.i32.16x16x16.iu8{{.*}} <{clamp = true, signA = true, signB = true}> : (vector<2xi32>, vector<2xi32>, vector<8xi32>) -> vector<8xi32>
+ // CHECK: rocdl.wmma.i32.16x16x16.iu8{{.*}} <signA = true, signB = true, clamp = true> : (vector<2xi32>, vector<2xi32>, vector<8xi32>) -> vector<8xi32>
amdgpu.wmma 16x16x16 %arg10 * %arg10 + %arg12 clamp : vector<8xi8>, vector<8xi8>, vector<8xi32>
- // CHECK: rocdl.wmma.i32.16x16x16.iu8{{.*}} <{clamp = true}> : (i32, i32, vector<4xi32>) -> vector<4xi32>
+ // CHECK: rocdl.wmma.i32.16x16x16.iu8{{.*}} <clamp = true> : (i32, i32, vector<4xi32>) -> vector<4xi32>
amdgpu.wmma 16x16x16 %arg11 * %arg11 + %arg13 unsignedA unsignedB clamp : vector<4xi8>, vector<4xi8>, vector<4xi32>
- // CHECK: rocdl.wmma.i32.16x16x32.iu4{{.*}} <{clamp = true, signA = true, signB = true}> : (vector<2xi32>, vector<2xi32>, vector<8xi32>) -> vector<8xi32>
+ // CHECK: rocdl.wmma.i32.16x16x32.iu4{{.*}} <signA = true, signB = true, clamp = true> : (vector<2xi32>, vector<2xi32>, vector<8xi32>) -> vector<8xi32>
amdgpu.wmma 16x16x32 %arg14 * %arg14 + %arg12 clamp : vector<16xi4>, vector<16xi4>, vector<8xi32>
- // CHECK: rocdl.wmma.i32.16x16x32.iu4{{.*}} <{clamp = true, signA = true, signB = true}> : (i32, i32, vector<4xi32>) -> vector<4xi32>
+ // CHECK: rocdl.wmma.i32.16x16x32.iu4{{.*}} <signA = true, signB = true, clamp = true> : (i32, i32, vector<4xi32>) -> vector<4xi32>
amdgpu.wmma 16x16x32 %arg15 * %arg15 + %arg13 clamp : vector<8xi4>, vector<8xi4>, vector<4xi32>
- // CHECK: rocdl.wmma.i32.16x16x16.iu4{{.*}} <{clamp = true, signA = true, signB = true}> : (i32, i32, vector<8xi32>) -> vector<8xi32>
+ // CHECK: rocdl.wmma.i32.16x16x16.iu4{{.*}} <signA = true, signB = true, clamp = true> : (i32, i32, vector<8xi32>) -> vector<8xi32>
amdgpu.wmma 16x16x16 %arg15 * %arg15 + %arg12 clamp : vector<8xi4>, vector<8xi4>, vector<8xi32>
- // CHECK: rocdl.wmma.i32.16x16x16.iu4{{.*}} <{clamp = true, signA = true, signB = true}> : (i32, i32, vector<4xi32>) -> vector<4xi32>
+ // CHECK: rocdl.wmma.i32.16x16x16.iu4{{.*}} <signA = true, signB = true, clamp = true> : (i32, i32, vector<4xi32>) -> vector<4xi32>
amdgpu.wmma 16x16x16 %arg16 * %arg16 + %arg13 clamp : vector<4xi4>, vector<4xi4>, vector<4xi32>
func.return
diff --git a/mlir/test/Conversion/AMDGPUToROCDL/wmma-gfx1250.mlir b/mlir/test/Conversion/AMDGPUToROCDL/wmma-gfx1250.mlir
index 5744d520f68e0..7f9605ad1a7eb 100644
--- a/mlir/test/Conversion/AMDGPUToROCDL/wmma-gfx1250.mlir
+++ b/mlir/test/Conversion/AMDGPUToROCDL/wmma-gfx1250.mlir
@@ -29,7 +29,7 @@ func.func @wmma_k32(%arg0 : vector<16xf16>, %arg1 : vector<16xbf16>, %arg2 : vec
// CHECK-LABEL: @wmma_k64
func.func @wmma_k64(%arg0 : vector<32xi8>, %arg1 : vector<32xf8E4M3FN>, %arg2 : vector<32xf8E5M2>,
%arg3 : vector<8xi32>, %arg4 : vector<8xf32>, %arg5 : vector<8xf16>) {
- // CHECK: rocdl.wmma.i32.16x16x64.iu8 {{.*}}, {{.*}}, %arg3 <{clamp = true, signA = true, signB = true}>
+ // CHECK: rocdl.wmma.i32.16x16x64.iu8 {{.*}}, {{.*}}, %arg3 <signA = true, signB = true, clamp = true>
amdgpu.wmma 16x16x64 %arg0 * %arg0 + %arg3 clamp : vector<32xi8>, vector<32xi8>, vector<8xi32>
// CHECK: rocdl.wmma.f32.16x16x64.fp8_fp8 {{.*}}, {{.*}}, %arg4
diff --git a/mlir/test/Conversion/GPUToROCDL/gpu-to-rocdl.mlir b/mlir/test/Conversion/GPUToROCDL/gpu-to-rocdl.mlir
index 2126463a6a444..c01af31e9d4f1 100755
--- a/mlir/test/Conversion/GPUToROCDL/gpu-to-rocdl.mlir
+++ b/mlir/test/Conversion/GPUToROCDL/gpu-to-rocdl.mlir
@@ -54,8 +54,8 @@ gpu.module @test_module {
// CHECK-DAG: llvm.call @__ockl_get_num_groups(%[[GD_C2]]) : (i32) -> i64
%gDimZ = gpu.grid_dim z
- // CHECK: = rocdl.mbcnt.lo %{{.*}}, %{{.*}} <{res_attrs = [{llvm.noundef, llvm.range = #llvm.constant_range<i32, 0, 32>}]}> : (i32, i32) -> i32
- // CHECK: = rocdl.mbcnt.hi %{{.*}}, %{{.*}} <{res_attrs = [{llvm.noundef, llvm.range = #llvm.constant_range<i32, 0, 64>}]}> : (i32, i32) -> i32
+ // CHECK: = rocdl.mbcnt.lo %{{.*}}, %{{.*}} <res_attrs = [{llvm.noundef, llvm.range = #llvm.constant_range<i32, 0, 32>}]> : (i32, i32) -> i32
+ // CHECK: = rocdl.mbcnt.hi %{{.*}}, %{{.*}} <res_attrs = [{llvm.noundef, llvm.range = #llvm.constant_range<i32, 0, 64>}]> : (i32, i32) -> i32
// CHECK: = llvm.sext %{{.*}} : i32 to i64
%laneId = gpu.lane_id
diff --git a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-alloc-copy.mlir b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-alloc-copy.mlir
index be0b9baf502bc..8f5b93bffe27e 100644
--- a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-alloc-copy.mlir
+++ b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-alloc-copy.mlir
@@ -18,7 +18,7 @@ func.func @alloc_copy(%arg0: memref<999xi32>) {
// CHECK-LABEL: func.func @alloc_copy(
// CHECK-SAME: %[[ARG0:.*]]: memref<999xi32>) {
// CHECK: %[[UNREALIZED_CONVERSION_CAST_0:.*]] = builtin.unrealized_conversion_cast %[[ARG0]] : memref<999xi32> to !emitc.array<999xi32>
-// CHECK: %[[CALL_OPAQUE_0:.*]] = emitc.call_opaque "sizeof"() <{args = [i32]}> : () -> !emitc.size_t
+// CHECK: %[[CALL_OPAQUE_0:.*]] = emitc.call_opaque "sizeof"() <args = [i32]> : () -> !emitc.size_t
// CHECK: %[[VAL_0:.*]] = "emitc.constant"() <{value = 999 : index}> : () -> index
// CHECK: %[[MUL_0:.*]] = emitc.mul %[[CALL_OPAQUE_0]], %[[VAL_0]] : (!emitc.size_t, index) -> !emitc.size_t
// CHECK: %[[CALL_OPAQUE_1:.*]] = emitc.call_opaque "malloc"(%[[MUL_0]]) : (!emitc.size_t) -> !emitc.ptr<!emitc.opaque<"void">>
@@ -30,11 +30,11 @@ func.func @alloc_copy(%arg0: memref<999xi32>) {
// CHECK: %[[VAL_2:.*]] = "emitc.constant"() <{value = 0 : index}> : () -> index
// CHECK: %[[SUBSCRIPT_1:.*]] = emitc.subscript %[[UNREALIZED_CONVERSION_CAST_1]]{{\[}}%[[VAL_2]]] : (!emitc.array<999xi32>, index) -> !emitc.lvalue<i32>
// CHECK: %[[ADDRESS_OF_1:.*]] = emitc.address_of %[[SUBSCRIPT_1]] : !emitc.lvalue<i32>
-// CHECK: %[[CALL_OPAQUE_2:.*]] = emitc.call_opaque "sizeof"() <{args = [i32]}> : () -> !emitc.size_t
+// CHECK: %[[CALL_OPAQUE_2:.*]] = emitc.call_opaque "sizeof"() <args = [i32]> : () -> !emitc.size_t
// CHECK: %[[VAL_3:.*]] = "emitc.constant"() <{value = 999 : index}> : () -> index
// CHECK: %[[MUL_1:.*]] = emitc.mul %[[CALL_OPAQUE_2]], %[[VAL_3]] : (!emitc.size_t, index) -> !emitc.size_t
// CHECK: emitc.call_opaque "memcpy"(%[[ADDRESS_OF_1]], %[[ADDRESS_OF_0]], %[[MUL_1]]) : (!emitc.ptr<i32>, !emitc.ptr<i32>, !emitc.size_t) -> ()
-// CHECK: %[[CALL_OPAQUE_3:.*]] = emitc.call_opaque "sizeof"() <{args = [i32]}> : () -> !emitc.size_t
+// CHECK: %[[CALL_OPAQUE_3:.*]] = emitc.call_opaque "sizeof"() <args = [i32]> : () -> !emitc.size_t
// CHECK: %[[VAL_4:.*]] = "emitc.constant"() <{value = 999 : index}> : () -> index
// CHECK: %[[MUL_2:.*]] = emitc.mul %[[CALL_OPAQUE_3]], %[[VAL_4]] : (!emitc.size_t, index) -> !emitc.size_t
// CHECK: %[[CALL_OPAQUE_4:.*]] = emitc.call_opaque "malloc"(%[[MUL_2]]) : (!emitc.size_t) -> !emitc.ptr<!emitc.opaque<"void">>
@@ -46,7 +46,7 @@ func.func @alloc_copy(%arg0: memref<999xi32>) {
// CHECK: %[[VAL_6:.*]] = "emitc.constant"() <{value = 0 : index}> : () -> index
// CHECK: %[[SUBSCRIPT_3:.*]] = emitc.subscript %[[UNREALIZED_CONVERSION_CAST_2]]{{\[}}%[[VAL_6]]] : (!emitc.array<999xi32>, index) -> !emitc.lvalue<i32>
// CHECK: %[[ADDRESS_OF_3:.*]] = emitc.address_of %[[SUBSCRIPT_3]] : !emitc.lvalue<i32>
-// CHECK: %[[CALL_OPAQUE_5:.*]] = emitc.call_opaque "sizeof"() <{args = [i32]}> : () -> !emitc.size_t
+// CHECK: %[[CALL_OPAQUE_5:.*]] = emitc.call_opaque "sizeof"() <args = [i32]> : () -> !emitc.size_t
// CHECK: %[[VAL_7:.*]] = "emitc.constant"() <{value = 999 : index}> : () -> index
// CHECK: %[[MUL_3:.*]] = emitc.mul %[[CALL_OPAQUE_5]], %[[VAL_7]] : (!emitc.size_t, index) -> !emitc.size_t
// CHECK: emitc.call_opaque "memcpy"(%[[ADDRESS_OF_3]], %[[ADDRESS_OF_2]], %[[MUL_3]]) : (!emitc.ptr<i32>, !emitc.ptr<i32>, !emitc.size_t) -> ()
diff --git a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-alloc-dealloc.mlir b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-alloc-dealloc.mlir
index 7f8b3a02d04e4..5cdcfd6408469 100644
--- a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-alloc-dealloc.mlir
+++ b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-alloc-dealloc.mlir
@@ -15,7 +15,7 @@ func.func @alloc_and_dealloc() {
// CPP: module {
// CPP-NEXT: emitc.include <"cstdlib">
// CPP-LABEL: alloc_and_dealloc()
-// CPP-NEXT: %[[ALLOC:.*]] = emitc.call_opaque "sizeof"() <{args = [i32]}> : () -> !emitc.size_t
+// CPP-NEXT: %[[ALLOC:.*]] = emitc.call_opaque "sizeof"() <args = [i32]> : () -> !emitc.size_t
// CPP-NEXT: %[[ALLOC_SIZE:.*]] = "emitc.constant"() <{value = 999 : index}> : () -> index
// CPP-NEXT: %[[ALLOC_TOTAL_SIZE:.*]] = emitc.mul %[[ALLOC]], %[[ALLOC_SIZE]] : (!emitc.size_t, index) -> !emitc.size_t
// CPP-NEXT: %[[ALLOC_PTR:.*]] = emitc.call_opaque "malloc"(%[[ALLOC_TOTAL_SIZE]]) : (!emitc.size_t) -> !emitc.ptr<!emitc.opaque<"void">>
@@ -27,7 +27,7 @@ func.func @alloc_and_dealloc() {
// NOCPP: module {
// NOCPP-NEXT: emitc.include <"stdlib.h">
// NOCPP-LABEL: alloc_and_dealloc()
-// NOCPP-NEXT: %[[ALLOC:.*]] = emitc.call_opaque "sizeof"() <{args = [i32]}> : () -> !emitc.size_t
+// NOCPP-NEXT: %[[ALLOC:.*]] = emitc.call_opaque "sizeof"() <args = [i32]> : () -> !emitc.size_t
// NOCPP-NEXT: %[[ALLOC_SIZE:.*]] = "emitc.constant"() <{value = 999 : index}> : () -> index
// NOCPP-NEXT: %[[ALLOC_TOTAL_SIZE:.*]] = emitc.mul %[[ALLOC]], %[[ALLOC_SIZE]] : (!emitc.size_t, index) -> !emitc.size_t
// NOCPP-NEXT: %[[ALLOC_PTR:.*]] = emitc.call_opaque "malloc"(%[[ALLOC_TOTAL_SIZE]]) : (!emitc.size_t) -> !emitc.ptr<!emitc.opaque<"void">>
@@ -43,7 +43,7 @@ func.func @alloc_and_dealloc_aligned() {
}
// CPP-LABEL: alloc_and_dealloc_aligned
-// CPP-NEXT: %[[ALLOC:.*]] = emitc.call_opaque "sizeof"() <{args = [f32]}> : () -> !emitc.size_t
+// CPP-NEXT: %[[ALLOC:.*]] = emitc.call_opaque "sizeof"() <args = [f32]> : () -> !emitc.size_t
// CPP-NEXT: %[[ALLOC_SIZE:.*]] = "emitc.constant"() <{value = 999 : index}> : () -> index
// CPP-NEXT: %[[ALLOC_TOTAL_SIZE:.*]] = emitc.mul %[[ALLOC]], %[[ALLOC_SIZE]] : (!emitc.size_t, index) -> !emitc.size_t
// CPP-NEXT: %[[ALIGNMENT:.*]] = "emitc.constant"() <{value = 64 : index}> : () -> !emitc.size_t
@@ -54,7 +54,7 @@ func.func @alloc_and_dealloc_aligned() {
// CPP-NEXT: return
// NOCPP-LABEL: alloc_and_dealloc_aligned
-// NOCPP-NEXT: %[[ALLOC:.*]] = emitc.call_opaque "sizeof"() <{args = [f32]}> : () -> !emitc.size_t
+// NOCPP-NEXT: %[[ALLOC:.*]] = emitc.call_opaque "sizeof"() <args = [f32]> : () -> !emitc.size_t
// NOCPP-NEXT: %[[ALLOC_SIZE:.*]] = "emitc.constant"() <{value = 999 : index}> : () -> index
// NOCPP-NEXT: %[[ALLOC_TOTAL_SIZE:.*]] = emitc.mul %[[ALLOC]], %[[ALLOC_SIZE]] : (!emitc.size_t, index) -> !emitc.size_t
// NOCPP-NEXT: %[[ALIGNMENT:.*]] = "emitc.constant"() <{value = 64 : index}> : () -> !emitc.size_t
@@ -71,7 +71,7 @@ func.func @allocating_and_deallocating_multi() {
}
// CPP-LABEL: allocating_and_deallocating_multi
-// CPP-NEXT: %[[ALLOC:.*]] = emitc.call_opaque "sizeof"() <{args = [i32]}> : () -> !emitc.size_t
+// CPP-NEXT: %[[ALLOC:.*]] = emitc.call_opaque "sizeof"() <args = [i32]> : () -> !emitc.size_t
// CPP-NEXT: %[[ALLOC_SIZE:.*]] = "emitc.constant"() <{value = 6993 : index}> : () -> index
// CPP-NEXT: %[[ALLOC_TOTAL_SIZE:.*]] = emitc.mul %[[ALLOC]], %[[ALLOC_SIZE]] : (!emitc.size_t, index) -> !emitc.size_t
// CPP-NEXT: %[[ALLOC_PTR:.*]] = emitc.call_opaque "malloc"(%[[ALLOC_TOTAL_SIZE]]) : (!emitc.size_t) -> !emitc.ptr<!emitc.opaque<"void">
@@ -81,7 +81,7 @@ func.func @allocating_and_deallocating_multi() {
// CPP-NEXT: return
// NOCPP-LABEL: allocating_and_deallocating_multi
-// NOCPP-NEXT: %[[ALLOC:.*]] = emitc.call_opaque "sizeof"() <{args = [i32]}> : () -> !emitc.size_t
+// NOCPP-NEXT: %[[ALLOC:.*]] = emitc.call_opaque "sizeof"() <args = [i32]> : () -> !emitc.size_t
// NOCPP-NEXT: %[[ALLOC_SIZE:.*]] = "emitc.constant"() <{value = 6993 : index}> : () -> index
// NOCPP-NEXT: %[[ALLOC_TOTAL_SIZE:.*]] = emitc.mul %[[ALLOC]], %[[ALLOC_SIZE]] : (!emitc.size_t, index) -> !emitc.size_t
// NOCPP-NEXT: %[[ALLOC_PTR:.*]] = emitc.call_opaque "malloc"(%[[ALLOC_TOTAL_SIZE]]) : (!emitc.size_t) -> !emitc.ptr<!emitc.opaque<"void">>
@@ -97,7 +97,7 @@ func.func @alloc_and_dealloc_rank0() {
}
// CPP-LABEL: alloc_and_dealloc_rank0
-// CPP-NEXT: %[[ALLOC:.*]] = emitc.call_opaque "sizeof"() <{args = [i32]}> : () -> !emitc.size_t
+// CPP-NEXT: %[[ALLOC:.*]] = emitc.call_opaque "sizeof"() <args = [i32]> : () -> !emitc.size_t
// CPP-NEXT: %[[ALLOC_SIZE:.*]] = "emitc.constant"() <{value = 1 : index}> : () -> index
// CPP-NEXT: %[[ALLOC_TOTAL_SIZE:.*]] = emitc.mul %[[ALLOC]], %[[ALLOC_SIZE]] : (!emitc.size_t, index) -> !emitc.size_t
// CPP-NEXT: %[[ALLOC_PTR:.*]] = emitc.call_opaque "malloc"(%[[ALLOC_TOTAL_SIZE]]) : (!emitc.size_t) -> !emitc.ptr<!emitc.opaque<"void">>
@@ -107,7 +107,7 @@ func.func @alloc_and_dealloc_rank0() {
// CPP-NEXT: return
// NOCPP-LABEL: alloc_and_dealloc_rank0
-// NOCPP-NEXT: %[[ALLOC:.*]] = emitc.call_opaque "sizeof"() <{args = [i32]}> : () -> !emitc.size_t
+// NOCPP-NEXT: %[[ALLOC:.*]] = emitc.call_opaque "sizeof"() <args = [i32]> : () -> !emitc.size_t
// NOCPP-NEXT: %[[ALLOC_SIZE:.*]] = "emitc.constant"() <{value = 1 : index}> : () -> index
// NOCPP-NEXT: %[[ALLOC_TOTAL_SIZE:.*]] = emitc.mul %[[ALLOC]], %[[ALLOC_SIZE]] : (!emitc.size_t, index) -> !emitc.size_t
// NOCPP-NEXT: %[[ALLOC_PTR:.*]] = emitc.call_opaque "malloc"(%[[ALLOC_TOTAL_SIZE]]) : (!emitc.size_t) -> !emitc.ptr<!emitc.opaque<"void">>
diff --git a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-alloc-load-store.mlir b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-alloc-load-store.mlir
index 653220470bb5a..43c5733baccb3 100644
--- a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-alloc-load-store.mlir
+++ b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-alloc-load-store.mlir
@@ -21,7 +21,7 @@
// CHECK-SAME: %[[ARG_J:.*]]: !emitc.size_t)
func.func private @memref_alloc_store(%v : f32, %i: index, %j: index) {
/// Allocation size computation
- // CHECK: %[[SIZEOF_F32:.*]] = call_opaque "sizeof"() <{args = [f32]}> : () -> !emitc.size_t
+ // CHECK: %[[SIZEOF_F32:.*]] = call_opaque "sizeof"() <args = [f32]> : () -> !emitc.size_t
// CHECK: %[[NUM_ELEMS:.*]] = "emitc.constant"() <{value = 32 : index}> : () -> index
// CHECK: %[[TOTAL_BYTES:.*]] = mul %[[SIZEOF_F32]], %[[NUM_ELEMS]] : (!emitc.size_t, index) -> !emitc.size_t
/// Alloc
@@ -42,7 +42,7 @@ func.func private @memref_alloc_store(%v : f32, %i: index, %j: index) {
// CHECK-SAME: %[[ARG_I:.*]]: !emitc.size_t,
// CHECK-SAME: %[[ARG_J:.*]]: !emitc.size_t) -> f32
func.func private @memref_alloc_load(%i: index, %j: index) -> f32 {
- // CHECK: %[[SIZEOF_F32:.*]] = call_opaque "sizeof"() <{args = [f32]}> : () -> !emitc.size_t
+ // CHECK: %[[SIZEOF_F32:.*]] = call_opaque "sizeof"() <args = [f32]> : () -> !emitc.size_t
// CHECK: %[[NUM_ELEMS:.*]] = "emitc.constant"() <{value = 32 : index}> : () -> index
// CHECK: %[[TOTAL_BYTES:.*]] = mul %[[SIZEOF_F32]], %[[NUM_ELEMS]] : (!emitc.size_t, index) -> !emitc.size_t
// CHECK: %[[MALLOC_PTR:.*]] = call_opaque "malloc"(%[[TOTAL_BYTES]]) : (!emitc.size_t) -> !emitc.ptr<!emitc.opaque<"void">>
@@ -77,7 +77,7 @@ func.func @memref_load_store(%buff0: memref<2xf32>,
// CHECK-LABEL: emitc.func private @memref_alloc_store_rank0(
// CHECK-SAME: %[[VAL:.*]]: i32)
func.func private @memref_alloc_store_rank0(%v : i32) {
- // CHECK: %[[SIZEOF_I32:.*]] = call_opaque "sizeof"() <{args = [i32]}> : () -> !emitc.size_t
+ // CHECK: %[[SIZEOF_I32:.*]] = call_opaque "sizeof"() <args = [i32]> : () -> !emitc.size_t
// CHECK: %[[NUM_ELEMS:.*]] = "emitc.constant"() <{value = 1 : index}> : () -> index
// CHECK: %[[TOTAL_BYTES:.*]] = mul %[[SIZEOF_I32]], %[[NUM_ELEMS]] : (!emitc.size_t, index) -> !emitc.size_t
// CHECK: %[[MALLOC_PTR:.*]] = call_opaque "malloc"(%[[TOTAL_BYTES]]) : (!emitc.size_t) -> !emitc.ptr<!emitc.opaque<"void">>
@@ -92,7 +92,7 @@ func.func private @memref_alloc_store_rank0(%v : i32) {
// CHECK-LABEL: emitc.func private @memref_alloc_load_rank0() -> i32
func.func private @memref_alloc_load_rank0() -> i32 {
- // CHECK: %[[SIZEOF_I32:.*]] = call_opaque "sizeof"() <{args = [i32]}> : () -> !emitc.size_t
+ // CHECK: %[[SIZEOF_I32:.*]] = call_opaque "sizeof"() <args = [i32]> : () -> !emitc.size_t
// CHECK: %[[NUM_ELEMS:.*]] = "emitc.constant"() <{value = 1 : index}> : () -> index
// CHECK: %[[TOTAL_BYTES:.*]] = mul %[[SIZEOF_I32]], %[[NUM_ELEMS]] : (!emitc.size_t, index) -> !emitc.size_t
// CHECK: %[[MALLOC_PTR:.*]] = call_opaque "malloc"(%[[TOTAL_BYTES]]) : (!emitc.size_t) -> !emitc.ptr<!emitc.opaque<"void">>
diff --git a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-copy.mlir b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-copy.mlir
index 6105521d9326d..828aa68ea9f1c 100644
--- a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-copy.mlir
+++ b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-copy.mlir
@@ -21,7 +21,7 @@ func.func @copying(%arg0 : memref<9x4x5x7xf32>, %arg1 : memref<9x4x5x7xf32>) {
// CHECK: %[[VAL_1:.*]] = "emitc.constant"() <{value = 0 : index}> : () -> index
// CHECK: %[[SUBSCRIPT_1:.*]] = emitc.subscript %[[UNREALIZED_CONVERSION_CAST_0]]{{\[}}%[[VAL_1]], %[[VAL_1]], %[[VAL_1]], %[[VAL_1]]] : (!emitc.array<9x4x5x7xf32>, index, index, index, index) -> !emitc.lvalue<f32>
// CHECK: %[[ADDRESS_OF_1:.*]] = emitc.address_of %[[SUBSCRIPT_1]] : !emitc.lvalue<f32>
-// CHECK: %[[CALL_OPAQUE_0:.*]] = emitc.call_opaque "sizeof"() <{args = [f32]}> : () -> !emitc.size_t
+// CHECK: %[[CALL_OPAQUE_0:.*]] = emitc.call_opaque "sizeof"() <args = [f32]> : () -> !emitc.size_t
// CHECK: %[[VAL_2:.*]] = "emitc.constant"() <{value = 1260 : index}> : () -> index
// CHECK: %[[MUL_0:.*]] = emitc.mul %[[CALL_OPAQUE_0]], %[[VAL_2]] : (!emitc.size_t, index) -> !emitc.size_t
// CHECK: emitc.call_opaque "memcpy"(%[[ADDRESS_OF_1]], %[[ADDRESS_OF_0]], %[[MUL_0]]) : (!emitc.ptr<f32>, !emitc.ptr<f32>, !emitc.size_t) -> ()
diff --git a/mlir/test/Conversion/MemRefToEmitC/memref-with-custom-types.mlir b/mlir/test/Conversion/MemRefToEmitC/memref-with-custom-types.mlir
index 4cc874633d456..bdb41baa4f743 100644
--- a/mlir/test/Conversion/MemRefToEmitC/memref-with-custom-types.mlir
+++ b/mlir/test/Conversion/MemRefToEmitC/memref-with-custom-types.mlir
@@ -5,7 +5,7 @@
// CHECK-LABEL: emitc.func @alloc_with_custom_element_type()
func.func @alloc_with_custom_element_type() {
- // CHECK: call_opaque "sizeof"() <{args = [!emitc.opaque<"TestElementT">]}> : () -> !emitc.size_t
+ // CHECK: call_opaque "sizeof"() <args = [!emitc.opaque<"TestElementT">]> : () -> !emitc.size_t
// CHECK: cast
// CHECK-SAME: !emitc.ptr<!emitc.opaque<"void">> to !emitc.ptr<!emitc.opaque<"TestElementT">>
%0 = memref.alloc() : memref<10x!test.memref_element>
@@ -43,4 +43,3 @@ func.func @load_with_custom_element_type(%i: index) -> !test.memref_element {
%v = memref.load %alloc[%i] : memref<4x!test.memref_element>
return %v : !test.memref_element
}
-
diff --git a/mlir/test/Dialect/EmitC/member_call_opaque.mlir b/mlir/test/Dialect/EmitC/member_call_opaque.mlir
index 5971d7826b270..bc4e0d55ddb48 100644
--- a/mlir/test/Dialect/EmitC/member_call_opaque.mlir
+++ b/mlir/test/Dialect/EmitC/member_call_opaque.mlir
@@ -19,14 +19,14 @@ func.func @member_call_template_args(%arg0 : !emitc.opaque<"MyClass">) {
return
}
// CHECK-LABEL: func @member_call_template_args
-// CHECK: emitc.member_call_opaque %arg0 "method"() <{template_args = [i32]}> : !emitc.opaque<"MyClass">, () -> i32
+// CHECK: emitc.member_call_opaque %arg0 "method"() <template_args = [i32]> : !emitc.opaque<"MyClass">, () -> i32
func.func @member_call_reorder(%arg0 : !emitc.opaque<"MyClass">, %arg1 : i32, %arg2 : i32) {
%0 = emitc.member_call_opaque %arg0 "method" (%arg1, %arg2) <{args = [1 : index, 0 : index]}> : !emitc.opaque<"MyClass">, (i32, i32) -> i32
return
}
// CHECK-LABEL: func @member_call_reorder
-// CHECK: emitc.member_call_opaque %arg0 "method"(%arg1, %arg2) <{args = [1 : index, 0 : index]}> : !emitc.opaque<"MyClass">, (i32, i32) -> i32
+// CHECK: emitc.member_call_opaque %arg0 "method"(%arg1, %arg2) <args = [1 : index, 0 : index]> : !emitc.opaque<"MyClass">, (i32, i32) -> i32
func.func @member_call_lvalue_arg(%arg0 : !emitc.opaque<"MyClass">, %arg1 : !emitc.lvalue<i32>) {
%0 = emitc.member_call_opaque %arg0 "method" (%arg1) : !emitc.opaque<"MyClass">, (!emitc.lvalue<i32>) -> i32
diff --git a/mlir/test/Dialect/LLVMIR/rocdl.mlir b/mlir/test/Dialect/LLVMIR/rocdl.mlir
index 67af5afc29b60..6075e68eb8b75 100644
--- a/mlir/test/Dialect/LLVMIR/rocdl.mlir
+++ b/mlir/test/Dialect/LLVMIR/rocdl.mlir
@@ -1737,12 +1737,12 @@ llvm.func @rocdl_dot_fdot2_family(%v2f16: vector<2xf16>, %v2bf16: vector<2xbf16>
%f16: f16, %bf16: bf16, %f32: f32) -> f32 {
// CHECK: rocdl.fdot2 %{{.*}}, %{{.*}}, %{{.*}} : (vector<2xf16>, vector<2xf16>, f32) -> f32
%r0 = rocdl.fdot2 %v2f16, %v2f16, %f32 : (vector<2xf16>, vector<2xf16>, f32) -> f32
- // CHECK: rocdl.fdot2 %{{.*}}, %{{.*}}, %{{.*}} <{clamp = true}> : (vector<2xf16>, vector<2xf16>, f32) -> f32
+ // CHECK: rocdl.fdot2 %{{.*}}, %{{.*}}, %{{.*}} <clamp = true> : (vector<2xf16>, vector<2xf16>, f32) -> f32
%r0c = rocdl.fdot2 %v2f16, %v2f16, %f32 <{clamp = true}> : (vector<2xf16>, vector<2xf16>, f32) -> f32
// CHECK: rocdl.fdot2.f32.bf16 %{{.*}}, %{{.*}}, %{{.*}} : (vector<2xbf16>, vector<2xbf16>, f32) -> f32
%r1 = rocdl.fdot2.f32.bf16 %v2bf16, %v2bf16, %f32 : (vector<2xbf16>, vector<2xbf16>, f32) -> f32
- // CHECK: rocdl.fdot2.f32.bf16 %{{.*}}, %{{.*}}, %{{.*}} <{clamp = true}> : (vector<2xbf16>, vector<2xbf16>, f32) -> f32
+ // CHECK: rocdl.fdot2.f32.bf16 %{{.*}}, %{{.*}}, %{{.*}} <clamp = true> : (vector<2xbf16>, vector<2xbf16>, f32) -> f32
%r1c = rocdl.fdot2.f32.bf16 %v2bf16, %v2bf16, %f32 <{clamp = true}> : (vector<2xbf16>, vector<2xbf16>, f32) -> f32
// CHECK: rocdl.fdot2.f16.f16 %{{.*}}, %{{.*}}, %{{.*}} : (vector<2xf16>, vector<2xf16>, f16) -> f16
@@ -1760,32 +1760,32 @@ llvm.func @rocdl_dot_fdot2_family(%v2f16: vector<2xf16>, %v2bf16: vector<2xbf16>
llvm.func @rocdl_dot_sdot_udot_family(%v2i16: vector<2xi16>, %i32: i32) -> i32 {
// CHECK: rocdl.sdot2 %{{.*}}, %{{.*}}, %{{.*}} : (vector<2xi16>, vector<2xi16>, i32) -> i32
%r0 = rocdl.sdot2 %v2i16, %v2i16, %i32 : (vector<2xi16>, vector<2xi16>, i32) -> i32
- // CHECK: rocdl.sdot2 %{{.*}}, %{{.*}}, %{{.*}} <{clamp = true}> : (vector<2xi16>, vector<2xi16>, i32) -> i32
+ // CHECK: rocdl.sdot2 %{{.*}}, %{{.*}}, %{{.*}} <clamp = true> : (vector<2xi16>, vector<2xi16>, i32) -> i32
%r0c = rocdl.sdot2 %v2i16, %v2i16, %i32 <{clamp = true}> : (vector<2xi16>, vector<2xi16>, i32) -> i32
// CHECK: rocdl.udot2 %{{.*}}, %{{.*}}, %{{.*}} : (vector<2xi16>, vector<2xi16>, i32) -> i32
%r1 = rocdl.udot2 %v2i16, %v2i16, %i32 : (vector<2xi16>, vector<2xi16>, i32) -> i32
- // CHECK: rocdl.udot2 %{{.*}}, %{{.*}}, %{{.*}} <{clamp = true}> : (vector<2xi16>, vector<2xi16>, i32) -> i32
+ // CHECK: rocdl.udot2 %{{.*}}, %{{.*}}, %{{.*}} <clamp = true> : (vector<2xi16>, vector<2xi16>, i32) -> i32
%r1c = rocdl.udot2 %v2i16, %v2i16, %i32 <{clamp = true}> : (vector<2xi16>, vector<2xi16>, i32) -> i32
// CHECK: rocdl.sdot4 %{{.*}}, %{{.*}}, %{{.*}} : (i32, i32, i32) -> i32
%r2 = rocdl.sdot4 %i32, %i32, %i32 : (i32, i32, i32) -> i32
- // CHECK: rocdl.sdot4 %{{.*}}, %{{.*}}, %{{.*}} <{clamp = true}> : (i32, i32, i32) -> i32
+ // CHECK: rocdl.sdot4 %{{.*}}, %{{.*}}, %{{.*}} <clamp = true> : (i32, i32, i32) -> i32
%r2c = rocdl.sdot4 %i32, %i32, %i32 <{clamp = true}> : (i32, i32, i32) -> i32
// CHECK: rocdl.udot4 %{{.*}}, %{{.*}}, %{{.*}} : (i32, i32, i32) -> i32
%r3 = rocdl.udot4 %i32, %i32, %i32 : (i32, i32, i32) -> i32
- // CHECK: rocdl.udot4 %{{.*}}, %{{.*}}, %{{.*}} <{clamp = true}> : (i32, i32, i32) -> i32
+ // CHECK: rocdl.udot4 %{{.*}}, %{{.*}}, %{{.*}} <clamp = true> : (i32, i32, i32) -> i32
%r3c = rocdl.udot4 %i32, %i32, %i32 <{clamp = true}> : (i32, i32, i32) -> i32
// CHECK: rocdl.sdot8 %{{.*}}, %{{.*}}, %{{.*}} : (i32, i32, i32) -> i32
%r4 = rocdl.sdot8 %i32, %i32, %i32 : (i32, i32, i32) -> i32
- // CHECK: rocdl.sdot8 %{{.*}}, %{{.*}}, %{{.*}} <{clamp = true}> : (i32, i32, i32) -> i32
+ // CHECK: rocdl.sdot8 %{{.*}}, %{{.*}}, %{{.*}} <clamp = true> : (i32, i32, i32) -> i32
%r4c = rocdl.sdot8 %i32, %i32, %i32 <{clamp = true}> : (i32, i32, i32) -> i32
// CHECK: rocdl.udot8 %{{.*}}, %{{.*}}, %{{.*}} : (i32, i32, i32) -> i32
%r5 = rocdl.udot8 %i32, %i32, %i32 : (i32, i32, i32) -> i32
- // CHECK: rocdl.udot8 %{{.*}}, %{{.*}}, %{{.*}} <{clamp = true}> : (i32, i32, i32) -> i32
+ // CHECK: rocdl.udot8 %{{.*}}, %{{.*}}, %{{.*}} <clamp = true> : (i32, i32, i32) -> i32
%r5c = rocdl.udot8 %i32, %i32, %i32 <{clamp = true}> : (i32, i32, i32) -> i32
llvm.return %r0 : i32
@@ -1797,20 +1797,20 @@ llvm.func @rocdl_dot_sdot_udot_family(%v2i16: vector<2xi16>, %i32: i32) -> i32 {
llvm.func @rocdl_dot_sudot_family(%i32: i32) -> i32 {
// CHECK: rocdl.sudot4 %{{.*}}, %{{.*}}, %{{.*}} : (i32, i32, i32) -> i32
%r0 = rocdl.sudot4 %i32, %i32, %i32 : (i32, i32, i32) -> i32
- // CHECK: rocdl.sudot4 %{{.*}}, %{{.*}}, %{{.*}} <{signA = true}> : (i32, i32, i32) -> i32
+ // CHECK: rocdl.sudot4 %{{.*}}, %{{.*}}, %{{.*}} <signA = true> : (i32, i32, i32) -> i32
%r0a = rocdl.sudot4 %i32, %i32, %i32 <{signA = true}> : (i32, i32, i32) -> i32
- // CHECK: rocdl.sudot4 %{{.*}}, %{{.*}}, %{{.*}} <{signB = true}> : (i32, i32, i32) -> i32
+ // CHECK: rocdl.sudot4 %{{.*}}, %{{.*}}, %{{.*}} <signB = true> : (i32, i32, i32) -> i32
%r0b = rocdl.sudot4 %i32, %i32, %i32 <{signB = true}> : (i32, i32, i32) -> i32
- // CHECK: rocdl.sudot4 %{{.*}}, %{{.*}}, %{{.*}} <{clamp = true, signA = true, signB = true}> : (i32, i32, i32) -> i32
+ // CHECK: rocdl.sudot4 %{{.*}}, %{{.*}}, %{{.*}} <signA = true, signB = true, clamp = true> : (i32, i32, i32) -> i32
%r0c = rocdl.sudot4 %i32, %i32, %i32 <{clamp = true, signA = true, signB = true}> : (i32, i32, i32) -> i32
// CHECK: rocdl.sudot8 %{{.*}}, %{{.*}}, %{{.*}} : (i32, i32, i32) -> i32
%r1 = rocdl.sudot8 %i32, %i32, %i32 : (i32, i32, i32) -> i32
- // CHECK: rocdl.sudot8 %{{.*}}, %{{.*}}, %{{.*}} <{signA = true}> : (i32, i32, i32) -> i32
+ // CHECK: rocdl.sudot8 %{{.*}}, %{{.*}}, %{{.*}} <signA = true> : (i32, i32, i32) -> i32
%r1a = rocdl.sudot8 %i32, %i32, %i32 <{signA = true}> : (i32, i32, i32) -> i32
- // CHECK: rocdl.sudot8 %{{.*}}, %{{.*}}, %{{.*}} <{signB = true}> : (i32, i32, i32) -> i32
+ // CHECK: rocdl.sudot8 %{{.*}}, %{{.*}}, %{{.*}} <signB = true> : (i32, i32, i32) -> i32
%r1b = rocdl.sudot8 %i32, %i32, %i32 <{signB = true}> : (i32, i32, i32) -> i32
- // CHECK: rocdl.sudot8 %{{.*}}, %{{.*}}, %{{.*}} <{clamp = true, signA = true, signB = true}> : (i32, i32, i32) -> i32
+ // CHECK: rocdl.sudot8 %{{.*}}, %{{.*}}, %{{.*}} <signA = true, signB = true, clamp = true> : (i32, i32, i32) -> i32
%r1c = rocdl.sudot8 %i32, %i32, %i32 <{clamp = true, signA = true, signB = true}> : (i32, i32, i32) -> i32
llvm.return %r0 : i32
diff --git a/mlir/test/Dialect/OpenACC/ops-cg.mlir b/mlir/test/Dialect/OpenACC/ops-cg.mlir
index adbd921af102e..f45ef8ae9a52c 100644
--- a/mlir/test/Dialect/OpenACC/ops-cg.mlir
+++ b/mlir/test/Dialect/OpenACC/ops-cg.mlir
@@ -465,7 +465,7 @@ func.func @gpu_shared_memory_static() {
: (index) -> memref<?xf32, #gpu.address_space<workgroup>>
return
}
-// CHECK: acc.gpu_shared_memory(%{{.*}}) <{num_copies = 1 : i64, static_upper_bound_bytes = 4096 : i64}>
+// CHECK: acc.gpu_shared_memory(%{{.*}}) <num_copies = 1, static_upper_bound_bytes = 4096>
// CHECK-SAME: : (index) -> memref<?xf32, #gpu.address_space<workgroup>>
// -----
@@ -481,7 +481,7 @@ func.func @gpu_shared_memory_runtime_sized() {
: (index) -> memref<?xf32, #gpu.address_space<workgroup>>
return
}
-// CHECK: acc.gpu_shared_memory(%{{.*}}) <{dynamic_shared_memory_fixed_bytes = 24 : i64, dynamic_shared_memory_scaling_bytes = 12 : i64, num_copies = 1 : i64, static_upper_bound_bytes = 1560 : i64}>
+// CHECK: acc.gpu_shared_memory(%{{.*}}) <num_copies = 1, static_upper_bound_bytes = 1560, dynamic_shared_memory_scaling_bytes = 12, dynamic_shared_memory_fixed_bytes = 24>
// -----
@@ -492,4 +492,4 @@ func.func @gpu_shared_memory_worker_copies() {
: () -> memref<8xf32, #gpu.address_space<workgroup>>
return
}
-// CHECK: acc.gpu_shared_memory <{num_copies = 4 : i64, static_upper_bound_bytes = 256 : i64}>
+// CHECK: acc.gpu_shared_memory <num_copies = 4, static_upper_bound_bytes = 256>
diff --git a/mlir/test/Dialect/OpenACC/ops.mlir b/mlir/test/Dialect/OpenACC/ops.mlir
index 65d49569280d3..24668cf18c6d5 100644
--- a/mlir/test/Dialect/OpenACC/ops.mlir
+++ b/mlir/test/Dialect/OpenACC/ops.mlir
@@ -1035,13 +1035,13 @@ func.func @testdataopmodifiers(%a: memref<f32>, %b: memref<f32>, %c: memref<f32>
}
// CHECK: func @testdataopmodifiers(%[[ARGA:.*]]: memref<f32>, %[[ARGB:.*]]: memref<f32>, %[[ARGC:.*]]: memref<f32>) {
-// CHECK: %[[CREATEA:.*]] = acc.create varPtr(%[[ARGA]] : memref<f32>) <{modifiers = #acc<data_clause_modifier zero,capture>}> -> memref<f32>
-// CHECK: %[[COPYINB:.*]] = acc.copyin varPtr(%[[ARGB]] : memref<f32>) <{modifiers = #acc<data_clause_modifier always,readonly,capture>}> -> memref<f32>
-// CHECK: %[[COPYINC:.*]] = acc.copyin varPtr(%[[ARGC]] : memref<f32>) <{modifiers = #acc<data_clause_modifier always>}> -> memref<f32>
-// CHECK: %[[CREATEC:.*]] = acc.create varPtr(%[[ARGC]] : memref<f32>) <{modifiers = #acc<data_clause_modifier always>}> -> memref<f32>
-// CHECK: acc.copyout accPtr(%[[CREATEA]] : memref<f32>) to varPtr(%[[ARGA]] : memref<f32>) <{modifiers = #acc<data_clause_modifier always,zero,capture>}>
-// CHECK: acc.delete accPtr(%[[COPYINC]] : memref<f32>) <{modifiers = #acc<data_clause_modifier always>}>
-// CHECK: acc.copyout accPtr(%[[CREATEC]] : memref<f32>) to varPtr(%[[ARGC]] : memref<f32>) <{modifiers = #acc<data_clause_modifier always>}>
+// CHECK: %[[CREATEA:.*]] = acc.create varPtr(%[[ARGA]] : memref<f32>) <modifiers = "zero,capture"> -> memref<f32>
+// CHECK: %[[COPYINB:.*]] = acc.copyin varPtr(%[[ARGB]] : memref<f32>) <modifiers = "always,readonly,capture"> -> memref<f32>
+// CHECK: %[[COPYINC:.*]] = acc.copyin varPtr(%[[ARGC]] : memref<f32>) <modifiers = "always"> -> memref<f32>
+// CHECK: %[[CREATEC:.*]] = acc.create varPtr(%[[ARGC]] : memref<f32>) <modifiers = "always"> -> memref<f32>
+// CHECK: acc.copyout accPtr(%[[CREATEA]] : memref<f32>) to varPtr(%[[ARGA]] : memref<f32>) <modifiers = "always,zero,capture">
+// CHECK: acc.delete accPtr(%[[COPYINC]] : memref<f32>) <modifiers = "always">
+// CHECK: acc.copyout accPtr(%[[CREATEC]] : memref<f32>) to varPtr(%[[ARGC]] : memref<f32>) <modifiers = "always">
// -----
diff --git a/mlir/test/IR/enum-attr-roundtrip.mlir b/mlir/test/IR/enum-attr-roundtrip.mlir
index d02776e226c80..113b5f07ee6f3 100644
--- a/mlir/test/IR/enum-attr-roundtrip.mlir
+++ b/mlir/test/IR/enum-attr-roundtrip.mlir
@@ -44,14 +44,14 @@ func.func @test_enum_prop() -> () {
// CHECK: test.op_with_enum_prop first
"test.op_with_enum_prop"() <{value = 0 : i32}> {} : () -> ()
- // CHECK: test.op_with_enum_prop_attr_form <{value = 0 : i32}>
+ // CHECK: test.op_with_enum_prop_attr_form <value = first>
test.op_with_enum_prop_attr_form <{value = 0 : i32}>
- // CHECK: test.op_with_enum_prop_attr_form <{value = 1 : i32}>
+ // CHECK: test.op_with_enum_prop_attr_form <value = second>
test.op_with_enum_prop_attr_form <{value = #test<enum second>}>
- // CHECK: test.op_with_enum_prop_attr_form_always <{value = #test<enum first>}>
+ // CHECK: test.op_with_enum_prop_attr_form_always <value = first>
test.op_with_enum_prop_attr_form_always <{value = #test<enum first>}>
- // CHECK: test.op_with_enum_prop_attr_form_always <{value = #test<enum second>}
+ // CHECK: test.op_with_enum_prop_attr_form_always <value = second>
test.op_with_enum_prop_attr_form_always <{value = #test<enum second>}>
return
diff --git a/mlir/test/IR/properties.mlir b/mlir/test/IR/properties.mlir
index 64548e41dc111..de37707a79d4d 100644
--- a/mlir/test/IR/properties.mlir
+++ b/mlir/test/IR/properties.mlir
@@ -14,7 +14,7 @@ test.with_properties a = 32, b = "foo", c = "bar", flag = true, array = [1, 2, 3
test.with_nice_properties "foo bar" is -3
// CHECK: test.with_wrapped_properties
-// CHECK-SAME: <{prop = "content for properties"}>{{$}}
+// CHECK-SAME: <prop = "content for properties">{{$}}
// GENERIC: "test.with_wrapped_properties"()
// GENERIC-SAME: <{prop = "content for properties"}> : () -> ()
test.with_wrapped_properties <{prop = "content for properties"}>
@@ -28,44 +28,50 @@ test.empty_properties
// GENERIC: "test.empty_properties"()
test.empty_properties <>
-// The key-value spelling uses the custom parsers for both attributes and
-// properties. Until the custom printer is enabled, it round-trips to the
-// generic DictionaryAttr spelling.
-// CHECK: test.with_custom_prop_dict <{attr = 1 : i32, prop = 2 : i64}>
+// The key-value spelling uses the custom parsers and printers for both
+// attributes and properties.
+// CHECK: test.with_custom_prop_dict <prop = 2, attr = 1>
// GENERIC: "test.with_custom_prop_dict"()
// GENERIC-SAME: <{attr = 1 : i32, defaulted = 42 : i64, prop = 2 : i64, unit = false}>
test.with_custom_prop_dict <attr = 1, prop = 2>
// The generic DictionaryAttr spelling remains accepted for compatibility.
-// CHECK: test.with_custom_prop_dict <{attr = 3 : i32, prop = 4 : i64}>
+// CHECK: test.with_custom_prop_dict <prop = 4, attr = 3>
// GENERIC: "test.with_custom_prop_dict"()
// GENERIC-SAME: <{attr = 3 : i32, defaulted = 42 : i64, prop = 4 : i64, unit = false}>
test.with_custom_prop_dict <{attr = 3 : i32, prop = 4 : i64}>
// Entries are order-independent, and optional/default-valued entries use
// their custom parsers when present.
-// CHECK: test.with_custom_prop_dict <{attr = 5 : i32, defaulted = 43 : i64, optional = "set", prop = 6 : i64}>
+// CHECK: test.with_custom_prop_dict <prop = 6, defaulted = 43, attr = 5, optional = "set">
// GENERIC: "test.with_custom_prop_dict"()
// GENERIC-SAME: <{attr = 5 : i32, defaulted = 43 : i64, optional = "set", prop = 6 : i64, unit = false}>
test.with_custom_prop_dict <optional = "set", defaulted = 43, prop = 6, attr = 5>
// A field name that is also the start of an attribute must not be consumed by
// the legacy DictionaryAttr compatibility probe.
-// CHECK: test.with_custom_prop_dict <{attr = 7 : i32, prop = 8 : i64, unit}>
+// CHECK: test.with_custom_prop_dict <prop = 8, unit = unit, attr = 7>
// GENERIC: "test.with_custom_prop_dict"()
// GENERIC-SAME: <{attr = 7 : i32, defaulted = 42 : i64, prop = 8 : i64, unit}>
test.with_custom_prop_dict <unit = unit, attr = 7, prop = 8>
+// Inherent attributes use their custom assembly printer in the key-value
+// spelling. Optional enum attributes compile and are omitted when absent.
+// CHECK: test.with_custom_attr_prop_dict <prop = 9, attr = first>
+test.with_custom_attr_prop_dict <attr = first, prop = 9>
+// CHECK: test.with_custom_attr_prop_dict <prop = 10, attr = first, optionalAttr = second>
+test.with_custom_attr_prop_dict <optionalAttr = second, prop = 10, attr = first>
+
// Properties bound elsewhere in the assembly format are excluded from the
// key-value list.
-// CHECK: test.with_properties_and_attr 7 <{rhs = 8 : i64}>
+// CHECK: test.with_properties_and_attr 7 <rhs = 8>
// GENERIC: "test.with_properties_and_attr"()
// GENERIC-SAME: <{lhs = 7 : i32, rhs = 8 : i64}>
test.with_properties_and_attr 7 <rhs = 8>
// A property without a usable custom parser falls back to its attribute
// conversion for this compatibility spelling.
-// CHECK: test.with_wrapped_properties <{prop = "custom spelling"}>
+// CHECK: test.with_wrapped_properties <prop = "custom spelling">
// GENERIC: "test.with_wrapped_properties"()
// GENERIC-SAME: <{prop = "custom spelling"}>
test.with_wrapped_properties <prop = "custom spelling">
@@ -89,7 +95,8 @@ test.with_wrapped_array_properties <prop = ["first", "second"]>
// following scalar key also checks that the container does not consume the
// outer comma.
// CHECK: test.with_key_value_parser_boundaries
-// CHECK-SAME: <{maybe = [], maybeEnum = [], next = 9 : i64, specializedMaybe = [7 : i16], specializedValues = array<i32: 3, 4>, values = array<i64: 1, 2>}>
+// CHECK-SAME: <values = array<i64: 1, 2>, maybe = [], maybeEnum = [],
+// CHECK-SAME: specializedValues = [3, 4], specializedMaybe = some<7>, next = 9>
// GENERIC: "test.with_key_value_parser_boundaries"()
// GENERIC-SAME: <{maybe = [], maybeEnum = [], next = 9 : i64, specializedMaybe = [7 : i16], specializedValues = array<i32: 3, 4>, values = array<i64: 1, 2>}>
test.with_key_value_parser_boundaries <specializedValues = [3, 4], specializedMaybe = some<7>, values = array<i64: 1, 2>, maybe = [], maybeEnum = [], next = 9>
@@ -97,7 +104,7 @@ test.with_key_value_parser_boundaries <specializedValues = [3, 4], specializedMa
// A comma-separated bit-enum FieldParser is not compositional with the outer
// list, so prop-dict uses its attribute conversion before parsing another key.
// CHECK: test.op_with_bit_enum_prop_dict
-// CHECK-SAME: <{flags = 3 : i32, next = 9 : i64}>
+// CHECK-SAME: <flags = 3 : i32, next = 9>
// GENERIC: "test.op_with_bit_enum_prop_dict"()
// GENERIC-SAME: <{flags = 3 : i32, next = 9 : i64}>
test.op_with_bit_enum_prop_dict <flags = 3 : i32, next = 9>
@@ -132,7 +139,7 @@ test.variadic_segment_prop %ci64, %ci64 : %ci64 : i64, i64 : i64 end
// `<{...}>`. Without the parser-side fix, re-parsing the CHECK line below
// (which is exactly what the printer emits) fails with "duplicate or unknown
// key 'operandSegmentSizes' in dictionary attribute".
-// CHECK: test.variadic_segment_prop_bulk_type(%[[CI64]], %[[CI64]], %[[CI64]]) : (i64, i64, i64) -> (i64, i64, i64) <{operandSegmentSizes = array<i32: 2, 1>, resultSegmentSizes = array<i32: 2, 1>}>
+// CHECK: test.variadic_segment_prop_bulk_type(%[[CI64]], %[[CI64]], %[[CI64]]) : (i64, i64, i64) -> (i64, i64, i64) <operandSegmentSizes = [2, 1], resultSegmentSizes = [2, 1]>
// GENERIC: "test.variadic_segment_prop_bulk_type"(%[[CI64]], %[[CI64]], %[[CI64]]) <{operandSegmentSizes = array<i32: 2, 1>, resultSegmentSizes = array<i32: 2, 1>}> : (i64, i64, i64) -> (i64, i64, i64)
test.variadic_segment_prop_bulk_type(%ci64, %ci64, %ci64) : (i64, i64, i64) -> (i64, i64, i64) <operandSegmentSizes = [2, 1], resultSegmentSizes = [2, 1]>
@@ -190,7 +197,8 @@ test.with_array_properties ints = [1, 2] strings = ["a", "b"] nested = [[1, 2],
// Tests that DefaultValuedProp is elided from prop-dict when value equals default.
// CHECK: test.op_with_property_predicates
-// CHECK-SAME: <{array = [], more_constrained = 1 : i64, non_empty_constrained = [1], non_empty_unconstrained = [1], scalar = 1 : i64, unconstrained = 0 : i64}>
+// CHECK-SAME: <scalar = 1, more_constrained = 1, array = [],
+// CHECK-SAME: non_empty_unconstrained = [1], non_empty_constrained = [1], unconstrained = 0>
// CHECK-NOT: defaulted
test.op_with_property_predicates <{
scalar = 1 : i64,
@@ -203,8 +211,8 @@ test.op_with_property_predicates <{
// Keyed parsing composes optional and aggregate property parsers with a
// following outer dictionary entry.
// CHECK: test.op_with_property_predicates
+// CHECK-SAME: optional = 2
// CHECK-SAME: array = [3, 4]
-// CHECK-SAME: optional = [2]
test.op_with_property_predicates <
scalar = 1,
optional = 2,
diff --git a/mlir/test/Target/LLVMIR/Import/intrinsic.ll b/mlir/test/Target/LLVMIR/Import/intrinsic.ll
index e201145e6575f..aaebaa2f46d1c 100644
--- a/mlir/test/Target/LLVMIR/Import/intrinsic.ll
+++ b/mlir/test/Target/LLVMIR/Import/intrinsic.ll
@@ -582,7 +582,7 @@ define void @trap_intrinsics() {
call void @llvm.trap()
; CHECK: llvm.intr.debugtrap
call void @llvm.debugtrap()
- ; CHECK: llvm.intr.ubsantrap <{failureKind = 1 : i8}>
+ ; CHECK: llvm.intr.ubsantrap <failureKind = 1>
call void @llvm.ubsantrap(i8 1)
ret void
}
diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td
index 4e17d54d6e9e5..7372c81898dea 100644
--- a/mlir/test/lib/Dialect/Test/TestOps.td
+++ b/mlir/test/lib/Dialect/Test/TestOps.td
@@ -3645,6 +3645,16 @@ def TestOpWithCustomPropDict : TEST_Op<"with_custom_prop_dict"> {
);
}
+def TestOpWithCustomAttrPropDict
+ : TEST_Op<"with_custom_attr_prop_dict"> {
+ let assemblyFormat = "prop-dict attr-dict";
+ let arguments = (ins
+ TestEnumAttr:$attr,
+ OptionalAttr<TestEnumAttr>:$optionalAttr,
+ I64Prop:$prop
+ );
+}
+
def TestOpWithPropertiesAndInferredType
: TEST_Op<"with_properties_and_inferred_type", [
DeclareOpInterfaceMethods<InferTypeOpInterface>
@@ -3842,6 +3852,13 @@ def KeyValueOptionalEnumProperty
def KeyValueSpecializedListProperty
: Property<"test::KeyValueSpecializedList"> {
+ let printer = [{
+ [&]() {
+ $_printer << "[";
+ ::llvm::interleaveComma($_storage, $_printer);
+ $_printer << "]";
+ }()
+ }];
let convertToAttribute =
"return ::mlir::DenseI32ArrayAttr::get($_ctxt, $_storage);";
let convertFromAttribute = [{
@@ -3860,6 +3877,15 @@ def KeyValueSpecializedListProperty
def KeyValueSpecializedOptionalProperty
: Property<"std::optional<int16_t>"> {
+ let printer = [{
+ [&]() {
+ if (!$_storage) {
+ $_printer << "none";
+ return;
+ }
+ $_printer << "some<" << *$_storage << ">";
+ }()
+ }];
let convertToAttribute = [{
if (!$_storage)
return ::mlir::ArrayAttr::get($_ctxt, {});
@@ -4005,6 +4031,7 @@ def PropertiesWithCustomPrint : Property<"PropertiesWithCustomPrint"> {
}
def TestOpWithNiceProperties : TEST_Op<"with_nice_properties"> {
+ let hasCustomPropertiesPrinter = 1;
let assemblyFormat = "prop-dict attr-dict";
let arguments = (ins
PropertiesWithCustomPrint:$prop
@@ -4069,6 +4096,7 @@ def VersionedProperties : Property<"VersionedProperties"> {
}
def TestOpWithVersionedProperties : TEST_Op<"with_versioned_properties"> {
+ let hasCustomPropertiesPrinter = 1;
let assemblyFormat = "prop-dict attr-dict";
let arguments = (ins
VersionedProperties:$prop
diff --git a/mlir/test/mlir-tblgen/op-format-custom-properties-printer.td b/mlir/test/mlir-tblgen/op-format-custom-properties-printer.td
new file mode 100644
index 0000000000000..6bec1ef9f8bf7
--- /dev/null
+++ b/mlir/test/mlir-tblgen/op-format-custom-properties-printer.td
@@ -0,0 +1,32 @@
+// RUN: mlir-tblgen -gen-op-defs -I %S/../../include %s | FileCheck %s
+
+include "mlir/IR/OpBase.td"
+
+def TestDialect : Dialect {
+ let name = "test";
+ let cppNamespace = "::test";
+}
+
+// A custom properties printer shadows the generated per-field helper.
+// CHECK-NOT: CustomPropertiesPrinterOp::_odsPrintPropertiesAsKeyValueList
+// CHECK: void CustomPropertiesPrinterOp::print
+// CHECK-NOT: CustomPropertiesPrinterOp::_odsPrintPropertiesAsKeyValueList
+def CustomPropertiesPrinterOp : Op<TestDialect, "custom_properties_printer"> {
+ let arguments = (ins I64Attr:$attr);
+ let assemblyFormat = "prop-dict attr-dict";
+ let hasCustomPropertiesPrinter = 1;
+ let extraClassDeclaration = [{
+ void printProperties(::mlir::MLIRContext *, ::mlir::OpAsmPrinter &,
+ const Properties &,
+ ::mlir::ArrayRef<::llvm::StringRef>);
+ }];
+}
+
+// Absent default-valued attributes are not printed from property storage.
+// CHECK: void DefaultValuedAttrOp::_odsPrintPropertiesAsKeyValueList
+// CHECK: if (shouldPrint("attr") && prop.attr) {
+// CHECK-NEXT: printKey("attr");
+def DefaultValuedAttrOp : Op<TestDialect, "default_valued_attr"> {
+ let arguments = (ins DefaultValuedAttr<I64Attr, "0">:$attr);
+ let assemblyFormat = "prop-dict attr-dict";
+}
diff --git a/mlir/test/mlir-tblgen/op-format.mlir b/mlir/test/mlir-tblgen/op-format.mlir
index 41d09231232de..f64a631a1c0da 100644
--- a/mlir/test/mlir-tblgen/op-format.mlir
+++ b/mlir/test/mlir-tblgen/op-format.mlir
@@ -296,13 +296,13 @@ test.format_optional_prop_dict <{a = [], b = 1 : i32}>
// CHECK: test.format_optional_prop_dict{{$}}
test.format_optional_prop_dict <{}>
-// CHECK: test.format_optional_prop_dict <{a = ["foo"]}>
+// CHECK: test.format_optional_prop_dict <a = "foo">
test.format_optional_prop_dict <{a = ["foo"]}>
-// CHECK: test.format_optional_prop_dict <{b = 2 : i32}>
+// CHECK: test.format_optional_prop_dict <b = 2>
test.format_optional_prop_dict <{b = 2 : i32}>
-// CHECK: test.format_optional_prop_dict <{a = ["foo"], b = 2 : i32}>
+// CHECK: test.format_optional_prop_dict <a = "foo", b = 2>
test.format_optional_prop_dict <{a = ["foo"], b = 2 : i32}>
//===----------------------------------------------------------------------===//
@@ -531,15 +531,15 @@ test.format_optional_operand_type(%i64) : i64
// CHECK: test.format_infer_type_variadic_operands(%[[I32]], %[[I32]] : i32, i32) (%[[I64]], %[[I64]] : i64, i64)
%ignored_res13:4 = test.format_infer_type_variadic_operands(%i32, %i32 : i32, i32) (%i64, %i64 : i64, i64)
-// CHECK: test.with_properties_and_attr 16 <{rhs = 16 : i64}>
+// CHECK: test.with_properties_and_attr 16 <rhs = 16>
test.with_properties_and_attr 16 <{rhs = 16 : i64}>
-// CHECK: test.with_properties_and_inferred_type 16 <{packed, rhs = 16 : i64}>
+// CHECK: test.with_properties_and_inferred_type 16 <rhs = 16, packed = unit>
%should_be_i32 = test.with_properties_and_inferred_type 16 <{packed, rhs = 16 : i64}>
// Assert through the verifier that its inferred as i32.
test.format_all_types_match_var %should_be_i32, %i32 : i32
-// CHECK: test.using_property_in_custom_and_other [1, 4, 20] <{other = 16 : i64}>
+// CHECK: test.using_property_in_custom_and_other [1, 4, 20] <other = 16>
test.using_property_in_custom_and_other [1, 4, 20] <{other = 16 : i64}>
//===----------------------------------------------------------------------===//
diff --git a/mlir/tools/mlir-tblgen/OpFormatGen.cpp b/mlir/tools/mlir-tblgen/OpFormatGen.cpp
index 408616a946ad6..05a26402005fd 100644
--- a/mlir/tools/mlir-tblgen/OpFormatGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpFormatGen.cpp
@@ -2343,7 +2343,7 @@ static const char *regionSingleBlockImplicitTerminatorPrinterCode = R"(
/// {1}: The name of the enum attributes symbolToString function.
static const char *enumAttrBeginPrinterCode = R"(
{
- auto caseValue = {0}();
+ auto caseValue = {0};
auto caseValueStr = {1}(caseValue);
)";
@@ -2394,6 +2394,129 @@ static void genVariadicSegmentElision(OperationFormat &fmt, Operator &op,
body << " " << elidedStorage << ".push_back(\"resultSegmentSizes\");\n";
}
+static void genEnumAttrPrinter(const NamedAttribute *var, const Operator &op,
+ MethodBody &body, StringRef valueExpression);
+
+/// Generate the key-value printer used by the default `prop-dict` printer.
+static void genKeyValuePropDictPrinter(OperationFormat &fmt, Operator &op,
+ OpClass &opClass) {
+ if (!fmt.hasPropDict || !fmt.useProperties || op.hasCustomPropertiesPrinter())
+ return;
+
+ bool hasPrintableField =
+ !op.getProperties().empty() ||
+ llvm::any_of(
+ op.getAttributes(),
+ [](const auto &attr) { return !attr.attr.isDerivedAttr(); }) ||
+ (op.getTrait("::mlir::OpTrait::AttrSizedOperandSegments") &&
+ fmt.allOperands) ||
+ (op.getTrait("::mlir::OpTrait::AttrSizedResultSegments") &&
+ fmt.allResultTypes);
+ if (!hasPrintableField)
+ return;
+
+ SmallVector<MethodParameter> paramList;
+ paramList.emplace_back("::mlir::MLIRContext *", "_odsContext");
+ paramList.emplace_back("::mlir::OpAsmPrinter &", "_odsPrinter");
+ paramList.emplace_back("const Properties &", "prop");
+ paramList.emplace_back("::mlir::ArrayRef<::llvm::StringRef>", "elidedProps");
+ Method *method = opClass.addStaticMethod(
+ "void", "_odsPrintPropertiesAsKeyValueList", std::move(paramList));
+ MethodBody &body = method->body().indent();
+
+ body << R"decl(
+bool first = true;
+auto printKey = [&](::llvm::StringRef name) {
+ _odsPrinter << (first ? " <" : ", ") << name << " = ";
+ first = false;
+};
+auto shouldPrint = [&](::llvm::StringRef name) {
+ return !::llvm::is_contained(elidedProps, name);
+};
+)decl";
+
+ auto genSegmentSizesPrinter = [&](StringRef name) {
+ body << "if (shouldPrint(\"" << name << "\")) {\n"
+ << " printKey(\"" << name << "\");\n"
+ << " _odsPrinter << \"[\";\n"
+ << " ::llvm::interleaveComma(prop." << name << ", _odsPrinter);\n"
+ << " _odsPrinter << \"]\";\n"
+ << "}\n";
+ };
+ if (op.getTrait("::mlir::OpTrait::AttrSizedOperandSegments") &&
+ fmt.allOperands)
+ genSegmentSizesPrinter("operandSegmentSizes");
+ if (op.getTrait("::mlir::OpTrait::AttrSizedResultSegments") &&
+ fmt.allResultTypes)
+ genSegmentSizesPrinter("resultSegmentSizes");
+
+ for (const NamedProperty &namedProperty : op.getProperties()) {
+ const Property &property = namedProperty.prop;
+ body << "if (shouldPrint(\"" << namedProperty.name << "\")) {\n"
+ << " printKey(\"" << namedProperty.name << "\");\n";
+ FmtContext printerContext;
+ printerContext.addSubst("_printer", "_odsPrinter");
+ printerContext.addSubst("_ctxt", "_odsContext");
+ printerContext.addSubst("_storage", "prop." + namedProperty.name);
+ if (property.usesDefaultParser()) {
+ body << " if constexpr (::mlir::detail::HasKeyValueFieldParser<"
+ "std::remove_cv_t<std::remove_reference_t<decltype(prop."
+ << namedProperty.name << ")>>>::value) {\n"
+ << " " << tgfmt(property.getPrinterCall(), &printerContext)
+ << ";\n"
+ << " } else {\n"
+ << " auto propertyAttr = [&]() -> ::mlir::Attribute {\n";
+ FmtContext conversionContext;
+ conversionContext.addSubst("_ctxt", "_odsContext");
+ conversionContext.addSubst("_storage", "prop." + namedProperty.name);
+ body << tgfmt(property.getConvertToAttributeCall(), &conversionContext)
+ << "\n"
+ << " }();\n"
+ << " _odsPrinter.printAttribute(propertyAttr);\n"
+ << " }\n";
+ } else {
+ body << " " << tgfmt(property.getPrinterCall(), &printerContext)
+ << ";\n";
+ }
+ body << "}\n";
+ }
+
+ for (const NamedAttribute &namedAttr : op.getAttributes()) {
+ if (namedAttr.attr.isDerivedAttr())
+ continue;
+ StringRef name = namedAttr.name;
+ body << "if (shouldPrint(\"" << name << "\")";
+ if (namedAttr.attr.isOptional() || namedAttr.attr.hasDefaultValue())
+ body << " && prop." << name;
+ body << ") {\n"
+ << " printKey(\"" << name << "\");\n";
+
+ if (canFormatEnumAttr(&namedAttr)) {
+ FmtContext conversionContext;
+ conversionContext.withSelf("prop." + name);
+ std::string valueExpression = std::string(tgfmt(
+ namedAttr.attr.getConvertFromStorageCall(), &conversionContext));
+ genEnumAttrPrinter(&namedAttr, op, body, valueExpression);
+ } else if (shouldFormatSymbolNameAttr(&namedAttr)) {
+ body << " _odsPrinter.printSymbolName(prop." << name
+ << ".getValue());\n";
+ } else {
+ AttributeVariable attrVariable(&namedAttr);
+ if (attrVariable.getTypeBuilder())
+ body << " _odsPrinter.printAttributeWithoutType(prop." << name
+ << ");\n";
+ else if (attrVariable.shouldBeQualified() ||
+ namedAttr.attr.getStorageType() == "::mlir::Attribute")
+ body << " _odsPrinter.printAttribute(prop." << name << ");\n";
+ else
+ body << " _odsPrinter.printStrippedAttrOrType(prop." << name << ");\n";
+ }
+ body << "}\n";
+ }
+ body << "if (!first)\n"
+ " _odsPrinter << \">\";\n";
+}
+
/// Generate the printer for the 'prop-dict' directive.
static void genPropDictPrinter(OperationFormat &fmt, Operator &op,
MethodBody &body) {
@@ -2633,15 +2756,20 @@ static MethodBody &genTypeOperandPrinter(FormatElement *arg, const Operator &op,
/// Generate the printer for an enum attribute.
static void genEnumAttrPrinter(const NamedAttribute *var, const Operator &op,
- MethodBody &body) {
+ MethodBody &body,
+ StringRef valueExpression = {}) {
Attribute baseAttr = var->attr.getBaseAttr();
const EnumInfo enumInfo(getEnumInfoRecord(baseAttr));
std::vector<EnumCase> cases = enumInfo.getAllCases();
bool dereferenceGetter =
var->attr.isOptional() && !var->attr.hasDefaultValue();
- body << formatv(enumAttrBeginPrinterCode,
- (dereferenceGetter ? "*" : "") + op.getGetterName(var->name),
+ std::string caseValue = valueExpression.empty()
+ ? op.getGetterName(var->name) + "()"
+ : valueExpression.str();
+ if (dereferenceGetter)
+ caseValue = "*(" + caseValue + ")";
+ body << formatv(enumAttrBeginPrinterCode, caseValue,
enumInfo.getSymbolToStringFnName());
// Get a string containing all of the cases that can't be represented with a
@@ -3051,6 +3179,8 @@ void OperationFormat::genPrinter(Operator &op, OpClass &opClass) {
bool shouldEmitSpace = true, lastWasPunctuation = false;
for (FormatElement *element : elements)
genElementPrinter(element, body, op, shouldEmitSpace, lastWasPunctuation);
+
+ genKeyValuePropDictPrinter(*this, op, opClass);
}
//===----------------------------------------------------------------------===//
More information about the Mlir-commits
mailing list