[Mlir-commits] [flang] [mlir] [mlir][ODS] Fix notorious double-space bug in op printers (PR #184253)
Jakub Kuderski
llvmlistbot at llvm.org
Mon Mar 2 14:54:50 PST 2026
https://github.com/kuhar created https://github.com/llvm/llvm-project/pull/184253
When an op's assembly format prints an attribute via `printStrippedAttrOrType`, two independent space-emission mechanisms would fire: the op format generator emits a space before each argument, and the attribute's generated `print` method also emits a leading space (`shouldEmitSpace` initialized to true). This caused double spaces like `gpu.shuffle xor`.
The usual workaround for this was to add double backticks to consume the leading space.
Fixed by removing the leading space from generated attr/type print() methods (initializing shouldEmitSpace=false) and compensating in the print dispatcher by conditionally adding a space between the mnemonic and `print` call when the format starts with a name or keyword rather than punctuation.
Also remove some workarounds for the double-spacing bug in op formats and fix tests that now don't have leading spaces.
Assisted-by: claude
>From f3beb74c9afb652bff56a20f9cde24327963749c Mon Sep 17 00:00:00 2001
From: Jakub Kuderski <jakub at nod-labs.com>
Date: Mon, 2 Mar 2026 07:23:50 -0500
Subject: [PATCH] [mlir][ODS] Fix notorious double-space bug in op printers
When an op's assembly format prints an attribute via `printStrippedAttrOrType`,
two independent space-emission mechanisms would fire: the op format generator
emits a space before each argument, and the attribute's generated `print`
method also emits a leading space (`shouldEmitSpace` initialized to true).
This caused double spaces like `gpu.shuffle xor`.
The usual workaround for this was to add double backticks to consume the
leading space.
Fixed by removing the leading space from generated attr/type print() methods
(initializing shouldEmitSpace=false) and compensating in the print dispatcher
by conditionally adding a space between the mnemonic and `print` call when
the format starts with a name or keyword rather than punctuation.
Also remove some workarounds for the double-spacing bug in op formats
and fix tests that now don't have leading spaces.
Assisted-by: claude
---
flang/test/Lower/location.f90 | 2 +-
.../include/mlir/Dialect/Index/IR/IndexOps.td | 2 +-
.../include/mlir/Dialect/XeGPU/IR/XeGPUOps.td | 2 +-
mlir/test/CAPI/irdl.c | 2 +-
mlir/test/Dialect/GPU/shuffle-rewrite.mlir | 8 ++--
mlir/test/Dialect/GPU/sparse-roundtrip.mlir | 4 +-
.../SparseTensor/GPU/gpu_spgemm_lib.mlir | 8 ++--
.../Vector/vector-warp-distribute.mlir | 34 ++++++++--------
.../XeGPU/sg-to-wi-experimental-unit.mlir | 40 +++++++++----------
mlir/test/IR/array-of-attr.mlir | 2 +-
.../attr-or-type-format-roundtrip.mlir | 4 +-
mlir/test/mlir-tblgen/attr-or-type-format.td | 35 +++++++++++++---
mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp | 39 +++++++++++++++++-
.../tools/mlir-tblgen/AttrOrTypeFormatGen.cpp | 11 +++--
14 files changed, 129 insertions(+), 64 deletions(-)
diff --git a/flang/test/Lower/location.f90 b/flang/test/Lower/location.f90
index cdde1cc4cb40a..744ff7e3bf039 100644
--- a/flang/test/Lower/location.f90
+++ b/flang/test/Lower/location.f90
@@ -6,7 +6,7 @@ program test
end
! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "TEST"} {
-! CHECK: fir.call @_FortranAioOutputAscii(%{{.*}}, %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1 loc(fused<#fir<loc_kind_array[ base, inclusion, inclusion]>>["{{.*}}location1.inc":1:10, "{{.*}}location0.inc":1:1, "{{.*}}location.f90":4:1])
+! CHECK: fir.call @_FortranAioOutputAscii(%{{.*}}, %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1 loc(fused<#fir<loc_kind_array[base, inclusion, inclusion]>>["{{.*}}location1.inc":1:10, "{{.*}}location0.inc":1:1, "{{.*}}location.f90":4:1])
! CHECK: return loc("{{.*}}location.f90":6:1)
! CHECK: } loc("{{.*}}location.f90":3:1)
diff --git a/mlir/include/mlir/Dialect/Index/IR/IndexOps.td b/mlir/include/mlir/Dialect/Index/IR/IndexOps.td
index 230a3815bdd81..d97d5be698034 100644
--- a/mlir/include/mlir/Dialect/Index/IR/IndexOps.td
+++ b/mlir/include/mlir/Dialect/Index/IR/IndexOps.td
@@ -560,7 +560,7 @@ def Index_CmpOp : IndexOp<"cmp", [Pure]> {
let arguments = (ins IndexCmpPredicateAttr:$pred, Index:$lhs, Index:$rhs);
let results = (outs I1:$result);
- let assemblyFormat = "`` $pred `(` $lhs `,` $rhs `)` attr-dict";
+ let assemblyFormat = "$pred `(` $lhs `,` $rhs `)` attr-dict";
let hasFolder = 1;
let hasCanonicalizeMethod = 1;
}
diff --git a/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUOps.td b/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUOps.td
index 6d21aa9295716..47a1804647fa7 100644
--- a/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUOps.td
+++ b/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUOps.td
@@ -1490,7 +1490,7 @@ def XeGPU_FenceOp: XeGPU_Op<"fence", []> {
}];
let arguments = (ins XeGPU_MemorySpaceAttr: $memory_kind,
XeGPU_FenceScopeAttr: $fence_scope);
- let assemblyFormat = [{`memory_kind` `=` `` $memory_kind `,` `fence_scope` `=` `` $fence_scope attr-dict}];
+ let assemblyFormat = [{`memory_kind` `=` $memory_kind `,` `fence_scope` `=` $fence_scope attr-dict}];
let extraClassDeclaration = extraBaseClassDeclaration;
}
diff --git a/mlir/test/CAPI/irdl.c b/mlir/test/CAPI/irdl.c
index 20cf35f2501ff..4ee4bc0cc35b6 100644
--- a/mlir/test/CAPI/irdl.c
+++ b/mlir/test/CAPI/irdl.c
@@ -62,7 +62,7 @@ void testVariadicityAttributes(MlirContext ctx) {
MlirAttribute variadicityArray =
mlirIRDLVariadicityArrayAttrGet(ctx, 3, variadicities);
- // CHECK: #irdl<variadicity_array[ single, optional, variadic]>
+ // CHECK: #irdl<variadicity_array[single, optional, variadic]>
mlirAttributeDump(variadicityArray);
}
diff --git a/mlir/test/Dialect/GPU/shuffle-rewrite.mlir b/mlir/test/Dialect/GPU/shuffle-rewrite.mlir
index c0ccae05a0572..5492ebee915cd 100644
--- a/mlir/test/Dialect/GPU/shuffle-rewrite.mlir
+++ b/mlir/test/Dialect/GPU/shuffle-rewrite.mlir
@@ -10,8 +10,8 @@ module {
// CHECK-NEXT: %[[LO:.*]] = arith.trunci %[[INTVAL]] : i64 to i32
// CHECK-NEXT: %[[HI64:.*]] = arith.shrui %[[INTVAL]], %[[C32:.*]] : i64
// CHECK-NEXT: %[[HI:.*]] = arith.trunci %[[HI64]] : i64 to i32
- // CHECK-NEXT: %[[SH1:.*]], %[[V1:.*]] = gpu.shuffle xor %[[LO]], %[[OFF]], %[[WIDTH]] : i32
- // CHECK-NEXT: %[[SH2:.*]], %[[V2:.*]] = gpu.shuffle xor %[[HI]], %[[OFF]], %[[WIDTH]] : i32
+ // CHECK-NEXT: %[[SH1:.*]], %[[V1:.*]] = gpu.shuffle xor %[[LO]], %[[OFF]], %[[WIDTH]] : i32
+ // CHECK-NEXT: %[[SH2:.*]], %[[V2:.*]] = gpu.shuffle xor %[[HI]], %[[OFF]], %[[WIDTH]] : i32
// CHECK-NEXT: %[[LOSH:.*]] = arith.extui %[[SH1]] : i32 to i64
// CHECK-NEXT: %[[HISHTMP:.*]] = arith.extui %[[SH2]] : i32 to i64
// CHECK-NEXT: %[[HISH:.*]] = arith.shli %[[HISHTMP]], %[[C32]] : i64
@@ -36,8 +36,8 @@ module {
// CHECK: %[[LO:.*]] = arith.trunci %[[VALUE]] : i64 to i32
// CHECK-NEXT: %[[HI64:.*]] = arith.shrui %[[VALUE]], %[[C32:.*]] : i64
// CHECK-NEXT: %[[HI:.*]] = arith.trunci %[[HI64]] : i64 to i32
- // CHECK-NEXT: %[[SH1:.*]], %[[V1:.*]] = gpu.shuffle xor %[[LO]], %[[OFF]], %[[WIDTH]] : i32
- // CHECK-NEXT: %[[SH2:.*]], %[[V2:.*]] = gpu.shuffle xor %[[HI]], %[[OFF]], %[[WIDTH]] : i32
+ // CHECK-NEXT: %[[SH1:.*]], %[[V1:.*]] = gpu.shuffle xor %[[LO]], %[[OFF]], %[[WIDTH]] : i32
+ // CHECK-NEXT: %[[SH2:.*]], %[[V2:.*]] = gpu.shuffle xor %[[HI]], %[[OFF]], %[[WIDTH]] : i32
// CHECK-NEXT: %[[LOSH:.*]] = arith.extui %[[SH1]] : i32 to i64
// CHECK-NEXT: %[[HISHTMP:.*]] = arith.extui %[[SH2]] : i32 to i64
// CHECK-NEXT: %[[HISH:.*]] = arith.shli %[[HISHTMP]], %[[C32]] : i64
diff --git a/mlir/test/Dialect/GPU/sparse-roundtrip.mlir b/mlir/test/Dialect/GPU/sparse-roundtrip.mlir
index 1e74aa3a4813a..b88492433ba02 100644
--- a/mlir/test/Dialect/GPU/sparse-roundtrip.mlir
+++ b/mlir/test/Dialect/GPU/sparse-roundtrip.mlir
@@ -62,8 +62,8 @@ module attributes {gpu.container_module} {
// CHECK: %{{.*}}, %{{.*}} = gpu.create_csr async [%{{.*}}] %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : memref<?xindex>, memref<?xindex>, memref<?xf32>
// CHECK: %{{.*}}, %{{.*}} = gpu.create_csr async [%{{.*}}] %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : memref<?xindex>, memref<?xindex>, memref<?xf32>
// CHECK: %{{.*}}, %{{.*}} = gpu.spgemm_create_descr async [%{{.*}}]
- // CHECK: %{{.*}}, %{{.*}} = gpu.spgemm_work_estimation_or_compute async [%{{.*}}]{ WORK_ESTIMATION} %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : f32 into memref<0xi8>
- // CHECK: %{{.*}}, %{{.*}} = gpu.spgemm_work_estimation_or_compute async [%{{.*}}]{ COMPUTE} %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : f32 into memref<0xi8>
+ // CHECK: %{{.*}}, %{{.*}} = gpu.spgemm_work_estimation_or_compute async [%{{.*}}]{WORK_ESTIMATION} %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : f32 into memref<0xi8>
+ // CHECK: %{{.*}}, %{{.*}} = gpu.spgemm_work_estimation_or_compute async [%{{.*}}]{COMPUTE} %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : f32 into memref<0xi8>
// CHECK: %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} = gpu.spmat_get_size async [%{{.*}}] %{{.*}}
// CHECK: %{{.*}} = gpu.set_csr_pointers async [%{{.*}}] %{{.*}}, {{.*}}, {{.*}}, {{.*}} : memref<?xindex>, memref<?xindex>, memref<?xf32>
// CHECK: %{{.*}} = gpu.spgemm_copy async [%{{.*}}] %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : f32
diff --git a/mlir/test/Dialect/SparseTensor/GPU/gpu_spgemm_lib.mlir b/mlir/test/Dialect/SparseTensor/GPU/gpu_spgemm_lib.mlir
index fa8ad1cc50604..9688e886f69ca 100644
--- a/mlir/test/Dialect/SparseTensor/GPU/gpu_spgemm_lib.mlir
+++ b/mlir/test/Dialect/SparseTensor/GPU/gpu_spgemm_lib.mlir
@@ -49,12 +49,12 @@
// CHECK: %[[VAL_53:.*]], %[[VAL_54:.*]] = gpu.alloc async {{\[}}%[[VAL_52]]] (%[[VAL_3]]) : memref<?xf32>
// CHECK: %[[VAL_55:.*]], %[[VAL_56:.*]] = gpu.create_csr async {{\[}}%[[VAL_54]]] %[[VAL_2]], %[[VAL_2]], %[[VAL_3]], %[[VAL_49]], %[[VAL_51]], %[[VAL_53]] : memref<?xindex>, memref<?xindex>, memref<?xf32>
// CHECK: %[[VAL_57:.*]], %[[VAL_58:.*]] = gpu.spgemm_create_descr async {{\[}}%[[VAL_56]]]
-// CHECK: %[[VAL_59:.*]], %[[VAL_60:.*]] = gpu.spgemm_work_estimation_or_compute async {{\[}}%[[VAL_58]]]{ WORK_ESTIMATION} %[[VAL_45]], %[[VAL_47]], %[[VAL_55]], %[[VAL_57]], %[[VAL_3]], %[[VAL_53]] : f32 into memref<?xf32>
+// CHECK: %[[VAL_59:.*]], %[[VAL_60:.*]] = gpu.spgemm_work_estimation_or_compute async {{\[}}%[[VAL_58]]]{WORK_ESTIMATION} %[[VAL_45]], %[[VAL_47]], %[[VAL_55]], %[[VAL_57]], %[[VAL_3]], %[[VAL_53]] : f32 into memref<?xf32>
// CHECK: %[[VAL_61:.*]], %[[VAL_62:.*]] = gpu.alloc async {{\[}}%[[VAL_60]]] (%[[VAL_59]]) : memref<?xi8>
-// CHECK: %[[VAL_63:.*]], %[[VAL_64:.*]] = gpu.spgemm_work_estimation_or_compute async {{\[}}%[[VAL_62]]]{ WORK_ESTIMATION} %[[VAL_45]], %[[VAL_47]], %[[VAL_55]], %[[VAL_57]], %[[VAL_59]], %[[VAL_61]] : f32 into memref<?xi8>
-// CHECK: %[[VAL_65:.*]], %[[VAL_66:.*]] = gpu.spgemm_work_estimation_or_compute async {{\[}}%[[VAL_64]]]{ COMPUTE} %[[VAL_45]], %[[VAL_47]], %[[VAL_55]], %[[VAL_57]], %[[VAL_3]], %[[VAL_53]] : f32 into memref<?xf32>
+// CHECK: %[[VAL_63:.*]], %[[VAL_64:.*]] = gpu.spgemm_work_estimation_or_compute async {{\[}}%[[VAL_62]]]{WORK_ESTIMATION} %[[VAL_45]], %[[VAL_47]], %[[VAL_55]], %[[VAL_57]], %[[VAL_59]], %[[VAL_61]] : f32 into memref<?xi8>
+// CHECK: %[[VAL_65:.*]], %[[VAL_66:.*]] = gpu.spgemm_work_estimation_or_compute async {{\[}}%[[VAL_64]]]{COMPUTE} %[[VAL_45]], %[[VAL_47]], %[[VAL_55]], %[[VAL_57]], %[[VAL_3]], %[[VAL_53]] : f32 into memref<?xf32>
// CHECK: %[[VAL_67:.*]], %[[VAL_68:.*]] = gpu.alloc async {{\[}}%[[VAL_66]]] (%[[VAL_65]]) : memref<?xi8>
-// CHECK: %[[VAL_69:.*]], %[[VAL_70:.*]] = gpu.spgemm_work_estimation_or_compute async {{\[}}%[[VAL_68]]]{ COMPUTE} %[[VAL_45]], %[[VAL_47]], %[[VAL_55]], %[[VAL_57]], %[[VAL_65]], %[[VAL_67]] : f32 into memref<?xi8>
+// CHECK: %[[VAL_69:.*]], %[[VAL_70:.*]] = gpu.spgemm_work_estimation_or_compute async {{\[}}%[[VAL_68]]]{COMPUTE} %[[VAL_45]], %[[VAL_47]], %[[VAL_55]], %[[VAL_57]], %[[VAL_65]], %[[VAL_67]] : f32 into memref<?xi8>
// CHECK: %[[VAL_71:.*]], %[[VAL_72:.*]], %[[VAL_73:.*]], %[[VAL_74:.*]] = gpu.spmat_get_size async {{\[}}%[[VAL_70]]] %[[VAL_55]]
// CHECK: %[[VAL_75:.*]], %[[VAL_76:.*]] = gpu.alloc async {{\[}}%[[VAL_74]]] (%[[VAL_73]]) : memref<?xindex>
// CHECK: %[[VAL_77:.*]], %[[VAL_78:.*]] = gpu.alloc async {{\[}}%[[VAL_76]]] (%[[VAL_73]]) : memref<?xf32>
diff --git a/mlir/test/Dialect/Vector/vector-warp-distribute.mlir b/mlir/test/Dialect/Vector/vector-warp-distribute.mlir
index 63c9d9b7a9bf8..bea098da13f1e 100644
--- a/mlir/test/Dialect/Vector/vector-warp-distribute.mlir
+++ b/mlir/test/Dialect/Vector/vector-warp-distribute.mlir
@@ -741,15 +741,15 @@ func.func @warp_scf_for_swapped_for_results(%arg0: index) {
// CHECK-PROP: gpu.yield %{{.*}} : vector<32xf32>
// CHECK-PROP: }
// CHECK-PROP: %[[a:.*]] = vector.extract %[[warp_op]][0] : f32 from vector<1xf32>
-// CHECK-PROP: %[[r0:.*]], %{{.*}} = gpu.shuffle xor %[[a]], %[[c1]], %[[c32]]
+// CHECK-PROP: %[[r0:.*]], %{{.*}} = gpu.shuffle xor %[[a]], %[[c1]], %[[c32]]
// CHECK-PROP: %[[a0:.*]] = arith.addf %[[a]], %[[r0]]
-// CHECK-PROP: %[[r1:.*]], %{{.*}} = gpu.shuffle xor %[[a0]], %[[c2]], %[[c32]]
+// CHECK-PROP: %[[r1:.*]], %{{.*}} = gpu.shuffle xor %[[a0]], %[[c2]], %[[c32]]
// CHECK-PROP: %[[a1:.*]] = arith.addf %[[a0]], %[[r1]]
-// CHECK-PROP: %[[r2:.*]], %{{.*}} = gpu.shuffle xor %[[a1]], %[[c4]], %[[c32]]
+// CHECK-PROP: %[[r2:.*]], %{{.*}} = gpu.shuffle xor %[[a1]], %[[c4]], %[[c32]]
// CHECK-PROP: %[[a2:.*]] = arith.addf %[[a1]], %[[r2]]
-// CHECK-PROP: %[[r3:.*]], %{{.*}} = gpu.shuffle xor %[[a2]], %[[c8]], %[[c32]]
+// CHECK-PROP: %[[r3:.*]], %{{.*}} = gpu.shuffle xor %[[a2]], %[[c8]], %[[c32]]
// CHECK-PROP: %[[a3:.*]] = arith.addf %[[a2]], %[[r3]]
-// CHECK-PROP: %[[r4:.*]], %{{.*}} = gpu.shuffle xor %[[a3]], %[[c16]], %[[c32]]
+// CHECK-PROP: %[[r4:.*]], %{{.*}} = gpu.shuffle xor %[[a3]], %[[c16]], %[[c32]]
// CHECK-PROP: %[[a4:.*]] = arith.addf %[[a3]], %[[r4]]
// CHECK-PROP: return %[[a4]] : f32
func.func @vector_reduction(%laneid: index) -> (f32) {
@@ -829,15 +829,15 @@ func.func @vector_reduction(%laneid: index, %m0: memref<4x2x32xf32>, %m1: memref
// CHECK-PROP: gpu.yield %{{.*}} : vector<64xf32>
// CHECK-PROP: }
// CHECK-PROP: %[[a:.*]] = vector.reduction <add>, %[[warp_op]] : vector<2xf32> into f32
-// CHECK-PROP: %[[r0:.*]], %{{.*}} = gpu.shuffle xor %[[a]], %[[c1]], %[[c32]]
+// CHECK-PROP: %[[r0:.*]], %{{.*}} = gpu.shuffle xor %[[a]], %[[c1]], %[[c32]]
// CHECK-PROP: %[[a0:.*]] = arith.addf %[[a]], %[[r0]]
-// CHECK-PROP: %[[r1:.*]], %{{.*}} = gpu.shuffle xor %[[a0]], %[[c2]], %[[c32]]
+// CHECK-PROP: %[[r1:.*]], %{{.*}} = gpu.shuffle xor %[[a0]], %[[c2]], %[[c32]]
// CHECK-PROP: %[[a1:.*]] = arith.addf %[[a0]], %[[r1]]
-// CHECK-PROP: %[[r2:.*]], %{{.*}} = gpu.shuffle xor %[[a1]], %[[c4]], %[[c32]]
+// CHECK-PROP: %[[r2:.*]], %{{.*}} = gpu.shuffle xor %[[a1]], %[[c4]], %[[c32]]
// CHECK-PROP: %[[a2:.*]] = arith.addf %[[a1]], %[[r2]]
-// CHECK-PROP: %[[r3:.*]], %{{.*}} = gpu.shuffle xor %[[a2]], %[[c8]], %[[c32]]
+// CHECK-PROP: %[[r3:.*]], %{{.*}} = gpu.shuffle xor %[[a2]], %[[c8]], %[[c32]]
// CHECK-PROP: %[[a3:.*]] = arith.addf %[[a2]], %[[r3]]
-// CHECK-PROP: %[[r4:.*]], %{{.*}} = gpu.shuffle xor %[[a3]], %[[c16]], %[[c32]]
+// CHECK-PROP: %[[r4:.*]], %{{.*}} = gpu.shuffle xor %[[a3]], %[[c16]], %[[c32]]
// CHECK-PROP: %[[a4:.*]] = arith.addf %[[a3]], %[[r4]]
// CHECK-PROP: return %[[a4]] : f32
func.func @vector_reduction_large(%laneid: index) -> (f32) {
@@ -863,15 +863,15 @@ func.func @vector_reduction_large(%laneid: index) -> (f32) {
// CHECK-PROP: gpu.yield %{{.*}}, %{{.*}} : vector<64xf32>, f32
// CHECK-PROP: }
// CHECK-PROP: %[[a:.*]] = vector.reduction <add>, %[[warp_op]]#0 : vector<2xf32> into f32
-// CHECK-PROP: %[[r0:.*]], %{{.*}} = gpu.shuffle xor %[[a]], %[[c1]], %[[c32]]
+// CHECK-PROP: %[[r0:.*]], %{{.*}} = gpu.shuffle xor %[[a]], %[[c1]], %[[c32]]
// CHECK-PROP: %[[a0:.*]] = arith.addf %[[a]], %[[r0]]
-// CHECK-PROP: %[[r1:.*]], %{{.*}} = gpu.shuffle xor %[[a0]], %[[c2]], %[[c32]]
+// CHECK-PROP: %[[r1:.*]], %{{.*}} = gpu.shuffle xor %[[a0]], %[[c2]], %[[c32]]
// CHECK-PROP: %[[a1:.*]] = arith.addf %[[a0]], %[[r1]]
-// CHECK-PROP: %[[r2:.*]], %{{.*}} = gpu.shuffle xor %[[a1]], %[[c4]], %[[c32]]
+// CHECK-PROP: %[[r2:.*]], %{{.*}} = gpu.shuffle xor %[[a1]], %[[c4]], %[[c32]]
// CHECK-PROP: %[[a2:.*]] = arith.addf %[[a1]], %[[r2]]
-// CHECK-PROP: %[[r3:.*]], %{{.*}} = gpu.shuffle xor %[[a2]], %[[c8]], %[[c32]]
+// CHECK-PROP: %[[r3:.*]], %{{.*}} = gpu.shuffle xor %[[a2]], %[[c8]], %[[c32]]
// CHECK-PROP: %[[a3:.*]] = arith.addf %[[a2]], %[[r3]]
-// CHECK-PROP: %[[r4:.*]], %{{.*}} = gpu.shuffle xor %[[a3]], %[[c16]], %[[c32]]
+// CHECK-PROP: %[[r4:.*]], %{{.*}} = gpu.shuffle xor %[[a3]], %[[c16]], %[[c32]]
// CHECK-PROP: %[[a4:.*]] = arith.addf %[[a3]], %[[r4]]
// CHECK-PROP: %[[a5:.*]] = arith.addf %[[a4]], %[[warp_op]]#1
// CHECK-PROP: return %[[a5]] : f32
@@ -926,7 +926,7 @@ func.func @warp_constant(%laneid: index) -> (vector<1xf32>) {
// CHECK-PROP: gpu.yield %[[V]] : vector<64xf32>
// CHECK-PROP: }
// CHECK-PROP: %[[E:.*]] = vector.extract %[[R]][1] : f32 from vector<2xf32>
-// CHECK-PROP: %[[SHUFFLED:.*]], %{{.*}} = gpu.shuffle idx %[[E]], %[[C5_I32]]
+// CHECK-PROP: %[[SHUFFLED:.*]], %{{.*}} = gpu.shuffle idx %[[E]], %[[C5_I32]]
// CHECK-PROP: return %[[SHUFFLED]] : f32
func.func @vector_extract_1d(%laneid: index) -> (f32) {
%r = gpu.warp_execute_on_lane_0(%laneid)[32] -> (f32) {
@@ -1061,7 +1061,7 @@ func.func @vector_extract_1element(%laneid: index) -> (f32) {
// CHECK-PROP: %[[DISTR_POS:.*]] = affine.apply #[[$map1]]()[%[[POS]]]
// CHECK-PROP: %[[EXTRACTED:.*]] = vector.extract %[[W]][%[[DISTR_POS]]] : f32 from vector<3xf32>
// CHECK-PROP: %[[FROM_LANE_I32:.*]] = arith.index_cast %[[FROM_LANE]] : index to i32
-// CHECK-PROP: %[[SHUFFLED:.*]], %{{.*}} = gpu.shuffle idx %[[EXTRACTED]], %[[FROM_LANE_I32]], %[[C32]] : f32
+// CHECK-PROP: %[[SHUFFLED:.*]], %{{.*}} = gpu.shuffle idx %[[EXTRACTED]], %[[FROM_LANE_I32]], %[[C32]] : f32
// CHECK-PROP: return %[[SHUFFLED]]
func.func @vector_extract_1d(%laneid: index, %pos: index) -> (f32) {
%r = gpu.warp_execute_on_lane_0(%laneid)[32] -> (f32) {
diff --git a/mlir/test/Dialect/XeGPU/sg-to-wi-experimental-unit.mlir b/mlir/test/Dialect/XeGPU/sg-to-wi-experimental-unit.mlir
index bc36554f5c266..5709ddc6c3403 100644
--- a/mlir/test/Dialect/XeGPU/sg-to-wi-experimental-unit.mlir
+++ b/mlir/test/Dialect/XeGPU/sg-to-wi-experimental-unit.mlir
@@ -267,19 +267,19 @@ gpu.func @scatter_ops_with_leading_dims(%src: memref<256xf16>) {
// CHECK: %[[LANE_RED:.*]] = vector.reduction <add>, %[[CAST:.*]] : vector<2xf32> into f32
// CHECK-DAG: %[[C16_1:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C1:.*]] = arith.constant 1 : i32
-// CHECK: %[[SHUFFLE1:.*]], %{{.*}} = gpu.shuffle xor %[[LANE_RED]], %[[C1]], %[[C16_1]] : f32
+// CHECK: %[[SHUFFLE1:.*]], %{{.*}} = gpu.shuffle xor %[[LANE_RED]], %[[C1]], %[[C16_1]] : f32
// CHECK: %[[ADD1:.*]] = arith.addf %[[LANE_RED]], %[[SHUFFLE1]] : f32
// CHECK-DAG: %[[C16_2:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C2:.*]] = arith.constant 2 : i32
-// CHECK: %[[SHUFFLE2:.*]], %{{.*}} = gpu.shuffle xor %[[ADD1]], %[[C2]], %[[C16_2]] : f32
+// CHECK: %[[SHUFFLE2:.*]], %{{.*}} = gpu.shuffle xor %[[ADD1]], %[[C2]], %[[C16_2]] : f32
// CHECK: %[[ADD2:.*]] = arith.addf %[[ADD1]], %[[SHUFFLE2]] : f32
// CHECK-DAG: %[[C16_3:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C4:.*]] = arith.constant 4 : i32
-// CHECK: %[[SHUFFLE3:.*]], %{{.*}} = gpu.shuffle xor %[[ADD2]], %[[C4]], %[[C16_3]] : f32
+// CHECK: %[[SHUFFLE3:.*]], %{{.*}} = gpu.shuffle xor %[[ADD2]], %[[C4]], %[[C16_3]] : f32
// CHECK: %[[ADD3:.*]] = arith.addf %[[ADD2]], %[[SHUFFLE3]] : f32
// CHECK-DAG: %[[C16_4:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C8:.*]] = arith.constant 8 : i32
-// CHECK: %[[SHUFFLE4:.*]], %{{.*}} = gpu.shuffle xor %[[ADD3]], %[[C8]], %[[C16_4]] : f32
+// CHECK: %[[SHUFFLE4:.*]], %{{.*}} = gpu.shuffle xor %[[ADD3]], %[[C8]], %[[C16_4]] : f32
// CHECK: %[[ADD4:.*]] = arith.addf %[[ADD3]], %[[SHUFFLE4]] : f32
// CHECK: %[[FINAL:.*]] = arith.addf %[[ADD4]], %[[CST]] : f32
gpu.func @vector_reduction() {
@@ -300,19 +300,19 @@ gpu.func @vector_reduction() {
// CHECK: %[[V3:.*]] = vector.reduction <add>, %[[V1]] : vector<1xf32> into f32
// CHECK-DAG: %[[C16:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C1:.*]] = arith.constant 1 : i32
-// CHECK: %[[SHUFFLE1:.*]], %{{.*}} = gpu.shuffle xor %[[V3]], %[[C1]], %[[C16]] : f32
+// CHECK: %[[SHUFFLE1:.*]], %{{.*}} = gpu.shuffle xor %[[V3]], %[[C1]], %[[C16]] : f32
// CHECK: %[[V4:.*]] = arith.addf %[[V3]], %[[SHUFFLE1]] : f32
// CHECK-DAG: %[[C16_2:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C2:.*]] = arith.constant 2 : i32
-// CHECK: %[[SHUFFLE2:.*]], %{{.*}} = gpu.shuffle xor %[[V4]], %[[C2]], %[[C16_2]] : f32
+// CHECK: %[[SHUFFLE2:.*]], %{{.*}} = gpu.shuffle xor %[[V4]], %[[C2]], %[[C16_2]] : f32
// CHECK: %[[V5:.*]] = arith.addf %[[V4]], %[[SHUFFLE2]] : f32
// CHECK-DAG: %[[C16_3:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C4:.*]] = arith.constant 4 : i32
-// CHECK: %[[SHUFFLE3:.*]], %{{.*}} = gpu.shuffle xor %[[V5]], %[[C4]], %[[C16_3]] : f32
+// CHECK: %[[SHUFFLE3:.*]], %{{.*}} = gpu.shuffle xor %[[V5]], %[[C4]], %[[C16_3]] : f32
// CHECK: %[[V6:.*]] = arith.addf %[[V5]], %[[SHUFFLE3]] : f32
// CHECK-DAG: %[[C16_4:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C8:.*]] = arith.constant 8 : i32
-// CHECK: %[[SHUFFLE4:.*]], %{{.*}} = gpu.shuffle xor %[[V6]], %[[C8]], %[[C16_4]] : f32
+// CHECK: %[[SHUFFLE4:.*]], %{{.*}} = gpu.shuffle xor %[[V6]], %[[C8]], %[[C16_4]] : f32
// CHECK: %[[V7:.*]] = arith.addf %[[V6]], %[[SHUFFLE4]] : f32
// CHECK: %[[V8:.*]] = arith.addf %[[V7]], %[[V2]] : f32
// CHECK: %[[V9:.*]] = vector.insert %[[V8]], %[[CST_1]] [0] : f32 into vector<2xf32>
@@ -322,19 +322,19 @@ gpu.func @vector_reduction() {
// CHECK: %[[V13:.*]] = vector.reduction <add>, %[[V11]] : vector<1xf32> into f32
// CHECK-DAG: %[[C16_5:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C1_2:.*]] = arith.constant 1 : i32
-// CHECK: %[[SHUFFLE5:.*]], %{{.*}} = gpu.shuffle xor %[[V13]], %[[C1_2]], %[[C16_5]] : f32
+// CHECK: %[[SHUFFLE5:.*]], %{{.*}} = gpu.shuffle xor %[[V13]], %[[C1_2]], %[[C16_5]] : f32
// CHECK: %[[V14:.*]] = arith.addf %[[V13]], %[[SHUFFLE5]] : f32
// CHECK-DAG: %[[C16_6:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C2_2:.*]] = arith.constant 2 : i32
-// CHECK: %[[SHUFFLE6:.*]], %{{.*}} = gpu.shuffle xor %[[V14]], %[[C2_2]], %[[C16_6]] : f32
+// CHECK: %[[SHUFFLE6:.*]], %{{.*}} = gpu.shuffle xor %[[V14]], %[[C2_2]], %[[C16_6]] : f32
// CHECK: %[[V15:.*]] = arith.addf %[[V14]], %[[SHUFFLE6]] : f32
// CHECK-DAG: %[[C16_7:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C4_2:.*]] = arith.constant 4 : i32
-// CHECK: %[[SHUFFLE7:.*]], %{{.*}} = gpu.shuffle xor %[[V15]], %[[C4_2]], %[[C16_7]] : f32
+// CHECK: %[[SHUFFLE7:.*]], %{{.*}} = gpu.shuffle xor %[[V15]], %[[C4_2]], %[[C16_7]] : f32
// CHECK: %[[V16:.*]] = arith.addf %[[V15]], %[[SHUFFLE7]] : f32
// CHECK-DAG: %[[C16_8:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C8_2:.*]] = arith.constant 8 : i32
-// CHECK: %[[SHUFFLE8:.*]], %{{.*}} = gpu.shuffle xor %[[V16]], %[[C8_2]], %[[C16_8]] : f32
+// CHECK: %[[SHUFFLE8:.*]], %{{.*}} = gpu.shuffle xor %[[V16]], %[[C8_2]], %[[C16_8]] : f32
// CHECK: %[[V17:.*]] = arith.addf %[[V16]], %[[SHUFFLE8]] : f32
// CHECK: %[[V18:.*]] = arith.addf %[[V17]], %[[V12]] : f32
// CHECK: %[[V19:.*]] = vector.insert %[[V18]], %[[V9]] [1] : f32 into vector<2xf32>
@@ -365,19 +365,19 @@ gpu.func @vector_multi_reduction_dim1_distributed_dim1_reduction(%laneid: index)
// CHECK: %[[V3:.*]] = vector.reduction <add>, %[[V1]] : vector<1xf32> into f32
// CHECK-DAG: %[[C16:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C1:.*]] = arith.constant 1 : i32
-// CHECK: %[[SHUFFLE1:.*]], %{{.*}} = gpu.shuffle xor %[[V3]], %[[C1]], %[[C16]] : f32
+// CHECK: %[[SHUFFLE1:.*]], %{{.*}} = gpu.shuffle xor %[[V3]], %[[C1]], %[[C16]] : f32
// CHECK: %[[V4:.*]] = arith.addf %[[V3]], %[[SHUFFLE1:.*]] : f32
// CHECK-DAG: %[[C16_2:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C2:.*]] = arith.constant 2 : i32
-// CHECK: %[[SHUFFLE2:.*]], %{{.*}} = gpu.shuffle xor %[[V4]], %[[C2]], %[[C16_2]] : f32
+// CHECK: %[[SHUFFLE2:.*]], %{{.*}} = gpu.shuffle xor %[[V4]], %[[C2]], %[[C16_2]] : f32
// CHECK: %[[V5:.*]] = arith.addf %[[V4]], %[[SHUFFLE2]] : f32
// CHECK-DAG: %[[C16_3:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C4:.*]] = arith.constant 4 : i32
-// CHECK: %[[SHUFFLE3:.*]], %{{.*}} = gpu.shuffle xor %[[V5]], %[[C4]], %[[C16_3]] : f32
+// CHECK: %[[SHUFFLE3:.*]], %{{.*}} = gpu.shuffle xor %[[V5]], %[[C4]], %[[C16_3]] : f32
// CHECK: %[[V6:.*]] = arith.addf %[[V5]], %[[SHUFFLE3]] : f32
// CHECK-DAG: %[[C16_4:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C8:.*]] = arith.constant 8 : i32
-// CHECK: %[[SHUFFLE4:.*]], %{{.*}} = gpu.shuffle xor %[[V6]], %[[C8]], %[[C16_4]] : f32
+// CHECK: %[[SHUFFLE4:.*]], %{{.*}} = gpu.shuffle xor %[[V6]], %[[C8]], %[[C16_4]] : f32
// CHECK: %[[V7:.*]] = arith.addf %[[V6]], %[[SHUFFLE4]] : f32
// CHECK: %[[V8:.*]] = arith.addf %[[V7]], %[[V2]] : f32
// CHECK: %[[V9:.*]] = vector.insert %[[V8]], %[[CST_1]] [0] : f32 into vector<2xf32>
@@ -387,19 +387,19 @@ gpu.func @vector_multi_reduction_dim1_distributed_dim1_reduction(%laneid: index)
// CHECK: %[[V13:.*]] = vector.reduction <add>, %[[V11]] : vector<1xf32> into f32
// CHECK-DAG: %[[C16_5:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C1_2:.*]] = arith.constant 1 : i32
-// CHECK: %[[SHUFFLE5:.*]], %{{.*}} = gpu.shuffle xor %[[V13]], %[[C1_2]], %[[C16_5]] : f32
+// CHECK: %[[SHUFFLE5:.*]], %{{.*}} = gpu.shuffle xor %[[V13]], %[[C1_2]], %[[C16_5]] : f32
// CHECK: %[[V14:.*]] = arith.addf %[[V13]], %[[SHUFFLE5]] : f32
// CHECK-DAG: %[[C16_6:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C2_2:.*]] = arith.constant 2 : i32
-// CHECK: %[[SHUFFLE6:.*]], %{{.*}} = gpu.shuffle xor %[[V14]], %[[C2_2]], %[[C16_6]] : f32
+// CHECK: %[[SHUFFLE6:.*]], %{{.*}} = gpu.shuffle xor %[[V14]], %[[C2_2]], %[[C16_6]] : f32
// CHECK: %[[V15:.*]] = arith.addf %[[V14]], %[[SHUFFLE6]] : f32
// CHECK-DAG: %[[C16_7:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C4_2:.*]] = arith.constant 4 : i32
-// CHECK: %[[SHUFFLE7:.*]], %{{.*}} = gpu.shuffle xor %[[V15]], %[[C4_2]], %[[C16_7]] : f32
+// CHECK: %[[SHUFFLE7:.*]], %{{.*}} = gpu.shuffle xor %[[V15]], %[[C4_2]], %[[C16_7]] : f32
// CHECK: %[[V16:.*]] = arith.addf %[[V15]], %[[SHUFFLE7]] : f32
// CHECK-DAG: %[[C16_8:.*]] = arith.constant 16 : i32
// CHECK-DAG: %[[C8_2:.*]] = arith.constant 8 : i32
-// CHECK: %[[SHUFFLE8:.*]], %{{.*}} = gpu.shuffle xor %[[V16]], %[[C8_2]], %[[C16_8]] : f32
+// CHECK: %[[SHUFFLE8:.*]], %{{.*}} = gpu.shuffle xor %[[V16]], %[[C8_2]], %[[C16_8]] : f32
// CHECK: %[[V17:.*]] = arith.addf %[[V16]], %[[SHUFFLE8]] : f32
// CHECK: %[[V18:.*]] = arith.addf %[[V17]], %[[V12]] : f32
// CHECK: %[[V19:.*]] = vector.insert %[[V18]], %[[V9]] [1] : f32 into vector<2xf32>
diff --git a/mlir/test/IR/array-of-attr.mlir b/mlir/test/IR/array-of-attr.mlir
index ad046eb8d1a07..2c7b5009f74a2 100644
--- a/mlir/test/IR/array-of-attr.mlir
+++ b/mlir/test/IR/array-of-attr.mlir
@@ -2,7 +2,7 @@
// CHECK: test.array_of_attr_op
test.array_of_attr_op
- // CHECK-SAME: a = [ begin 0 : index end, begin 2 : index end ]
+ // CHECK-SAME: a = [begin 0 : index end, begin 2 : index end ]
a = [begin 0 : index end, begin 2 : index end],
// CHECK-SAME: [0, 1, -42, 42]
b = [0, 1, -42, 42],
diff --git a/mlir/test/mlir-tblgen/attr-or-type-format-roundtrip.mlir b/mlir/test/mlir-tblgen/attr-or-type-format-roundtrip.mlir
index 35554b20fbece..9bb333f88dab1 100644
--- a/mlir/test/mlir-tblgen/attr-or-type-format-roundtrip.mlir
+++ b/mlir/test/mlir-tblgen/attr-or-type-format-roundtrip.mlir
@@ -5,9 +5,9 @@
// CHECK: !test.type_with_format<2147, three = "hi", two = "hi">
func.func private @test_roundtrip_parameter_parsers(!test.type_with_format<111, three = #test<attr_ugly begin 5 : index end>, two = "foo">) -> !test.type_with_format<2147, two = "hi", three = "hi">
attributes {
- // CHECK: #test.attr_with_format<3 : two = "hello", four = [1, 2, 3] : 42 : i64 : 0 : [4, 5, 6], [ 10 : i16]
+ // CHECK: #test.attr_with_format<3 : two = "hello", four = [1, 2, 3] : 42 : i64 : 0 : [4, 5, 6], [10 : i16]
attr0 = #test.attr_with_format<3 : two = "hello", four = [1, 2, 3] : 42 : i64 : 0 : [4, 5, 6], [10 : i16]>,
- // CHECK: #test.attr_with_format<5 : two = "a_string", four = [4, 5, 6, 7, 8] : 8 : i8 : 255 : [9, 10, 11], [ 10 : i16]>,
+ // CHECK: #test.attr_with_format<5 : two = "a_string", four = [4, 5, 6, 7, 8] : 8 : i8 : 255 : [9, 10, 11], [10 : i16]>,
attr1 = #test.attr_with_format<5 : two = "a_string", four = [4, 5, 6, 7, 8] : 8 : i8 : 255 : [9, 10, 11], [10 : i16]>,
// CHECK: #test<attr_ugly begin 5 : index end>
attr2 = #test<attr_ugly begin 5 : index end>,
diff --git a/mlir/test/mlir-tblgen/attr-or-type-format.td b/mlir/test/mlir-tblgen/attr-or-type-format.td
index 70c335f2f826c..0a28b303bd220 100644
--- a/mlir/test/mlir-tblgen/attr-or-type-format.td
+++ b/mlir/test/mlir-tblgen/attr-or-type-format.td
@@ -2,6 +2,32 @@
// RUN: sed 's/DEFAULT_TYPE_PARSER/0/' %s | mlir-tblgen -gen-typedef-defs -typedefs-dialect=TestDialect -I %S/../../include | FileCheck %s --check-prefix=TYPE
// RUN: sed 's/DEFAULT_TYPE_PARSER/1/' %s | mlir-tblgen -gen-typedef-defs -typedefs-dialect=TestDialect -I %S/../../include | FileCheck %s --check-prefix=TYPE --check-prefix=DEFAULT_TYPE_PARSER
+/// Verify the generated printer dispatcher conditionally emits a space between
+/// the mnemonic and t.print(printer). A space is needed when the format starts
+/// with a non-punctuation element; no space when it starts with `<`, `{`, etc.
+
+// Format starts with `$value` (variable): dispatcher adds a space.
+// ATTR-LABEL: .Case<::test::TestEnumBAttr>([&](auto t)
+// ATTR-NEXT: printer << ::test::TestEnumBAttr::getMnemonic();
+// ATTR-NEXT: printer << ' ';
+// ATTR-NEXT: t.print(printer);
+
+// Format starts with `{` (punctuation literal): dispatcher does not add a space.
+// ATTR-LABEL: .Case<::test::TestTAttr>([&](auto t)
+// ATTR-NEXT: printer << ::test::TestTAttr::getMnemonic();
+// ATTR-NEXT: t.print(printer);
+
+// Format starts with `{` (punctuation literal): dispatcher does not add a space.
+// TYPE-LABEL: .Case<::test::TestEType>([&](auto t)
+// TYPE-NEXT: printer << ::test::TestEType::getMnemonic();
+// TYPE-NEXT: t.print(printer);
+
+// Format starts with `$a` (variable): dispatcher adds a space.
+// TYPE-LABEL: .Case<::test::TestSType>([&](auto t)
+// TYPE-NEXT: printer << ::test::TestSType::getMnemonic();
+// TYPE-NEXT: printer << ' ';
+// TYPE-NEXT: t.print(printer);
+
include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/BuiltinAttributes.td"
include "mlir/IR/EnumAttr.td"
@@ -64,7 +90,7 @@ def TypeParamB : TypeParameter<"TestParamD", "a type param D"> {
// ATTR: }
// ATTR: void TestAAttr::print(::mlir::AsmPrinter &odsPrinter) const {
-// ATTR: odsPrinter << ' ' << "hello";
+// ATTR: odsPrinter << "hello";
// ATTR: odsPrinter << ' ' << "=";
// ATTR: odsPrinter << ' ';
// ATTR: odsPrinter.printStrippedAttrOrType(getValue());
@@ -273,7 +299,7 @@ def EnumAttrB : EnumAttr<Test_Dialect, TestEnumB, "EnumAttrB"> {
// TYPE: }
// TYPE: void TestCType::print(::mlir::AsmPrinter &odsPrinter) const {
-// TYPE: odsPrinter << ' ' << "foo";
+// TYPE: odsPrinter << "foo";
// TYPE: odsPrinter << ",";
// TYPE: odsPrinter << ' ' << ":";
// TYPE: odsPrinter << ' ' << "bob";
@@ -462,7 +488,6 @@ def TypeC : TestType<"TestE"> {
// TYPE: void TestFType::print(::mlir::AsmPrinter &odsPrinter) const {
// TYPE if (getA()) {
-// TYPE odsPrinter << ' ';
// TYPE odsPrinter.printStrippedAttrOrType(getA());
def TypeD : TestType<"TestF"> {
let parameters = (ins OptionalParameter<"int">:$a);
@@ -546,7 +571,7 @@ def TypeG : TestType<"TestI"> {
// TYPE: odsPrinter.printStrippedAttrOrType(getB());
// TYPE: odsPrinter << ")";
// TYPE: } else {
-// TYPE: odsPrinter << ' ' << "x";
+// TYPE: odsPrinter << "x";
// TYPE: }
// TYPE: odsPrinter.printStrippedAttrOrType(getA());
@@ -631,7 +656,7 @@ def TypeL : TestType<"TestN"> {
// TYPE-LABEL: void TestOType::print
// TYPE: if (!(!(getA() == int())))
-// TYPE: odsPrinter << ' ' << "?"
+// TYPE: odsPrinter << "?"
// TYPE: else
// TYPE: odsPrinter.printStrippedAttrOrType(getA())
diff --git a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
index 031e03071842f..9d04264dfc2ff 100644
--- a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
+++ b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
@@ -1099,9 +1099,44 @@ void DefGenerator::emitParsePrintDispatch(ArrayRef<AttrOrTypeDef> defs) {
parse.body() << llvm::formatv(getValueForMnemonic, defClass, parseOrGet);
// If the def has no parameters and no printer, just print the mnemonic.
- StringRef printDef = "";
- if (hasParserPrinterDecl)
+ std::string printDef;
+ if (def.hasCustomAssemblyFormat()) {
+ // Custom format: the user's print() controls its own spacing.
printDef = "\nt.print(printer);";
+ } else if (auto fmt = def.getAssemblyFormat()) {
+ // Declarative format: since print() no longer emits a leading space,
+ // add one here unless the format starts with punctuation or a
+ // space-eraser directive that should attach directly to the mnemonic.
+ //
+ // '(' starts an optional group, not a literal paren. Treating it as
+ // "no space needed" is correct when the first printed element inside
+ // the group is punctuation (the only in-tree case today, e.g.
+ // TBAARootAttr: `(`<` struct(params)^ `>`)?`). If a future attr/type
+ // has an optional group whose first element is a variable or keyword,
+ // this heuristic will incorrectly suppress the space.
+ // TODO: Query the parsed DefFormat structure instead of inspecting the
+ // raw format string to handle this case properly.
+ //
+ // Note: bare '<', '{', '[' cannot appear at position 0 of a valid
+ // format string (the format lexer rejects them); they must be
+ // backtick-quoted (e.g. `<`), which is handled by the '`' case below.
+ StringRef fmtStr = fmt->trim();
+ bool needsSpace = !fmtStr.empty();
+ if (needsSpace) {
+ char first = fmtStr[0];
+ // '(' starts an optional group (see NOTE above).
+ if (first == '(')
+ needsSpace = false;
+ // Backtick-quoted literal (e.g. `<`, `{`, `[`) or space-eraser (``)
+ else if (first == '`' && fmtStr.size() >= 2 &&
+ StringRef("<{([`").contains(fmtStr[1]))
+ needsSpace = false;
+ }
+ if (needsSpace)
+ printDef = "\nprinter << ' ';\nt.print(printer);";
+ else
+ printDef = "\nt.print(printer);";
+ }
printer.body() << llvm::formatv(printValue, defClass, printDef);
}
parse.body() << " .Default([&](llvm::StringRef keyword, llvm::SMLoc) {\n"
diff --git a/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp
index 348026eb99b00..9c12cf59ed083 100644
--- a/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp
+++ b/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp
@@ -751,9 +751,14 @@ void DefFormat::genPrinter(MethodBody &os) {
os.indent();
os << "::mlir::Builder odsBuilder(getContext());\n";
- // Generate printers.
- shouldEmitSpace = true;
- lastWasPunctuation = false;
+ // Start with no leading space: the generated dispatcher
+ // (generatedAttributePrinter/generatedTypePrinter in AttrOrTypeDefGen.cpp)
+ // is responsible for emitting any space between the mnemonic and the first
+ // printed element. Set lastWasPunctuation = true so that the
+ // `!lastWasPunctuation` term in genVariablePrinter/genCustomPrinter also
+ // evaluates to false, fully suppressing any leading space from those paths.
+ shouldEmitSpace = false;
+ lastWasPunctuation = true;
for (FormatElement *el : elements)
genElementPrinter(el, ctx, os);
}
More information about the Mlir-commits
mailing list