Skip to content

[mlir][smt] Allow empty function domains#193732

Merged
TaoBi22 merged 1 commit into
mainfrom
users/TaoBi22/allow-empty-smt-func-domain
Apr 28, 2026
Merged

[mlir][smt] Allow empty function domains#193732
TaoBi22 merged 1 commit into
mainfrom
users/TaoBi22/allow-empty-smt-func-domain

Conversation

@TaoBi22
Copy link
Copy Markdown
Contributor

@TaoBi22 TaoBi22 commented Apr 23, 2026

Currently the SMT dialect doesn't allow SMT functions with an empty domain. Not sure if the intention behind this was because it makes the parsing/printing a little more complex or because it's semantically equivalent to declaring a const, but since it's legal SMTLIB it would be nice to allow it (especially since declare-const isn't actually part of the SMTLIB 2.0 spec, just Z3 syntactic sugar). This means we can avoid unnecessary special cases when generating function declarations whose domains vary (e.g. in FSMToSMT).

@TaoBi22 TaoBi22 requested review from maerhart and math-fehr April 23, 2026 13:12
@llvmbot llvmbot added the mlir label Apr 23, 2026
@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Apr 23, 2026

@llvm/pr-subscribers-mlir

Author: Bea Healy (TaoBi22)

Changes

Currently the SMT dialect doesn't allow SMT functions with an empty domain. Not sure if the intention behind this was because it makes the parsing/printing a little more complex or because it's semantically equivalent to declaring a const, but since it's legal SMTLIB it would be nice to allow it (especially since declare-const isn't actually part of the SMTLIB 2.0 spec, just Z3 syntactic sugar).


Full diff: https://github.com/llvm/llvm-project/pull/193732.diff

5 Files Affected:

  • (modified) mlir/include/mlir/Dialect/SMT/IR/SMTTypes.td (+1-4)
  • (modified) mlir/lib/Dialect/SMT/IR/SMTTypes.cpp (+15-2)
  • (modified) mlir/test/Dialect/SMT/basic.mlir (+6)
  • (modified) mlir/unittests/Dialect/SMT/CMakeLists.txt (-1)
  • (removed) mlir/unittests/Dialect/SMT/TypeTest.cpp (-31)
diff --git a/mlir/include/mlir/Dialect/SMT/IR/SMTTypes.td b/mlir/include/mlir/Dialect/SMT/IR/SMTTypes.td
index 19fee9756e5f5..b22fb0a6e7234 100644
--- a/mlir/include/mlir/Dialect/SMT/IR/SMTTypes.td
+++ b/mlir/include/mlir/Dialect/SMT/IR/SMTTypes.td
@@ -82,10 +82,7 @@ def SMTFuncType : SMTTypeDef<"SMTFunc"> {
     "mlir::Type":$rangeType
   );
 
-  // Note: We are not printing the parentheses when no domain type is present
-  // because the default MLIR parser thinks it is a builtin function type
-  // otherwise.
-  let assemblyFormat = "`<` `(` $domainTypes `)` ` ` $rangeType `>`";
+  let assemblyFormat = "`<` custom<DomainTypes>($domainTypes) $rangeType `>`";
 
   let builders = [
     TypeBuilderWithInferredContext<(ins
diff --git a/mlir/lib/Dialect/SMT/IR/SMTTypes.cpp b/mlir/lib/Dialect/SMT/IR/SMTTypes.cpp
index 6188719bb1ab5..d9baef98aff37 100644
--- a/mlir/lib/Dialect/SMT/IR/SMTTypes.cpp
+++ b/mlir/lib/Dialect/SMT/IR/SMTTypes.cpp
@@ -16,6 +16,21 @@ using namespace mlir;
 using namespace smt;
 using namespace mlir;
 
+static mlir::ParseResult
+parseDomainTypes(mlir::AsmParser &parser,
+                 llvm::SmallVectorImpl<mlir::Type> &types) {
+  return parser.parseCommaSeparatedList(
+      mlir::AsmParser::Delimiter::Paren,
+      [&]() { return parser.parseType(types.emplace_back()); });
+}
+
+static void printDomainTypes(mlir::AsmPrinter &printer,
+                             llvm::ArrayRef<mlir::Type> types) {
+  printer << '(';
+  llvm::interleaveComma(types, printer);
+  printer << ')';
+}
+
 #define GET_TYPEDEF_CLASSES
 #include "mlir/Dialect/SMT/IR/SMTTypes.cpp.inc"
 
@@ -67,8 +82,6 @@ LogicalResult ArrayType::verify(function_ref<InFlightDiagnostic()> emitError,
 
 LogicalResult SMTFuncType::verify(function_ref<InFlightDiagnostic()> emitError,
                                   ArrayRef<Type> domainTypes, Type rangeType) {
-  if (domainTypes.empty())
-    return emitError() << "domain must not be empty";
   if (!llvm::all_of(domainTypes, isAnyNonFuncSMTValueType))
     return emitError() << "domain types must be any non-function SMT type";
   if (!isAnyNonFuncSMTValueType(rangeType))
diff --git a/mlir/test/Dialect/SMT/basic.mlir b/mlir/test/Dialect/SMT/basic.mlir
index 44bf0d6faa00d..38d8f4e8d7fb3 100644
--- a/mlir/test/Dialect/SMT/basic.mlir
+++ b/mlir/test/Dialect/SMT/basic.mlir
@@ -17,6 +17,9 @@ func.func @core(%in: i8) {
   %d = smt.declare_fun {smt.some_attr} : !smt.sort<"uninterpreted_sort">
   // CHECK: smt.declare_fun {smt.some_attr} : !smt.func<(!smt.int, !smt.bool) !smt.bool>
   %e = smt.declare_fun {smt.some_attr} : !smt.func<(!smt.int, !smt.bool) !smt.bool>
+  // CHECK: smt.declare_fun {smt.some_attr} : !smt.func<() !smt.bool>
+  %f = smt.declare_fun {smt.some_attr} : !smt.func<() !smt.bool>
+
 
   // CHECK: smt.constant true {smt.some_attr}
   %true = smt.constant true {smt.some_attr}
@@ -105,6 +108,9 @@ func.func @core(%in: i8) {
   // CHECK: smt.apply_func %{{.*}}(%{{.*}}, %{{.*}}) {smt.some_attr} : !smt.func<(!smt.int, !smt.bool) !smt.bool>
   %11 = smt.apply_func %e(%c, %a) {smt.some_attr} : !smt.func<(!smt.int, !smt.bool) !smt.bool>
 
+  // CHECK: smt.apply_func %{{.*}}() {smt.some_attr} : !smt.func<() !smt.bool>
+  %12 = smt.apply_func %f() {smt.some_attr} : !smt.func<() !smt.bool>
+
   return
 }
 
diff --git a/mlir/unittests/Dialect/SMT/CMakeLists.txt b/mlir/unittests/Dialect/SMT/CMakeLists.txt
index a1331467febaa..184e227c40327 100644
--- a/mlir/unittests/Dialect/SMT/CMakeLists.txt
+++ b/mlir/unittests/Dialect/SMT/CMakeLists.txt
@@ -1,7 +1,6 @@
 add_mlir_unittest(MLIRSMTTests
   AttributeTest.cpp
   QuantifierTest.cpp
-  TypeTest.cpp
 )
 
 mlir_target_link_libraries(MLIRSMTTests
diff --git a/mlir/unittests/Dialect/SMT/TypeTest.cpp b/mlir/unittests/Dialect/SMT/TypeTest.cpp
deleted file mode 100644
index f3b06cd0f84e0..0000000000000
--- a/mlir/unittests/Dialect/SMT/TypeTest.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-//===- TypeTest.cpp - SMT type unit tests ---------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "mlir/Dialect/SMT/IR/SMTDialect.h"
-#include "mlir/Dialect/SMT/IR/SMTTypes.h"
-#include "gtest/gtest.h"
-
-using namespace mlir;
-using namespace smt;
-
-namespace {
-
-TEST(SMTFuncTypeTest, NonEmptyDomain) {
-  MLIRContext context;
-  context.loadDialect<SMTDialect>();
-  Location loc(UnknownLoc::get(&context));
-
-  auto boolTy = BoolType::get(&context);
-  auto funcTy = SMTFuncType::getChecked(loc, ArrayRef<Type>{}, boolTy);
-  ASSERT_EQ(funcTy, Type());
-  context.getDiagEngine().registerHandler([&](Diagnostic &diag) {
-    ASSERT_STREQ(diag.str().c_str(), "domain must not be empty");
-  });
-}
-
-} // namespace

@TaoBi22 TaoBi22 requested a review from makslevental April 27, 2026 12:51
Copy link
Copy Markdown
Contributor

@makslevental makslevental left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (and I agree with the reasoning for the PR - empty funcs are pervasive it makes sense to support them)

@makslevental
Copy link
Copy Markdown
Contributor

@TaoBi22 let me know if you need me to merge (but I think you have commit access)

@TaoBi22
Copy link
Copy Markdown
Contributor Author

TaoBi22 commented Apr 28, 2026

@TaoBi22 let me know if you need me to merge (but I think you have commit access)

I have commit access but thanks for checking and reviewing!

@TaoBi22 TaoBi22 merged commit 3d1fa9e into main Apr 28, 2026
12 checks passed
@TaoBi22 TaoBi22 deleted the users/TaoBi22/allow-empty-smt-func-domain branch April 28, 2026 09:27
@llvm-ci
Copy link
Copy Markdown

llvm-ci commented Apr 28, 2026

LLVM Buildbot has detected a new failure on builder clang-aarch64-sve2-vla running on linaro-g4-01 while building mlir at step 14 "test-suite".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/198/builds/13026

Here is the relevant piece of the build log for the reference
Step 14 (test-suite) failure: test (failure)
******************** TEST 'test-suite :: tools/test/alloc_mem.test' FAILED ********************

/home/tcwg-buildbot/worker/clang-aarch64-sve2-vla/test/sandbox/build/tools/timeit-target --timeout 7200 --limit-core 0 --limit-cpu 7200 --limit-file-size 209715200 --limit-rss-size 838860800 --redirect-input /dev/null --summary /home/tcwg-buildbot/worker/clang-aarch64-sve2-vla/test/sandbox/build/tools/test/Output/alloc_mem.test.time /usr/bin/python3.10 /home/tcwg-buildbot/worker/clang-aarch64-sve2-vla/test/sandbox/build/tools/test/test_maxrss.py /home/tcwg-buildbot/worker/clang-aarch64-sve2-vla/test/sandbox/build/tools/timeit-target /home/tcwg-buildbot/worker/clang-aarch64-sve2-vla/test/sandbox/build/tools/test/alloc_mem
maxrss too low: 134111232 < 134217728

+ /home/tcwg-buildbot/worker/clang-aarch64-sve2-vla/test/sandbox/build/tools/timeit-target --timeout 7200 --limit-core 0 --limit-cpu 7200 --limit-file-size 209715200 --limit-rss-size 838860800 --redirect-input /dev/null --summary /home/tcwg-buildbot/worker/clang-aarch64-sve2-vla/test/sandbox/build/tools/test/Output/alloc_mem.test.time /usr/bin/python3.10 /home/tcwg-buildbot/worker/clang-aarch64-sve2-vla/test/sandbox/build/tools/test/test_maxrss.py /home/tcwg-buildbot/worker/clang-aarch64-sve2-vla/test/sandbox/build/tools/timeit-target /home/tcwg-buildbot/worker/clang-aarch64-sve2-vla/test/sandbox/build/tools/test/alloc_mem

********************


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants