-
Notifications
You must be signed in to change notification settings - Fork 313
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
1,352 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
//===- SMTToZ3LLVM.h --------------------------------------------*- C++ -*-===// | ||
// | ||
// 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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef CIRCT_CONVERSION_SMTTOZ3LLVM_H | ||
#define CIRCT_CONVERSION_SMTTOZ3LLVM_H | ||
|
||
#include "circt/Support/LLVM.h" | ||
#include "circt/Support/Namespace.h" | ||
#include "mlir/Dialect/LLVMIR/LLVMDialect.h" | ||
#include "llvm/ADT/StringRef.h" | ||
#include <memory> | ||
|
||
namespace circt { | ||
|
||
#define GEN_PASS_DECL_LOWERSMTTOZ3LLVM | ||
#include "circt/Conversion/Passes.h.inc" | ||
|
||
/// A symbol cache for LLVM globals and functions relevant to SMT lowering | ||
/// patterns. | ||
struct SMTGlobalsHandler { | ||
/// Creates the LLVM global operations to store the pointers to the solver and | ||
/// the context and returns a 'SMTGlobalHandler' initialized with those new | ||
/// globals. | ||
static SMTGlobalsHandler create(OpBuilder &builder, ModuleOp module); | ||
|
||
/// Initializes the caches and keeps track of the given globals to store the | ||
/// pointers to the SMT solver and context. It is assumed that the passed | ||
/// global operations are of the correct (or at least compatible) form. E.g., | ||
/// ``` | ||
/// llvm.mlir.global internal @ctx() {alignment = 8 : i64} : !llvm.ptr { | ||
/// %0 = llvm.mlir.zero : !llvm.ptr | ||
/// llvm.return %0 : !llvm.ptr | ||
/// } | ||
/// ``` | ||
SMTGlobalsHandler(ModuleOp module, mlir::LLVM::GlobalOp solver, | ||
mlir::LLVM::GlobalOp ctx); | ||
|
||
/// Initializes the caches and keeps track of the given globals to store the | ||
/// pointers to the SMT solver and context. It is assumed that the passed | ||
/// global operations are of the correct (or at least compatible) form. E.g., | ||
/// ``` | ||
/// llvm.mlir.global internal @ctx() {alignment = 8 : i64} : !llvm.ptr { | ||
/// %0 = llvm.mlir.zero : !llvm.ptr | ||
/// llvm.return %0 : !llvm.ptr | ||
/// } | ||
/// ``` | ||
SMTGlobalsHandler(Namespace &&names, mlir::LLVM::GlobalOp solver, | ||
mlir::LLVM::GlobalOp ctx); | ||
|
||
/// The global storing the pointer to the SMT solver object currently active. | ||
const mlir::LLVM::GlobalOp solver; | ||
|
||
/// The global storing the pointer to the SMT context object currently active. | ||
const mlir::LLVM::GlobalOp ctx; | ||
|
||
Namespace names; | ||
DenseMap<StringRef, mlir::LLVM::LLVMFuncOp> funcMap; | ||
DenseMap<Block *, Value> ctxCache; | ||
DenseMap<Block *, Value> solverCache; | ||
DenseMap<StringRef, mlir::LLVM::GlobalOp> stringCache; | ||
}; | ||
|
||
/// Populate the given type converter with the SMT to LLVM type conversions. | ||
void populateSMTToZ3LLVMTypeConverter(TypeConverter &converter); | ||
|
||
/// Add the SMT to LLVM IR conversion patterns to 'patterns'. A | ||
/// 'SMTGlobalHandler' object has to be passed which acts as a symbol cache for | ||
/// LLVM globals and functions. | ||
void populateSMTToZ3LLVMConversionPatterns( | ||
RewritePatternSet &patterns, TypeConverter &converter, | ||
SMTGlobalsHandler &globals, const LowerSMTToZ3LLVMOptions &options); | ||
|
||
} // namespace circt | ||
|
||
#endif // CIRCT_CONVERSION_SMTTOZ3LLVM_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// RUN: circt-opt %s --lower-smt-to-z3-llvm --canonicalize | \ | ||
// RUN: mlir-cpu-runner -e entry -entry-point-result=void --shared-libs=%libz3 | \ | ||
// RUN: FileCheck %s | ||
|
||
// RUN: circt-opt %s --lower-smt-to-z3-llvm=debug=true --canonicalize | \ | ||
// RUN: mlir-cpu-runner -e entry -entry-point-result=void --shared-libs=%libz3 | \ | ||
// RUN: FileCheck %s | ||
|
||
// REQUIRES: libz3 | ||
// REQUIRES: mlir-cpu-runner | ||
|
||
func.func @entry() { | ||
%false = llvm.mlir.constant(0 : i1) : i1 | ||
// CHECK: sat | ||
// CHECK: Res: 1 | ||
smt.solver () : () -> () { | ||
%c42_bv65 = smt.bv.constant #smt.bv<42> : !smt.bv<65> | ||
%1 = smt.declare_fun : !smt.bv<65> | ||
%2 = smt.declare_fun "a" : !smt.bv<65> | ||
%3 = smt.eq %c42_bv65, %1, %2 : !smt.bv<65> | ||
func.call @check(%3) : (!smt.bool) -> () | ||
smt.yield | ||
} | ||
|
||
// CHECK: sat | ||
// CHECK: Res: 1 | ||
smt.solver () : () -> () { | ||
%c0_bv8 = smt.bv.constant #smt.bv<0> : !smt.bv<8> | ||
%c-1_bv8 = smt.bv.constant #smt.bv<-1> : !smt.bv<8> | ||
%2 = smt.distinct %c0_bv8, %c-1_bv8 : !smt.bv<8> | ||
func.call @check(%2) : (!smt.bool) -> () | ||
smt.yield | ||
} | ||
|
||
// CHECK: sat | ||
// CHECK: Res: 1 | ||
smt.solver () : () -> () { | ||
%0 = smt.declare_fun : !smt.func<(!smt.bv<4>) !smt.array<[!smt.int -> !smt.sort<"uninterpreted_sort"[!smt.bool]>]>> | ||
%1 = smt.declare_fun : !smt.func<(!smt.bv<4>) !smt.array<[!smt.int -> !smt.sort<"uninterpreted_sort"[!smt.bool]>]>> | ||
%c0_bv4 = smt.bv.constant #smt.bv<0> : !smt.bv<4> | ||
%2 = smt.apply_func %0(%c0_bv4) : !smt.func<(!smt.bv<4>) !smt.array<[!smt.int -> !smt.sort<"uninterpreted_sort"[!smt.bool]>]>> | ||
%3 = smt.apply_func %1(%c0_bv4) : !smt.func<(!smt.bv<4>) !smt.array<[!smt.int -> !smt.sort<"uninterpreted_sort"[!smt.bool]>]>> | ||
%4 = smt.eq %2, %3 : !smt.array<[!smt.int -> !smt.sort<"uninterpreted_sort"[!smt.bool]>]> | ||
func.call @check(%4) : (!smt.bool) -> () | ||
smt.yield | ||
} | ||
|
||
// CHECK: unsat | ||
// CHECK: Res: -1 | ||
smt.solver (%false) : (i1) -> () { | ||
^bb0(%arg0: i1): | ||
%c0_bv32 = smt.bv.constant #smt.bv<0> : !smt.bv<32> | ||
%0 = scf.if %arg0 -> !smt.bv<32> { | ||
%1 = smt.declare_fun : !smt.bv<32> | ||
scf.yield %1 : !smt.bv<32> | ||
} else { | ||
%c1_bv32 = smt.bv.constant #smt.bv<-1> : !smt.bv<32> | ||
scf.yield %c1_bv32 : !smt.bv<32> | ||
} | ||
%1 = smt.eq %c0_bv32, %0 : !smt.bv<32> | ||
func.call @check(%1) : (!smt.bool) -> () | ||
smt.yield | ||
} | ||
|
||
return | ||
} | ||
|
||
|
||
func.func @check(%expr: !smt.bool) { | ||
smt.assert %expr | ||
%0 = smt.check sat { | ||
%1 = llvm.mlir.addressof @sat : !llvm.ptr | ||
llvm.call @printf(%1) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr) -> i32 | ||
%c1 = llvm.mlir.constant(1 : i32) : i32 | ||
smt.yield %c1 : i32 | ||
} unknown { | ||
%1 = llvm.mlir.addressof @unknown : !llvm.ptr | ||
llvm.call @printf(%1) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr) -> i32 | ||
%c0 = llvm.mlir.constant(0 : i32) : i32 | ||
smt.yield %c0 : i32 | ||
} unsat { | ||
%1 = llvm.mlir.addressof @unsat : !llvm.ptr | ||
llvm.call @printf(%1) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr) -> i32 | ||
%c-1 = llvm.mlir.constant(-1 : i32) : i32 | ||
smt.yield %c-1 : i32 | ||
} -> i32 | ||
%1 = llvm.mlir.addressof @res : !llvm.ptr | ||
llvm.call @printf(%1, %0) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i32) -> i32 | ||
return | ||
} | ||
|
||
llvm.func @printf(!llvm.ptr, ...) -> i32 | ||
llvm.mlir.global private constant @res("Res: %d\n\00") {addr_space = 0 : i32} | ||
llvm.mlir.global private constant @sat("sat\n\00") {addr_space = 0 : i32} | ||
llvm.mlir.global private constant @unsat("unsat\n\00") {addr_space = 0 : i32} | ||
llvm.mlir.global private constant @unknown("unknown\n\00") {addr_space = 0 : i32} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
add_circt_conversion_library(CIRCTSMTToZ3LLVM | ||
LowerSMTToZ3LLVM.cpp | ||
|
||
DEPENDS | ||
CIRCTConversionPassIncGen | ||
|
||
LINK_COMPONENTS | ||
Core | ||
|
||
LINK_LIBS PUBLIC | ||
CIRCTSMT | ||
CIRCTSupport | ||
MLIRLLVMCommonConversion | ||
MLIRSCFToControlFlow | ||
MLIRControlFlowToLLVM | ||
MLIRFuncToLLVM | ||
MLIRTransforms | ||
) |
Oops, something went wrong.