[Mlir-commits] [mlir] 64bccb9 - [mlir][bytecode] Allow selecting dialect versions in mlir-opt (#233149)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Oct 20 01:56:24 PDT 2026
Author: Mehdi Amini
Date: 2026-10-20T10:56:18+02:00
New Revision: 64bccb9d9ac016ec576971b1591fd8e82e7be801
URL: https://github.com/llvm/llvm-project/commit/64bccb9d9ac016ec576971b1591fd8e82e7be801
DIFF: https://github.com/llvm/llvm-project/commit/64bccb9d9ac016ec576971b1591fd8e82e7be801.diff
LOG: [mlir][bytecode] Allow selecting dialect versions in mlir-opt (#233149)
Added:
mlir/test/Bytecode/versioning/emit-builtin-version-dlti.mlir
mlir/test/Bytecode/versioning/emit-dialect-version.mlir
mlir/test/Bytecode/versioning/emit-test-version-lossy.mlir
mlir/test/Dialect/Builtin/Bytecode/builtin_fixed_1.mlirbc
Modified:
mlir/docs/BytecodeFormat.md
mlir/include/mlir/Bytecode/BytecodeDialectInterface.td
mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
mlir/lib/Bytecode/Writer/BytecodeWriter.cpp
mlir/lib/IR/BuiltinDialectBytecode.cpp
mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
mlir/test/Bytecode/bytecode_downgrade.mlir
mlir/test/Bytecode/versioning/versioned_op_with_native_properties.mlir
mlir/test/Dialect/Builtin/Bytecode/builtin_fixed.mlir
mlir/test/Dialect/Builtin/Bytecode/builtin_fixed_0.mlirbc
mlir/test/lib/Dialect/Test/TestDialectInterfaces.cpp
mlir/test/lib/Dialect/Test/TestOpDefs.cpp
Removed:
################################################################################
diff --git a/mlir/docs/BytecodeFormat.md b/mlir/docs/BytecodeFormat.md
index f50ddeb25cc332..27ce718fa3a62a 100644
--- a/mlir/docs/BytecodeFormat.md
+++ b/mlir/docs/BytecodeFormat.md
@@ -21,6 +21,18 @@ upgrades post-parsing through the `upgradeFromVersion` method.
There is no restriction on what kind of information a dialect
is allowed to encode to model its versioning.
+When emitting bytecode, `mlir-opt --emit-bytecode-version=<version>` selects the
+overall bytecode format version. Dialect versions are selected separately with
+`--emit-bytecode-dialect-version=<dialect>=<version>`, which may be repeated for
+
diff erent dialects. For example, `mlir-opt --emit-bytecode
+--emit-bytecode-dialect-version=builtin=0` selects the historical builtin dialect
+encoding. A dialect must implement `BytecodeDialectInterface::parseVersion` to
+accept a version string; the dialect defines its syntax and supported versions.
+The resulting version object is passed to the bytecode writer through
+`BytecodeWriterConfig::setDialectVersion`. Before emission, the writer invokes
+`BytecodeDialectInterface::verifyVersion` for explicitly selected versions so
+dialects can reject IR that cannot be represented without losing information.
+
[TOC]
## Magic Number
diff --git a/mlir/include/mlir/Bytecode/BytecodeDialectInterface.td b/mlir/include/mlir/Bytecode/BytecodeDialectInterface.td
index f06715e2339604..11d9b4db7cb940 100644
--- a/mlir/include/mlir/Bytecode/BytecodeDialectInterface.td
+++ b/mlir/include/mlir/Bytecode/BytecodeDialectInterface.td
@@ -57,6 +57,27 @@ def BytecodeDialectInterface : DialectInterface<"BytecodeDialectInterface"> {
return ::llvm::failure();
}]
>,
+ InterfaceMethod<[{
+ Parse a target dialect version for bytecode emission from a string, for
+ example from a command-line option. Return null if the version is invalid
+ or unsupported. The dialect defines the syntax of the version string.
+ }],
+ "std::unique_ptr<::mlir::DialectVersion>", "parseVersion",
+ (ins "::llvm::StringRef":$version),
+ [{ return nullptr; }]
+ >,
+ InterfaceMethod<[{
+ Verify that the given operation and its nested IR can be emitted for the
+ requested dialect version without losing information. This hook is
+ invoked before bytecode emission when a target version is explicitly
+ configured. Emit a diagnostic and return failure if the IR cannot be
+ represented in that version.
+ }],
+ "::llvm::LogicalResult", "verifyVersion",
+ (ins "::mlir::Operation *":$topLevelOp,
+ "const ::mlir::DialectVersion &":$version),
+ [{ return ::llvm::success(); }]
+ >,
InterfaceMethod<[{
Write the version of this dialect to the given writer.
}],
diff --git a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
index 7e0b7024608c91..e6697b376fa005 100644
--- a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
+++ b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
@@ -15,6 +15,7 @@
#include "mlir/Debug/CLOptionsSetup.h"
#include "mlir/Support/ToolUtilities.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include <cstdlib>
@@ -128,6 +129,17 @@ class MlirOptMainConfig {
return emitBytecodeVersion;
}
+ /// Set target dialect versions as strings of the form "dialect=version".
+ /// The dialect defines the syntax of its version string.
+ MlirOptMainConfig &
+ setEmitBytecodeDialectVersions(ArrayRef<std::string> versions) {
+ emitBytecodeDialectVersions.assign(versions.begin(), versions.end());
+ return *this;
+ }
+ ArrayRef<std::string> bytecodeDialectVersionsToEmit() const {
+ return emitBytecodeDialectVersions;
+ }
+
/// Set the bytecode producer to use.
MlirOptMainConfig &emitBytecodeProducer(StringRef producer) {
emitBytecodeProducerFlag = producer.str();
@@ -320,6 +332,9 @@ class MlirOptMainConfig {
/// Emit bytecode at given version.
std::optional<int64_t> emitBytecodeVersion = std::nullopt;
+ /// Target dialect versions for bytecode emission, as "dialect=version".
+ std::vector<std::string> emitBytecodeDialectVersions;
+
/// Emit bytecode with given producer.
std::string emitBytecodeProducerFlag = "";
diff --git a/mlir/lib/Bytecode/Writer/BytecodeWriter.cpp b/mlir/lib/Bytecode/Writer/BytecodeWriter.cpp
index 89aa731c5cca05..8cd4658d804765 100644
--- a/mlir/lib/Bytecode/Writer/BytecodeWriter.cpp
+++ b/mlir/lib/Bytecode/Writer/BytecodeWriter.cpp
@@ -13,6 +13,7 @@
#include "mlir/Bytecode/Encoding.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Diagnostics.h"
+#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/OpImplementation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/CachedHashString.h"
@@ -1373,6 +1374,16 @@ void BytecodeWriter::writePropertiesSection(EncodingEmitter &emitter) {
LogicalResult mlir::writeBytecodeToFile(Operation *op, raw_ostream &os,
const BytecodeWriterConfig &config) {
+ // Validate before numbering the IR, which may invoke dialect writers.
+ for (const auto &entry : config.getDialectVersionMap()) {
+ Dialect *dialect = op->getContext()->getLoadedDialect(entry.getKey());
+ if (!dialect)
+ continue;
+ auto *interface =
+ dialect->getRegisteredInterface<BytecodeDialectInterface>();
+ if (interface && failed(interface->verifyVersion(op, *entry.getValue())))
+ return failure();
+ }
BytecodeWriter writer(op, config);
return writer.write(op, os);
}
diff --git a/mlir/lib/IR/BuiltinDialectBytecode.cpp b/mlir/lib/IR/BuiltinDialectBytecode.cpp
index e5476082cd6a04..1390769dd8e6ff 100644
--- a/mlir/lib/IR/BuiltinDialectBytecode.cpp
+++ b/mlir/lib/IR/BuiltinDialectBytecode.cpp
@@ -13,6 +13,7 @@
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/BuiltinDialect.h"
+#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Diagnostics.h"
#include "mlir/IR/DialectResourceBlobManager.h"
@@ -578,13 +579,38 @@ struct BuiltinDialectBytecodeInterface : public BytecodeDialectInterface {
//===--------------------------------------------------------------------===//
// Version
+ std::unique_ptr<DialectVersion>
+ parseVersion(StringRef version) const override {
+ int64_t parsedVersion;
+ if (version.getAsInteger(10, parsedVersion) || parsedVersion < 0 ||
+ parsedVersion > BuiltinDialectVersion::getCurrentVersion().getVersion())
+ return nullptr;
+ return std::make_unique<BuiltinDialectVersion>(parsedVersion);
+ }
+
+ LogicalResult verifyVersion(Operation *topLevelOp,
+ const DialectVersion &version) const override {
+ if (static_cast<const BuiltinDialectVersion &>(version).getVersion() >= 1)
+ return success();
+ WalkResult result = topLevelOp->walk([](ModuleOp module) {
+ if (!module.getDltiAttr())
+ return WalkResult::advance();
+ module.emitOpError("cannot emit builtin dialect version 0 with a 'dlti' "
+ "property");
+ return WalkResult::interrupt();
+ });
+ return failure(result.wasInterrupted());
+ }
+
void writeVersion(DialectBytecodeWriter &writer) const override {
auto configVersion = writer.getDialectVersion(getDialect()->getNamespace());
// Write version set in config.
if (succeeded(configVersion)) {
auto *version =
static_cast<const BuiltinDialectVersion *>(*configVersion);
- writer.writeVarInt(static_cast<uint64_t>(version->getVersion()));
+ // Version 0 predates dialect version metadata. Preserve its encoding.
+ if (version->getVersion() > 0)
+ writer.writeVarInt(static_cast<uint64_t>(version->getVersion()));
return;
}
// Else, write current set version version if not 0.
diff --git a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
index d4812aec50fc19..490e0c20f86f6c 100644
--- a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
+++ b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "mlir/Tools/mlir-opt/MlirOptMain.h"
+#include "mlir/Bytecode/BytecodeImplementation.h"
#include "mlir/Bytecode/BytecodeWriter.h"
#include "mlir/Debug/CLOptionsSetup.h"
#include "mlir/Debug/Counter.h"
@@ -36,6 +37,7 @@
#include "mlir/Tools/Plugins/PassPlugin.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/Remarks/RemarkFormat.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -107,6 +109,15 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
cl::desc("Use specified bytecode when generating output"),
cl::location(emitBytecodeVersion), cl::init(std::nullopt));
+ static cl::list<std::string, std::vector<std::string>>
+ bytecodeDialectVersions(
+ "emit-bytecode-dialect-version",
+ cl::desc(
+ "Use the specified dialect version when generating bytecode "
+ "(may be repeated for
diff erent dialects)"),
+ cl::value_desc("dialect=version"),
+ cl::location(emitBytecodeDialectVersions));
+
static cl::opt<std::string, /*ExternalStorage=*/true> irdlFile(
"irdl-file",
cl::desc("IRDL file to register before processing the input"),
@@ -620,6 +631,30 @@ performActions(raw_ostream &os,
: BytecodeWriterConfig(fallbackResourceMap);
if (auto v = config.bytecodeVersionToEmit())
writerConfig.setDesiredBytecodeVersion(*v);
+ llvm::StringSet<> versionedDialects;
+ for (StringRef entry : config.bytecodeDialectVersionsToEmit()) {
+ auto [name, version] = entry.split('=');
+ if (name.empty() || version.empty())
+ return op.get()->emitError() << "expected 'dialect=version' for "
+ "--emit-bytecode-dialect-version, got '"
+ << entry << "'";
+ if (!versionedDialects.insert(name).second)
+ return op.get()->emitError()
+ << "duplicate bytecode version for dialect '" << name << "'";
+ Dialect *dialect = context->getOrLoadDialect(name);
+ if (!dialect)
+ return op.get()->emitError()
+ << "unknown dialect '" << name << "' for bytecode emission";
+ auto *interface =
+ dialect->getRegisteredInterface<BytecodeDialectInterface>();
+ std::unique_ptr<DialectVersion> parsedVersion =
+ interface ? interface->parseVersion(version) : nullptr;
+ if (!parsedVersion)
+ return op.get()->emitError()
+ << "dialect '" << name << "' does not support emitting bytecode "
+ << "version '" << version << "'";
+ writerConfig.setDialectVersion(name, std::move(parsedVersion));
+ }
if (config.shouldElideResourceDataFromBytecode())
writerConfig.setElideResourceDataFlag();
return writeBytecodeToFile(op.get(), os, writerConfig);
@@ -629,6 +664,10 @@ performActions(raw_ostream &os,
return emitError(UnknownLoc::get(pm.getContext()))
<< "bytecode version while not emitting bytecode";
+ if (!config.bytecodeDialectVersionsToEmit().empty())
+ return emitError(UnknownLoc::get(pm.getContext()))
+ << "dialect bytecode version while not emitting bytecode";
+
// Don't re-run the verifier if we already ran the verifier at the end of the
// pass pipeline.
AsmState asmState(op.get(),
diff --git a/mlir/test/Bytecode/bytecode_downgrade.mlir b/mlir/test/Bytecode/bytecode_downgrade.mlir
index fd98b9d7ee6a58..71decad979f0b4 100644
--- a/mlir/test/Bytecode/bytecode_downgrade.mlir
+++ b/mlir/test/Bytecode/bytecode_downgrade.mlir
@@ -4,7 +4,5 @@ module {
"test.versionedA"() <{dims = 123 : i64, modifier = false}> : () -> ()
}
-// COM: the property downgrader is executed twice: first for IR numbering and then for emission.
// CHECK: downgrading op...
-// CHECK: downgrading op properties...
-// CHECK: downgrading op properties...
+// CHECK: "test.versionedA"() <{dims = 123 : i64, modifier = false}>
diff --git a/mlir/test/Bytecode/versioning/emit-builtin-version-dlti.mlir b/mlir/test/Bytecode/versioning/emit-builtin-version-dlti.mlir
new file mode 100644
index 00000000000000..0c4cc638aafd3c
--- /dev/null
+++ b/mlir/test/Bytecode/versioning/emit-builtin-version-dlti.mlir
@@ -0,0 +1,16 @@
+// RUN: mlir-opt %s -split-input-file -emit-bytecode -emit-bytecode-dialect-version=builtin=0 -verify-diagnostics
+// RUN: mlir-opt %s -emit-bytecode -emit-bytecode-dialect-version=builtin=1 | mlir-opt | FileCheck %s
+
+// A property introduced in version 1 cannot be silently dropped for version 0.
+// CHECK: module <dlti = #dlti.map<"chip" = "sm_90">>
+// expected-error at +1 {{cannot emit builtin dialect version 0 with a 'dlti' property}}
+module <{dlti = #dlti.map<"chip" = "sm_90">}> {}
+
+// -----
+
+// Also reject DLTI properties on nested modules.
+// CHECK: module @nested <dlti = #dlti.map<"chip" = "sm_90">>
+module {
+ // expected-error at +1 {{cannot emit builtin dialect version 0 with a 'dlti' property}}
+ module @nested <{dlti = #dlti.map<"chip" = "sm_90">}> {}
+}
diff --git a/mlir/test/Bytecode/versioning/emit-dialect-version.mlir b/mlir/test/Bytecode/versioning/emit-dialect-version.mlir
new file mode 100644
index 00000000000000..ba477ad302d4b5
--- /dev/null
+++ b/mlir/test/Bytecode/versioning/emit-dialect-version.mlir
@@ -0,0 +1,36 @@
+// RUN: mlir-opt %s -emit-bytecode -emit-bytecode-producer=fixed -emit-bytecode-dialect-version=builtin=0 -emit-bytecode-dialect-version=test=2.0 -o %t.0
+// RUN: mlir-opt %s -emit-bytecode -emit-bytecode-producer=fixed -emit-bytecode-dialect-version=builtin=1 -emit-bytecode-dialect-version=test=2.0 -o %t.1
+// RUN: not cmp -s %t.0 %t.1
+// RUN: mlir-opt %t.0 | FileCheck %s
+// RUN: mlir-opt %t.1 | FileCheck %s
+// RUN: mlir-opt %s -emit-bytecode -emit-bytecode-producer=fixed -o %t.default
+// RUN: cmp -s %t.1 %t.default
+// RUN: mlir-opt %s -emit-bytecode -emit-bytecode-producer=fixed -emit-bytecode-dialect-version=builtin=1 -emit-bytecode-dialect-version=test=1.12 -o %t.old-test
+// RUN: not cmp -s %t.old-test %t.1
+// RUN: mlir-opt %t.old-test | FileCheck %s
+// RUN: mlir-opt %s -emit-bytecode -emit-bytecode-dialect-version=test=1.12 | mlir-opt | FileCheck %s
+// RUN: mlir-opt %s -emit-bytecode -emit-bytecode-version=0 -emit-bytecode-dialect-version=test=1.12 | mlir-opt | FileCheck %s
+// RUN: not mlir-opt %s -emit-bytecode-dialect-version=builtin=0 2>&1 | FileCheck %s --check-prefix=NO-BYTECODE
+// RUN: not mlir-opt %s -emit-bytecode -emit-bytecode-dialect-version=builtin 2>&1 | FileCheck %s --check-prefix=MALFORMED
+// RUN: not mlir-opt %s -emit-bytecode -emit-bytecode-dialect-version=builtin= 2>&1 | FileCheck %s --check-prefix=MALFORMED
+// RUN: not mlir-opt %s -emit-bytecode -emit-bytecode-dialect-version==0 2>&1 | FileCheck %s --check-prefix=MALFORMED
+// RUN: not mlir-opt %s -emit-bytecode -emit-bytecode-dialect-version=unknown=0 2>&1 | FileCheck %s --check-prefix=UNKNOWN
+// RUN: not mlir-opt %s -emit-bytecode -emit-bytecode-dialect-version=arith=0 2>&1 | FileCheck %s --check-prefix=UNSUPPORTED-DIALECT
+// RUN: not mlir-opt %s -emit-bytecode -emit-bytecode-dialect-version=func=1 2>&1 | FileCheck %s --check-prefix=UNSUPPORTED-PARSER
+// RUN: not mlir-opt %s -emit-bytecode -emit-bytecode-dialect-version=builtin=-1 2>&1 | FileCheck %s --check-prefix=UNSUPPORTED-VERSION
+// RUN: not mlir-opt %s -emit-bytecode -emit-bytecode-dialect-version=builtin=2 2>&1 | FileCheck %s --check-prefix=UNSUPPORTED-VERSION
+// RUN: not mlir-opt %s -emit-bytecode -emit-bytecode-dialect-version=builtin=abc 2>&1 | FileCheck %s --check-prefix=UNSUPPORTED-VERSION
+// RUN: not mlir-opt %s -emit-bytecode -emit-bytecode-dialect-version=builtin=0 -emit-bytecode-dialect-version=builtin=1 2>&1 | FileCheck %s --check-prefix=DUPLICATE
+
+// NO-BYTECODE: dialect bytecode version while not emitting bytecode
+// MALFORMED: expected 'dialect=version' for --emit-bytecode-dialect-version
+// UNKNOWN: unknown dialect 'unknown' for bytecode emission
+// UNSUPPORTED-DIALECT: dialect 'arith' does not support emitting bytecode version '0'
+// UNSUPPORTED-PARSER: dialect 'func' does not support emitting bytecode version '1'
+// UNSUPPORTED-VERSION: dialect 'builtin' does not support emitting bytecode version
+// DUPLICATE: duplicate bytecode version for dialect 'builtin'
+
+// CHECK: "test.versionedA"() <{dims = 123 : i64, modifier = false}>
+"test.versionedA"() <{dims = 123 : i64, modifier = false}> : () -> ()
+// CHECK: "test.versionedC"() <{attribute = #test.attr_params<42, 24>}>
+"test.versionedC"() <{attribute = #test.attr_params<42, 24>}> : () -> ()
diff --git a/mlir/test/Bytecode/versioning/emit-test-version-lossy.mlir b/mlir/test/Bytecode/versioning/emit-test-version-lossy.mlir
new file mode 100644
index 00000000000000..d95607cd8fe081
--- /dev/null
+++ b/mlir/test/Bytecode/versioning/emit-test-version-lossy.mlir
@@ -0,0 +1,12 @@
+// RUN: mlir-opt %s -split-input-file -emit-bytecode -emit-bytecode-dialect-version=test=1.12 -verify-diagnostics
+// RUN: mlir-opt %s -emit-bytecode -emit-bytecode-dialect-version=test=2.0 | mlir-opt | FileCheck %s
+
+// CHECK: "test.versionedA"() <{dims = 123 : i64, modifier = true}>
+// expected-error at +1 {{cannot emit test dialect versions before 2.0 with 'modifier = true'}}
+"test.versionedA"() <{dims = 123 : i64, modifier = true}> : () -> ()
+
+// -----
+
+// CHECK: test.with_versioned_properties 1 | 2
+// expected-error at +1 {{cannot emit test dialect versions before 2.0 with a nonzero 'value2' property}}
+test.with_versioned_properties 1 | 2
diff --git a/mlir/test/Bytecode/versioning/versioned_op_with_native_properties.mlir b/mlir/test/Bytecode/versioning/versioned_op_with_native_properties.mlir
index 823a559cbca146..77ae93d22fb22c 100644
--- a/mlir/test/Bytecode/versioning/versioned_op_with_native_properties.mlir
+++ b/mlir/test/Bytecode/versioning/versioned_op_with_native_properties.mlir
@@ -26,3 +26,9 @@
// COM: }
// RUN: mlir-opt %S/versioned-op-with-native-prop-1.12.mlirbc 2>&1 | FileCheck %s --check-prefix=CHECK3
// CHECK3: test.with_versioned_properties 1 | 0
+
+// Verify emission for both historical and current dialect versions.
+// RUN: mlir-opt %s -emit-bytecode -emit-bytecode-dialect-version=test=1.12 | mlir-opt | FileCheck %s --check-prefix=EMIT
+// RUN: mlir-opt %s -emit-bytecode -emit-bytecode-dialect-version=test=2.0 | mlir-opt | FileCheck %s --check-prefix=EMIT
+// EMIT: test.with_versioned_properties 1 | 0
+test.with_versioned_properties 1 | 0
diff --git a/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed.mlir b/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed.mlir
index ebb198456b3c12..1a2527a45f01b5 100644
--- a/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed.mlir
+++ b/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed.mlir
@@ -1,8 +1,14 @@
+// Verify that both historical and current builtin encodings are unchanged.
+// RUN: mlir-opt -allow-unregistered-dialect -emit-bytecode -emit-bytecode-producer=fixed -emit-bytecode-dialect-version=builtin=0 %s -o %t.0
+// RUN: cmp -s %t.0 %p/builtin_fixed_0.mlirbc
+// RUN: mlir-opt -allow-unregistered-dialect -emit-bytecode -emit-bytecode-producer=fixed -emit-bytecode-dialect-version=builtin=1 %s -o %t.1
+// RUN: cmp -s %t.1 %p/builtin_fixed_1.mlirbc
+// Verify that the default encoding is the current version.
// RUN: mlir-opt -allow-unregistered-dialect -emit-bytecode -emit-bytecode-producer=fixed %s -o %t
-// Verify unchanged.
-// RUN: cmp -s %t %p/builtin_fixed_0.mlirbc
-// Verify can read as expected.
-// RUN: mlir-opt -allow-unregistered-dialect -mlir-print-local-scope %t | FileCheck %s
+// RUN: cmp -s %t %t.1
+// Verify that the checked-in fixtures can be read as expected.
+// RUN: mlir-opt -allow-unregistered-dialect -mlir-print-local-scope %p/builtin_fixed_0.mlirbc | FileCheck %s
+// RUN: mlir-opt -allow-unregistered-dialect -mlir-print-local-scope %p/builtin_fixed_1.mlirbc | FileCheck %s
// Regression test for all builtin dialect bytecode attribute and
// type encodings. Exercises every entry in BuiltinDialectAttributes and
diff --git a/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed_0.mlirbc b/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed_0.mlirbc
index ee79226875ffae..4f661b5a1d2333 100644
Binary files a/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed_0.mlirbc and b/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed_0.mlirbc
diff er
diff --git a/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed_1.mlirbc b/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed_1.mlirbc
new file mode 100644
index 00000000000000..ee79226875ffae
Binary files /dev/null and b/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed_1.mlirbc
diff er
diff --git a/mlir/test/lib/Dialect/Test/TestDialectInterfaces.cpp b/mlir/test/lib/Dialect/Test/TestDialectInterfaces.cpp
index 2b52978fe3636d..f77a0fe06aa9f7 100644
--- a/mlir/test/lib/Dialect/Test/TestDialectInterfaces.cpp
+++ b/mlir/test/lib/Dialect/Test/TestDialectInterfaces.cpp
@@ -9,6 +9,7 @@
#include "TestDialect.h"
#include "TestOps.h"
#include "TestTypes.h"
+#include "mlir/Bytecode/Encoding.h"
#include "mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h"
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
@@ -74,9 +75,19 @@ struct TestBytecodeDialectInterface : public BytecodeDialectInterface {
LogicalResult writeAttribute(Attribute attr,
DialectBytecodeWriter &writer) const final {
if (auto concreteAttr = llvm::dyn_cast<TestAttrParamsAttr>(attr)) {
+ // Without dialect version metadata, use the textual fallback rather than
+ // emit a historical encoding that a reader would interpret as current.
+ if (writer.getBytecodeVersion() < bytecode::kDialectVersioning)
+ return failure();
writer.writeVarInt(test_encoding::k_attr_params);
- writer.writeVarInt(concreteAttr.getV0());
- writer.writeVarInt(concreteAttr.getV1());
+ auto version = writer.getDialectVersion<TestDialect>();
+ bool useOldEncoding =
+ succeeded(version) &&
+ static_cast<const TestDialectVersion *>(*version)->major_ < 2;
+ writer.writeVarInt(useOldEncoding ? concreteAttr.getV1()
+ : concreteAttr.getV0());
+ writer.writeVarInt(useOldEncoding ? concreteAttr.getV0()
+ : concreteAttr.getV1());
return success();
}
return failure();
@@ -97,6 +108,39 @@ struct TestBytecodeDialectInterface : public BytecodeDialectInterface {
return Attribute();
}
+ std::unique_ptr<DialectVersion> parseVersion(StringRef version) const final {
+ auto [major, minor] = version.split('.');
+ uint32_t majorVersion, minorVersion;
+ if (major.getAsInteger(10, majorVersion) ||
+ minor.getAsInteger(10, minorVersion) || majorVersion > 2 ||
+ (majorVersion == 2 && minorVersion > 0))
+ return nullptr;
+ return std::make_unique<TestDialectVersion>(majorVersion, minorVersion);
+ }
+
+ LogicalResult verifyVersion(Operation *topLevelOp,
+ const DialectVersion &version) const final {
+ if (static_cast<const TestDialectVersion &>(version).major_ >= 2)
+ return success();
+ WalkResult result = topLevelOp->walk([](TestVersionedOpA op) {
+ if (!op.getModifier())
+ return WalkResult::advance();
+ op.emitOpError("cannot emit test dialect versions before 2.0 with "
+ "'modifier = true'");
+ return WalkResult::interrupt();
+ });
+ if (result.wasInterrupted())
+ return failure();
+ result = topLevelOp->walk([](TestOpWithVersionedProperties op) {
+ if (op.getProperties().prop.value2 == 0)
+ return WalkResult::advance();
+ op.emitOpError("cannot emit test dialect versions before 2.0 with "
+ "a nonzero 'value2' property");
+ return WalkResult::interrupt();
+ });
+ return failure(result.wasInterrupted());
+ }
+
// Emit a specific version of the dialect.
void writeVersion(DialectBytecodeWriter &writer) const final {
// Construct the current dialect version.
diff --git a/mlir/test/lib/Dialect/Test/TestOpDefs.cpp b/mlir/test/lib/Dialect/Test/TestOpDefs.cpp
index e2ec23e2a68a1e..57cd56f70fac0f 100644
--- a/mlir/test/lib/Dialect/Test/TestOpDefs.cpp
+++ b/mlir/test/lib/Dialect/Test/TestOpDefs.cpp
@@ -1778,7 +1778,6 @@ void TestVersionedOpA::writeProperties(mlir::DialectBytecodeWriter &writer) {
const auto *version =
reinterpret_cast<const TestDialectVersion *>(*maybeVersion);
if ((version->major_ < 2)) {
- llvm::outs() << "downgrading op properties...\n";
return;
}
}
@@ -1819,6 +1818,10 @@ void TestOpWithVersionedProperties::writeToMlirBytecode(
mlir::DialectBytecodeWriter &writer,
const test::VersionedProperties &prop) {
writer.writeVarInt(prop.value1);
+ auto version = writer.getDialectVersion<test::TestDialect>();
+ if (succeeded(version) &&
+ static_cast<const TestDialectVersion *>(*version)->major_ < 2)
+ return;
writer.writeVarInt(prop.value2);
}
More information about the Mlir-commits
mailing list