10b57cec5SDimitry Andric //== Z3Solver.cpp -----------------------------------------------*- C++ -*--==// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90fca6ea1SDimitry Andric #include "llvm/ADT/ScopeExit.h" 100b57cec5SDimitry Andric #include "llvm/Config/config.h" 110fca6ea1SDimitry Andric #include "llvm/Support/NativeFormatting.h" 120b57cec5SDimitry Andric #include "llvm/Support/SMTAPI.h" 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric using namespace llvm; 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #if LLVM_WITH_Z3 170b57cec5SDimitry Andric 1881ad6265SDimitry Andric #include "llvm/ADT/SmallString.h" 1981ad6265SDimitry Andric #include "llvm/ADT/Twine.h" 2081ad6265SDimitry Andric 2181ad6265SDimitry Andric #include <set> 22*6c4b055cSDimitry Andric #include <unordered_map> 2381ad6265SDimitry Andric 240b57cec5SDimitry Andric #include <z3.h> 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric namespace { 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric /// Configuration class for Z3 290b57cec5SDimitry Andric class Z3Config { 300b57cec5SDimitry Andric friend class Z3Context; 310b57cec5SDimitry Andric 320fca6ea1SDimitry Andric Z3_config Config = Z3_mk_config(); 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric public: 350fca6ea1SDimitry Andric Z3Config() = default; 360fca6ea1SDimitry Andric Z3Config(const Z3Config &) = delete; 370fca6ea1SDimitry Andric Z3Config(Z3Config &&) = default; 380fca6ea1SDimitry Andric Z3Config &operator=(Z3Config &) = delete; 390fca6ea1SDimitry Andric Z3Config &operator=(Z3Config &&) = default; 400b57cec5SDimitry Andric ~Z3Config() { Z3_del_config(Config); } 410b57cec5SDimitry Andric }; // end class Z3Config 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric // Function used to report errors 440b57cec5SDimitry Andric void Z3ErrorHandler(Z3_context Context, Z3_error_code Error) { 450b57cec5SDimitry Andric llvm::report_fatal_error("Z3 error: " + 460b57cec5SDimitry Andric llvm::Twine(Z3_get_error_msg(Context, Error))); 470b57cec5SDimitry Andric } 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric /// Wrapper for Z3 context 500b57cec5SDimitry Andric class Z3Context { 510b57cec5SDimitry Andric public: 520fca6ea1SDimitry Andric Z3Config Config; 530b57cec5SDimitry Andric Z3_context Context; 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric Z3Context() { 560fca6ea1SDimitry Andric Context = Z3_mk_context_rc(Config.Config); 570b57cec5SDimitry Andric // The error function is set here because the context is the first object 580b57cec5SDimitry Andric // created by the backend 590b57cec5SDimitry Andric Z3_set_error_handler(Context, Z3ErrorHandler); 600b57cec5SDimitry Andric } 610b57cec5SDimitry Andric 620fca6ea1SDimitry Andric Z3Context(const Z3Context &) = delete; 630fca6ea1SDimitry Andric Z3Context(Z3Context &&) = default; 640fca6ea1SDimitry Andric Z3Context &operator=(Z3Context &) = delete; 650fca6ea1SDimitry Andric Z3Context &operator=(Z3Context &&) = default; 660fca6ea1SDimitry Andric 670fca6ea1SDimitry Andric ~Z3Context() { 680b57cec5SDimitry Andric Z3_del_context(Context); 690b57cec5SDimitry Andric Context = nullptr; 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric }; // end class Z3Context 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric /// Wrapper for Z3 Sort 740b57cec5SDimitry Andric class Z3Sort : public SMTSort { 750b57cec5SDimitry Andric friend class Z3Solver; 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric Z3Context &Context; 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric Z3_sort Sort; 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric public: 820b57cec5SDimitry Andric /// Default constructor, mainly used by make_shared 830b57cec5SDimitry Andric Z3Sort(Z3Context &C, Z3_sort ZS) : Context(C), Sort(ZS) { 840b57cec5SDimitry Andric Z3_inc_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort)); 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric /// Override implicit copy constructor for correct reference counting. 880b57cec5SDimitry Andric Z3Sort(const Z3Sort &Other) : Context(Other.Context), Sort(Other.Sort) { 890b57cec5SDimitry Andric Z3_inc_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort)); 900b57cec5SDimitry Andric } 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric /// Override implicit copy assignment constructor for correct reference 930b57cec5SDimitry Andric /// counting. 940b57cec5SDimitry Andric Z3Sort &operator=(const Z3Sort &Other) { 950b57cec5SDimitry Andric Z3_inc_ref(Context.Context, reinterpret_cast<Z3_ast>(Other.Sort)); 960b57cec5SDimitry Andric Z3_dec_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort)); 970b57cec5SDimitry Andric Sort = Other.Sort; 980b57cec5SDimitry Andric return *this; 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric Z3Sort(Z3Sort &&Other) = delete; 1020b57cec5SDimitry Andric Z3Sort &operator=(Z3Sort &&Other) = delete; 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric ~Z3Sort() { 1050b57cec5SDimitry Andric if (Sort) 1060b57cec5SDimitry Andric Z3_dec_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort)); 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric void Profile(llvm::FoldingSetNodeID &ID) const override { 1100b57cec5SDimitry Andric ID.AddInteger( 1110b57cec5SDimitry Andric Z3_get_ast_id(Context.Context, reinterpret_cast<Z3_ast>(Sort))); 1120b57cec5SDimitry Andric } 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric bool isBitvectorSortImpl() const override { 1150b57cec5SDimitry Andric return (Z3_get_sort_kind(Context.Context, Sort) == Z3_BV_SORT); 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric bool isFloatSortImpl() const override { 1190b57cec5SDimitry Andric return (Z3_get_sort_kind(Context.Context, Sort) == Z3_FLOATING_POINT_SORT); 1200b57cec5SDimitry Andric } 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric bool isBooleanSortImpl() const override { 1230b57cec5SDimitry Andric return (Z3_get_sort_kind(Context.Context, Sort) == Z3_BOOL_SORT); 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric unsigned getBitvectorSortSizeImpl() const override { 1270b57cec5SDimitry Andric return Z3_get_bv_sort_size(Context.Context, Sort); 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric unsigned getFloatSortSizeImpl() const override { 1310b57cec5SDimitry Andric return Z3_fpa_get_ebits(Context.Context, Sort) + 1320b57cec5SDimitry Andric Z3_fpa_get_sbits(Context.Context, Sort); 1330b57cec5SDimitry Andric } 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric bool equal_to(SMTSort const &Other) const override { 1360b57cec5SDimitry Andric return Z3_is_eq_sort(Context.Context, Sort, 1370b57cec5SDimitry Andric static_cast<const Z3Sort &>(Other).Sort); 1380b57cec5SDimitry Andric } 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric void print(raw_ostream &OS) const override { 1410b57cec5SDimitry Andric OS << Z3_sort_to_string(Context.Context, Sort); 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric }; // end class Z3Sort 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric static const Z3Sort &toZ3Sort(const SMTSort &S) { 1460b57cec5SDimitry Andric return static_cast<const Z3Sort &>(S); 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric class Z3Expr : public SMTExpr { 1500b57cec5SDimitry Andric friend class Z3Solver; 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric Z3Context &Context; 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric Z3_ast AST; 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric public: 1570b57cec5SDimitry Andric Z3Expr(Z3Context &C, Z3_ast ZA) : SMTExpr(), Context(C), AST(ZA) { 1580b57cec5SDimitry Andric Z3_inc_ref(Context.Context, AST); 1590b57cec5SDimitry Andric } 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric /// Override implicit copy constructor for correct reference counting. 1620b57cec5SDimitry Andric Z3Expr(const Z3Expr &Copy) : SMTExpr(), Context(Copy.Context), AST(Copy.AST) { 1630b57cec5SDimitry Andric Z3_inc_ref(Context.Context, AST); 1640b57cec5SDimitry Andric } 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric /// Override implicit copy assignment constructor for correct reference 1670b57cec5SDimitry Andric /// counting. 1680b57cec5SDimitry Andric Z3Expr &operator=(const Z3Expr &Other) { 1690b57cec5SDimitry Andric Z3_inc_ref(Context.Context, Other.AST); 1700b57cec5SDimitry Andric Z3_dec_ref(Context.Context, AST); 1710b57cec5SDimitry Andric AST = Other.AST; 1720b57cec5SDimitry Andric return *this; 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric Z3Expr(Z3Expr &&Other) = delete; 1760b57cec5SDimitry Andric Z3Expr &operator=(Z3Expr &&Other) = delete; 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric ~Z3Expr() { 1790b57cec5SDimitry Andric if (AST) 1800b57cec5SDimitry Andric Z3_dec_ref(Context.Context, AST); 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric void Profile(llvm::FoldingSetNodeID &ID) const override { 1840b57cec5SDimitry Andric ID.AddInteger(Z3_get_ast_id(Context.Context, AST)); 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric /// Comparison of AST equality, not model equivalence. 1880b57cec5SDimitry Andric bool equal_to(SMTExpr const &Other) const override { 1890b57cec5SDimitry Andric assert(Z3_is_eq_sort(Context.Context, Z3_get_sort(Context.Context, AST), 1900b57cec5SDimitry Andric Z3_get_sort(Context.Context, 1910b57cec5SDimitry Andric static_cast<const Z3Expr &>(Other).AST)) && 1920b57cec5SDimitry Andric "AST's must have the same sort"); 1930b57cec5SDimitry Andric return Z3_is_eq_ast(Context.Context, AST, 1940b57cec5SDimitry Andric static_cast<const Z3Expr &>(Other).AST); 1950b57cec5SDimitry Andric } 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric void print(raw_ostream &OS) const override { 1980b57cec5SDimitry Andric OS << Z3_ast_to_string(Context.Context, AST); 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric }; // end class Z3Expr 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric static const Z3Expr &toZ3Expr(const SMTExpr &E) { 2030b57cec5SDimitry Andric return static_cast<const Z3Expr &>(E); 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric class Z3Model { 2070b57cec5SDimitry Andric friend class Z3Solver; 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric Z3Context &Context; 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric Z3_model Model; 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric public: 2140b57cec5SDimitry Andric Z3Model(Z3Context &C, Z3_model ZM) : Context(C), Model(ZM) { 2150b57cec5SDimitry Andric Z3_model_inc_ref(Context.Context, Model); 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric Z3Model(const Z3Model &Other) = delete; 2190b57cec5SDimitry Andric Z3Model(Z3Model &&Other) = delete; 2200b57cec5SDimitry Andric Z3Model &operator=(Z3Model &Other) = delete; 2210b57cec5SDimitry Andric Z3Model &operator=(Z3Model &&Other) = delete; 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric ~Z3Model() { 2240b57cec5SDimitry Andric if (Model) 2250b57cec5SDimitry Andric Z3_model_dec_ref(Context.Context, Model); 2260b57cec5SDimitry Andric } 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric void print(raw_ostream &OS) const { 2290b57cec5SDimitry Andric OS << Z3_model_to_string(Context.Context, Model); 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric LLVM_DUMP_METHOD void dump() const { print(llvm::errs()); } 2330b57cec5SDimitry Andric }; // end class Z3Model 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric /// Get the corresponding IEEE floating-point type for a given bitwidth. 2360b57cec5SDimitry Andric static const llvm::fltSemantics &getFloatSemantics(unsigned BitWidth) { 2370b57cec5SDimitry Andric switch (BitWidth) { 2380b57cec5SDimitry Andric default: 2390b57cec5SDimitry Andric llvm_unreachable("Unsupported floating-point semantics!"); 2400b57cec5SDimitry Andric break; 2410b57cec5SDimitry Andric case 16: 2420b57cec5SDimitry Andric return llvm::APFloat::IEEEhalf(); 2430b57cec5SDimitry Andric case 32: 2440b57cec5SDimitry Andric return llvm::APFloat::IEEEsingle(); 2450b57cec5SDimitry Andric case 64: 2460b57cec5SDimitry Andric return llvm::APFloat::IEEEdouble(); 2470b57cec5SDimitry Andric case 128: 2480b57cec5SDimitry Andric return llvm::APFloat::IEEEquad(); 2490b57cec5SDimitry Andric } 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric // Determine whether two float semantics are equivalent 2530b57cec5SDimitry Andric static bool areEquivalent(const llvm::fltSemantics &LHS, 2540b57cec5SDimitry Andric const llvm::fltSemantics &RHS) { 2550b57cec5SDimitry Andric return (llvm::APFloat::semanticsPrecision(LHS) == 2560b57cec5SDimitry Andric llvm::APFloat::semanticsPrecision(RHS)) && 2570b57cec5SDimitry Andric (llvm::APFloat::semanticsMinExponent(LHS) == 2580b57cec5SDimitry Andric llvm::APFloat::semanticsMinExponent(RHS)) && 2590b57cec5SDimitry Andric (llvm::APFloat::semanticsMaxExponent(LHS) == 2600b57cec5SDimitry Andric llvm::APFloat::semanticsMaxExponent(RHS)) && 2610b57cec5SDimitry Andric (llvm::APFloat::semanticsSizeInBits(LHS) == 2620b57cec5SDimitry Andric llvm::APFloat::semanticsSizeInBits(RHS)); 2630b57cec5SDimitry Andric } 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric class Z3Solver : public SMTSolver { 2660b57cec5SDimitry Andric friend class Z3ConstraintManager; 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric Z3Context Context; 2690b57cec5SDimitry Andric 2700fca6ea1SDimitry Andric Z3_solver Solver = [this] { 2710fca6ea1SDimitry Andric Z3_solver S = Z3_mk_simple_solver(Context.Context); 2720fca6ea1SDimitry Andric Z3_solver_inc_ref(Context.Context, S); 2730fca6ea1SDimitry Andric return S; 2740fca6ea1SDimitry Andric }(); 2750fca6ea1SDimitry Andric 2760fca6ea1SDimitry Andric Z3_params Params = [this] { 2770fca6ea1SDimitry Andric Z3_params P = Z3_mk_params(Context.Context); 2780fca6ea1SDimitry Andric Z3_params_inc_ref(Context.Context, P); 2790fca6ea1SDimitry Andric return P; 2800fca6ea1SDimitry Andric }(); 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric // Cache Sorts 2830b57cec5SDimitry Andric std::set<Z3Sort> CachedSorts; 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric // Cache Exprs 2860b57cec5SDimitry Andric std::set<Z3Expr> CachedExprs; 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric public: 2890fca6ea1SDimitry Andric Z3Solver() = default; 2900b57cec5SDimitry Andric Z3Solver(const Z3Solver &Other) = delete; 2910b57cec5SDimitry Andric Z3Solver(Z3Solver &&Other) = delete; 2920b57cec5SDimitry Andric Z3Solver &operator=(Z3Solver &Other) = delete; 2930b57cec5SDimitry Andric Z3Solver &operator=(Z3Solver &&Other) = delete; 2940b57cec5SDimitry Andric 2950fca6ea1SDimitry Andric ~Z3Solver() override { 2960fca6ea1SDimitry Andric Z3_params_dec_ref(Context.Context, Params); 2970b57cec5SDimitry Andric Z3_solver_dec_ref(Context.Context, Solver); 2980b57cec5SDimitry Andric } 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric void addConstraint(const SMTExprRef &Exp) const override { 3010b57cec5SDimitry Andric Z3_solver_assert(Context.Context, Solver, toZ3Expr(*Exp).AST); 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric // Given an SMTSort, adds/retrives it from the cache and returns 3050b57cec5SDimitry Andric // an SMTSortRef to the SMTSort in the cache 3060b57cec5SDimitry Andric SMTSortRef newSortRef(const SMTSort &Sort) { 3070b57cec5SDimitry Andric auto It = CachedSorts.insert(toZ3Sort(Sort)); 3080b57cec5SDimitry Andric return &(*It.first); 3090b57cec5SDimitry Andric } 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric // Given an SMTExpr, adds/retrives it from the cache and returns 3120b57cec5SDimitry Andric // an SMTExprRef to the SMTExpr in the cache 3130b57cec5SDimitry Andric SMTExprRef newExprRef(const SMTExpr &Exp) { 3140b57cec5SDimitry Andric auto It = CachedExprs.insert(toZ3Expr(Exp)); 3150b57cec5SDimitry Andric return &(*It.first); 3160b57cec5SDimitry Andric } 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric SMTSortRef getBoolSort() override { 3190b57cec5SDimitry Andric return newSortRef(Z3Sort(Context, Z3_mk_bool_sort(Context.Context))); 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric SMTSortRef getBitvectorSort(unsigned BitWidth) override { 3230b57cec5SDimitry Andric return newSortRef( 3240b57cec5SDimitry Andric Z3Sort(Context, Z3_mk_bv_sort(Context.Context, BitWidth))); 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric SMTSortRef getSort(const SMTExprRef &Exp) override { 3280b57cec5SDimitry Andric return newSortRef( 3290b57cec5SDimitry Andric Z3Sort(Context, Z3_get_sort(Context.Context, toZ3Expr(*Exp).AST))); 3300b57cec5SDimitry Andric } 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric SMTSortRef getFloat16Sort() override { 3330b57cec5SDimitry Andric return newSortRef(Z3Sort(Context, Z3_mk_fpa_sort_16(Context.Context))); 3340b57cec5SDimitry Andric } 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric SMTSortRef getFloat32Sort() override { 3370b57cec5SDimitry Andric return newSortRef(Z3Sort(Context, Z3_mk_fpa_sort_32(Context.Context))); 3380b57cec5SDimitry Andric } 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric SMTSortRef getFloat64Sort() override { 3410b57cec5SDimitry Andric return newSortRef(Z3Sort(Context, Z3_mk_fpa_sort_64(Context.Context))); 3420b57cec5SDimitry Andric } 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric SMTSortRef getFloat128Sort() override { 3450b57cec5SDimitry Andric return newSortRef(Z3Sort(Context, Z3_mk_fpa_sort_128(Context.Context))); 3460b57cec5SDimitry Andric } 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric SMTExprRef mkBVNeg(const SMTExprRef &Exp) override { 3490b57cec5SDimitry Andric return newExprRef( 3500b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvneg(Context.Context, toZ3Expr(*Exp).AST))); 3510b57cec5SDimitry Andric } 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric SMTExprRef mkBVNot(const SMTExprRef &Exp) override { 3540b57cec5SDimitry Andric return newExprRef( 3550b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvnot(Context.Context, toZ3Expr(*Exp).AST))); 3560b57cec5SDimitry Andric } 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric SMTExprRef mkNot(const SMTExprRef &Exp) override { 3590b57cec5SDimitry Andric return newExprRef( 3600b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_not(Context.Context, toZ3Expr(*Exp).AST))); 3610b57cec5SDimitry Andric } 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andric SMTExprRef mkBVAdd(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 3640b57cec5SDimitry Andric return newExprRef( 3650b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvadd(Context.Context, toZ3Expr(*LHS).AST, 3660b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 3670b57cec5SDimitry Andric } 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric SMTExprRef mkBVSub(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 3700b57cec5SDimitry Andric return newExprRef( 3710b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvsub(Context.Context, toZ3Expr(*LHS).AST, 3720b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric SMTExprRef mkBVMul(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 3760b57cec5SDimitry Andric return newExprRef( 3770b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvmul(Context.Context, toZ3Expr(*LHS).AST, 3780b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 3790b57cec5SDimitry Andric } 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric SMTExprRef mkBVSRem(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 3820b57cec5SDimitry Andric return newExprRef( 3830b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvsrem(Context.Context, toZ3Expr(*LHS).AST, 3840b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 3850b57cec5SDimitry Andric } 3860b57cec5SDimitry Andric 3870b57cec5SDimitry Andric SMTExprRef mkBVURem(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 3880b57cec5SDimitry Andric return newExprRef( 3890b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvurem(Context.Context, toZ3Expr(*LHS).AST, 3900b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 3910b57cec5SDimitry Andric } 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric SMTExprRef mkBVSDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 3940b57cec5SDimitry Andric return newExprRef( 3950b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvsdiv(Context.Context, toZ3Expr(*LHS).AST, 3960b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 3970b57cec5SDimitry Andric } 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric SMTExprRef mkBVUDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4000b57cec5SDimitry Andric return newExprRef( 4010b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvudiv(Context.Context, toZ3Expr(*LHS).AST, 4020b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric SMTExprRef mkBVShl(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4060b57cec5SDimitry Andric return newExprRef( 4070b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvshl(Context.Context, toZ3Expr(*LHS).AST, 4080b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 4090b57cec5SDimitry Andric } 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric SMTExprRef mkBVAshr(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4120b57cec5SDimitry Andric return newExprRef( 4130b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvashr(Context.Context, toZ3Expr(*LHS).AST, 4140b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 4150b57cec5SDimitry Andric } 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric SMTExprRef mkBVLshr(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4180b57cec5SDimitry Andric return newExprRef( 4190b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvlshr(Context.Context, toZ3Expr(*LHS).AST, 4200b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 4210b57cec5SDimitry Andric } 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric SMTExprRef mkBVXor(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4240b57cec5SDimitry Andric return newExprRef( 4250b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvxor(Context.Context, toZ3Expr(*LHS).AST, 4260b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 4270b57cec5SDimitry Andric } 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric SMTExprRef mkBVOr(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4300b57cec5SDimitry Andric return newExprRef( 4310b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvor(Context.Context, toZ3Expr(*LHS).AST, 4320b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 4330b57cec5SDimitry Andric } 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric SMTExprRef mkBVAnd(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4360b57cec5SDimitry Andric return newExprRef( 4370b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvand(Context.Context, toZ3Expr(*LHS).AST, 4380b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 4390b57cec5SDimitry Andric } 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric SMTExprRef mkBVUlt(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4420b57cec5SDimitry Andric return newExprRef( 4430b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvult(Context.Context, toZ3Expr(*LHS).AST, 4440b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 4450b57cec5SDimitry Andric } 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andric SMTExprRef mkBVSlt(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4480b57cec5SDimitry Andric return newExprRef( 4490b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvslt(Context.Context, toZ3Expr(*LHS).AST, 4500b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 4510b57cec5SDimitry Andric } 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric SMTExprRef mkBVUgt(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4540b57cec5SDimitry Andric return newExprRef( 4550b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvugt(Context.Context, toZ3Expr(*LHS).AST, 4560b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 4570b57cec5SDimitry Andric } 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric SMTExprRef mkBVSgt(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4600b57cec5SDimitry Andric return newExprRef( 4610b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvsgt(Context.Context, toZ3Expr(*LHS).AST, 4620b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 4630b57cec5SDimitry Andric } 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric SMTExprRef mkBVUle(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4660b57cec5SDimitry Andric return newExprRef( 4670b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvule(Context.Context, toZ3Expr(*LHS).AST, 4680b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 4690b57cec5SDimitry Andric } 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric SMTExprRef mkBVSle(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4720b57cec5SDimitry Andric return newExprRef( 4730b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvsle(Context.Context, toZ3Expr(*LHS).AST, 4740b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 4750b57cec5SDimitry Andric } 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric SMTExprRef mkBVUge(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4780b57cec5SDimitry Andric return newExprRef( 4790b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvuge(Context.Context, toZ3Expr(*LHS).AST, 4800b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 4810b57cec5SDimitry Andric } 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric SMTExprRef mkBVSge(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4840b57cec5SDimitry Andric return newExprRef( 4850b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_bvsge(Context.Context, toZ3Expr(*LHS).AST, 4860b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 4870b57cec5SDimitry Andric } 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric SMTExprRef mkAnd(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4900b57cec5SDimitry Andric Z3_ast Args[2] = {toZ3Expr(*LHS).AST, toZ3Expr(*RHS).AST}; 4910b57cec5SDimitry Andric return newExprRef(Z3Expr(Context, Z3_mk_and(Context.Context, 2, Args))); 4920b57cec5SDimitry Andric } 4930b57cec5SDimitry Andric 4940b57cec5SDimitry Andric SMTExprRef mkOr(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 4950b57cec5SDimitry Andric Z3_ast Args[2] = {toZ3Expr(*LHS).AST, toZ3Expr(*RHS).AST}; 4960b57cec5SDimitry Andric return newExprRef(Z3Expr(Context, Z3_mk_or(Context.Context, 2, Args))); 4970b57cec5SDimitry Andric } 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric SMTExprRef mkEqual(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 5000b57cec5SDimitry Andric return newExprRef( 5010b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_eq(Context.Context, toZ3Expr(*LHS).AST, 5020b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 5030b57cec5SDimitry Andric } 5040b57cec5SDimitry Andric 5050b57cec5SDimitry Andric SMTExprRef mkFPNeg(const SMTExprRef &Exp) override { 5060b57cec5SDimitry Andric return newExprRef( 5070b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_fpa_neg(Context.Context, toZ3Expr(*Exp).AST))); 5080b57cec5SDimitry Andric } 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric SMTExprRef mkFPIsInfinite(const SMTExprRef &Exp) override { 5110b57cec5SDimitry Andric return newExprRef(Z3Expr( 5120b57cec5SDimitry Andric Context, Z3_mk_fpa_is_infinite(Context.Context, toZ3Expr(*Exp).AST))); 5130b57cec5SDimitry Andric } 5140b57cec5SDimitry Andric 5150b57cec5SDimitry Andric SMTExprRef mkFPIsNaN(const SMTExprRef &Exp) override { 5160b57cec5SDimitry Andric return newExprRef( 5170b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_fpa_is_nan(Context.Context, toZ3Expr(*Exp).AST))); 5180b57cec5SDimitry Andric } 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric SMTExprRef mkFPIsNormal(const SMTExprRef &Exp) override { 5210b57cec5SDimitry Andric return newExprRef(Z3Expr( 5220b57cec5SDimitry Andric Context, Z3_mk_fpa_is_normal(Context.Context, toZ3Expr(*Exp).AST))); 5230b57cec5SDimitry Andric } 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andric SMTExprRef mkFPIsZero(const SMTExprRef &Exp) override { 5260b57cec5SDimitry Andric return newExprRef(Z3Expr( 5270b57cec5SDimitry Andric Context, Z3_mk_fpa_is_zero(Context.Context, toZ3Expr(*Exp).AST))); 5280b57cec5SDimitry Andric } 5290b57cec5SDimitry Andric 5300b57cec5SDimitry Andric SMTExprRef mkFPMul(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 5310b57cec5SDimitry Andric SMTExprRef RoundingMode = getFloatRoundingMode(); 5320b57cec5SDimitry Andric return newExprRef( 5330b57cec5SDimitry Andric Z3Expr(Context, 5345ffd83dbSDimitry Andric Z3_mk_fpa_mul(Context.Context, toZ3Expr(*RoundingMode).AST, 5355ffd83dbSDimitry Andric toZ3Expr(*LHS).AST, toZ3Expr(*RHS).AST))); 5360b57cec5SDimitry Andric } 5370b57cec5SDimitry Andric 5380b57cec5SDimitry Andric SMTExprRef mkFPDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 5390b57cec5SDimitry Andric SMTExprRef RoundingMode = getFloatRoundingMode(); 5400b57cec5SDimitry Andric return newExprRef( 5410b57cec5SDimitry Andric Z3Expr(Context, 5425ffd83dbSDimitry Andric Z3_mk_fpa_div(Context.Context, toZ3Expr(*RoundingMode).AST, 5435ffd83dbSDimitry Andric toZ3Expr(*LHS).AST, toZ3Expr(*RHS).AST))); 5440b57cec5SDimitry Andric } 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric SMTExprRef mkFPRem(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 5470b57cec5SDimitry Andric return newExprRef( 5480b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_fpa_rem(Context.Context, toZ3Expr(*LHS).AST, 5490b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 5500b57cec5SDimitry Andric } 5510b57cec5SDimitry Andric 5520b57cec5SDimitry Andric SMTExprRef mkFPAdd(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 5530b57cec5SDimitry Andric SMTExprRef RoundingMode = getFloatRoundingMode(); 5540b57cec5SDimitry Andric return newExprRef( 5550b57cec5SDimitry Andric Z3Expr(Context, 5565ffd83dbSDimitry Andric Z3_mk_fpa_add(Context.Context, toZ3Expr(*RoundingMode).AST, 5575ffd83dbSDimitry Andric toZ3Expr(*LHS).AST, toZ3Expr(*RHS).AST))); 5580b57cec5SDimitry Andric } 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric SMTExprRef mkFPSub(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 5610b57cec5SDimitry Andric SMTExprRef RoundingMode = getFloatRoundingMode(); 5620b57cec5SDimitry Andric return newExprRef( 5630b57cec5SDimitry Andric Z3Expr(Context, 5645ffd83dbSDimitry Andric Z3_mk_fpa_sub(Context.Context, toZ3Expr(*RoundingMode).AST, 5655ffd83dbSDimitry Andric toZ3Expr(*LHS).AST, toZ3Expr(*RHS).AST))); 5660b57cec5SDimitry Andric } 5670b57cec5SDimitry Andric 5680b57cec5SDimitry Andric SMTExprRef mkFPLt(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 5690b57cec5SDimitry Andric return newExprRef( 5700b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_fpa_lt(Context.Context, toZ3Expr(*LHS).AST, 5710b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 5720b57cec5SDimitry Andric } 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric SMTExprRef mkFPGt(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 5750b57cec5SDimitry Andric return newExprRef( 5760b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_fpa_gt(Context.Context, toZ3Expr(*LHS).AST, 5770b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 5780b57cec5SDimitry Andric } 5790b57cec5SDimitry Andric 5800b57cec5SDimitry Andric SMTExprRef mkFPLe(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 5810b57cec5SDimitry Andric return newExprRef( 5820b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_fpa_leq(Context.Context, toZ3Expr(*LHS).AST, 5830b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 5840b57cec5SDimitry Andric } 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andric SMTExprRef mkFPGe(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 5870b57cec5SDimitry Andric return newExprRef( 5880b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_fpa_geq(Context.Context, toZ3Expr(*LHS).AST, 5890b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 5900b57cec5SDimitry Andric } 5910b57cec5SDimitry Andric 5920b57cec5SDimitry Andric SMTExprRef mkFPEqual(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 5930b57cec5SDimitry Andric return newExprRef( 5940b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_fpa_eq(Context.Context, toZ3Expr(*LHS).AST, 5950b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 5960b57cec5SDimitry Andric } 5970b57cec5SDimitry Andric 5980b57cec5SDimitry Andric SMTExprRef mkIte(const SMTExprRef &Cond, const SMTExprRef &T, 5990b57cec5SDimitry Andric const SMTExprRef &F) override { 6000b57cec5SDimitry Andric return newExprRef( 6010b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_ite(Context.Context, toZ3Expr(*Cond).AST, 6020b57cec5SDimitry Andric toZ3Expr(*T).AST, toZ3Expr(*F).AST))); 6030b57cec5SDimitry Andric } 6040b57cec5SDimitry Andric 6050b57cec5SDimitry Andric SMTExprRef mkBVSignExt(unsigned i, const SMTExprRef &Exp) override { 6060b57cec5SDimitry Andric return newExprRef(Z3Expr( 6070b57cec5SDimitry Andric Context, Z3_mk_sign_ext(Context.Context, i, toZ3Expr(*Exp).AST))); 6080b57cec5SDimitry Andric } 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric SMTExprRef mkBVZeroExt(unsigned i, const SMTExprRef &Exp) override { 6110b57cec5SDimitry Andric return newExprRef(Z3Expr( 6120b57cec5SDimitry Andric Context, Z3_mk_zero_ext(Context.Context, i, toZ3Expr(*Exp).AST))); 6130b57cec5SDimitry Andric } 6140b57cec5SDimitry Andric 6150b57cec5SDimitry Andric SMTExprRef mkBVExtract(unsigned High, unsigned Low, 6160b57cec5SDimitry Andric const SMTExprRef &Exp) override { 6170b57cec5SDimitry Andric return newExprRef(Z3Expr(Context, Z3_mk_extract(Context.Context, High, Low, 6180b57cec5SDimitry Andric toZ3Expr(*Exp).AST))); 6190b57cec5SDimitry Andric } 6200b57cec5SDimitry Andric 6210b57cec5SDimitry Andric /// Creates a predicate that checks for overflow in a bitvector addition 6220b57cec5SDimitry Andric /// operation 6230b57cec5SDimitry Andric SMTExprRef mkBVAddNoOverflow(const SMTExprRef &LHS, const SMTExprRef &RHS, 6240b57cec5SDimitry Andric bool isSigned) override { 6250b57cec5SDimitry Andric return newExprRef(Z3Expr( 6260b57cec5SDimitry Andric Context, Z3_mk_bvadd_no_overflow(Context.Context, toZ3Expr(*LHS).AST, 6270b57cec5SDimitry Andric toZ3Expr(*RHS).AST, isSigned))); 6280b57cec5SDimitry Andric } 6290b57cec5SDimitry Andric 6300b57cec5SDimitry Andric /// Creates a predicate that checks for underflow in a signed bitvector 6310b57cec5SDimitry Andric /// addition operation 6320b57cec5SDimitry Andric SMTExprRef mkBVAddNoUnderflow(const SMTExprRef &LHS, 6330b57cec5SDimitry Andric const SMTExprRef &RHS) override { 6340b57cec5SDimitry Andric return newExprRef(Z3Expr( 6350b57cec5SDimitry Andric Context, Z3_mk_bvadd_no_underflow(Context.Context, toZ3Expr(*LHS).AST, 6360b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 6370b57cec5SDimitry Andric } 6380b57cec5SDimitry Andric 6390b57cec5SDimitry Andric /// Creates a predicate that checks for overflow in a signed bitvector 6400b57cec5SDimitry Andric /// subtraction operation 6410b57cec5SDimitry Andric SMTExprRef mkBVSubNoOverflow(const SMTExprRef &LHS, 6420b57cec5SDimitry Andric const SMTExprRef &RHS) override { 6430b57cec5SDimitry Andric return newExprRef(Z3Expr( 6440b57cec5SDimitry Andric Context, Z3_mk_bvsub_no_overflow(Context.Context, toZ3Expr(*LHS).AST, 6450b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 6460b57cec5SDimitry Andric } 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric /// Creates a predicate that checks for underflow in a bitvector subtraction 6490b57cec5SDimitry Andric /// operation 6500b57cec5SDimitry Andric SMTExprRef mkBVSubNoUnderflow(const SMTExprRef &LHS, const SMTExprRef &RHS, 6510b57cec5SDimitry Andric bool isSigned) override { 6520b57cec5SDimitry Andric return newExprRef(Z3Expr( 6530b57cec5SDimitry Andric Context, Z3_mk_bvsub_no_underflow(Context.Context, toZ3Expr(*LHS).AST, 6540b57cec5SDimitry Andric toZ3Expr(*RHS).AST, isSigned))); 6550b57cec5SDimitry Andric } 6560b57cec5SDimitry Andric 6570b57cec5SDimitry Andric /// Creates a predicate that checks for overflow in a signed bitvector 6580b57cec5SDimitry Andric /// division/modulus operation 6590b57cec5SDimitry Andric SMTExprRef mkBVSDivNoOverflow(const SMTExprRef &LHS, 6600b57cec5SDimitry Andric const SMTExprRef &RHS) override { 6610b57cec5SDimitry Andric return newExprRef(Z3Expr( 6620b57cec5SDimitry Andric Context, Z3_mk_bvsdiv_no_overflow(Context.Context, toZ3Expr(*LHS).AST, 6630b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 6640b57cec5SDimitry Andric } 6650b57cec5SDimitry Andric 6660b57cec5SDimitry Andric /// Creates a predicate that checks for overflow in a bitvector negation 6670b57cec5SDimitry Andric /// operation 6680b57cec5SDimitry Andric SMTExprRef mkBVNegNoOverflow(const SMTExprRef &Exp) override { 6690b57cec5SDimitry Andric return newExprRef(Z3Expr( 6700b57cec5SDimitry Andric Context, Z3_mk_bvneg_no_overflow(Context.Context, toZ3Expr(*Exp).AST))); 6710b57cec5SDimitry Andric } 6720b57cec5SDimitry Andric 6730b57cec5SDimitry Andric /// Creates a predicate that checks for overflow in a bitvector multiplication 6740b57cec5SDimitry Andric /// operation 6750b57cec5SDimitry Andric SMTExprRef mkBVMulNoOverflow(const SMTExprRef &LHS, const SMTExprRef &RHS, 6760b57cec5SDimitry Andric bool isSigned) override { 6770b57cec5SDimitry Andric return newExprRef(Z3Expr( 6780b57cec5SDimitry Andric Context, Z3_mk_bvmul_no_overflow(Context.Context, toZ3Expr(*LHS).AST, 6790b57cec5SDimitry Andric toZ3Expr(*RHS).AST, isSigned))); 6800b57cec5SDimitry Andric } 6810b57cec5SDimitry Andric 6820b57cec5SDimitry Andric /// Creates a predicate that checks for underflow in a signed bitvector 6830b57cec5SDimitry Andric /// multiplication operation 6840b57cec5SDimitry Andric SMTExprRef mkBVMulNoUnderflow(const SMTExprRef &LHS, 6850b57cec5SDimitry Andric const SMTExprRef &RHS) override { 6860b57cec5SDimitry Andric return newExprRef(Z3Expr( 6870b57cec5SDimitry Andric Context, Z3_mk_bvmul_no_underflow(Context.Context, toZ3Expr(*LHS).AST, 6880b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 6890b57cec5SDimitry Andric } 6900b57cec5SDimitry Andric 6910b57cec5SDimitry Andric SMTExprRef mkBVConcat(const SMTExprRef &LHS, const SMTExprRef &RHS) override { 6920b57cec5SDimitry Andric return newExprRef( 6930b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_concat(Context.Context, toZ3Expr(*LHS).AST, 6940b57cec5SDimitry Andric toZ3Expr(*RHS).AST))); 6950b57cec5SDimitry Andric } 6960b57cec5SDimitry Andric 6970b57cec5SDimitry Andric SMTExprRef mkFPtoFP(const SMTExprRef &From, const SMTSortRef &To) override { 6980b57cec5SDimitry Andric SMTExprRef RoundingMode = getFloatRoundingMode(); 6990b57cec5SDimitry Andric return newExprRef(Z3Expr( 7000b57cec5SDimitry Andric Context, 7010b57cec5SDimitry Andric Z3_mk_fpa_to_fp_float(Context.Context, toZ3Expr(*RoundingMode).AST, 7020b57cec5SDimitry Andric toZ3Expr(*From).AST, toZ3Sort(*To).Sort))); 7030b57cec5SDimitry Andric } 7040b57cec5SDimitry Andric 7050b57cec5SDimitry Andric SMTExprRef mkSBVtoFP(const SMTExprRef &From, const SMTSortRef &To) override { 7060b57cec5SDimitry Andric SMTExprRef RoundingMode = getFloatRoundingMode(); 7070b57cec5SDimitry Andric return newExprRef(Z3Expr( 7080b57cec5SDimitry Andric Context, 7090b57cec5SDimitry Andric Z3_mk_fpa_to_fp_signed(Context.Context, toZ3Expr(*RoundingMode).AST, 7100b57cec5SDimitry Andric toZ3Expr(*From).AST, toZ3Sort(*To).Sort))); 7110b57cec5SDimitry Andric } 7120b57cec5SDimitry Andric 7130b57cec5SDimitry Andric SMTExprRef mkUBVtoFP(const SMTExprRef &From, const SMTSortRef &To) override { 7140b57cec5SDimitry Andric SMTExprRef RoundingMode = getFloatRoundingMode(); 7150b57cec5SDimitry Andric return newExprRef(Z3Expr( 7160b57cec5SDimitry Andric Context, 7170b57cec5SDimitry Andric Z3_mk_fpa_to_fp_unsigned(Context.Context, toZ3Expr(*RoundingMode).AST, 7180b57cec5SDimitry Andric toZ3Expr(*From).AST, toZ3Sort(*To).Sort))); 7190b57cec5SDimitry Andric } 7200b57cec5SDimitry Andric 7210b57cec5SDimitry Andric SMTExprRef mkFPtoSBV(const SMTExprRef &From, unsigned ToWidth) override { 7220b57cec5SDimitry Andric SMTExprRef RoundingMode = getFloatRoundingMode(); 7230b57cec5SDimitry Andric return newExprRef(Z3Expr( 7240b57cec5SDimitry Andric Context, Z3_mk_fpa_to_sbv(Context.Context, toZ3Expr(*RoundingMode).AST, 7250b57cec5SDimitry Andric toZ3Expr(*From).AST, ToWidth))); 7260b57cec5SDimitry Andric } 7270b57cec5SDimitry Andric 7280b57cec5SDimitry Andric SMTExprRef mkFPtoUBV(const SMTExprRef &From, unsigned ToWidth) override { 7290b57cec5SDimitry Andric SMTExprRef RoundingMode = getFloatRoundingMode(); 7300b57cec5SDimitry Andric return newExprRef(Z3Expr( 7310b57cec5SDimitry Andric Context, Z3_mk_fpa_to_ubv(Context.Context, toZ3Expr(*RoundingMode).AST, 7320b57cec5SDimitry Andric toZ3Expr(*From).AST, ToWidth))); 7330b57cec5SDimitry Andric } 7340b57cec5SDimitry Andric 7350b57cec5SDimitry Andric SMTExprRef mkBoolean(const bool b) override { 7360b57cec5SDimitry Andric return newExprRef(Z3Expr(Context, b ? Z3_mk_true(Context.Context) 7370b57cec5SDimitry Andric : Z3_mk_false(Context.Context))); 7380b57cec5SDimitry Andric } 7390b57cec5SDimitry Andric 7400b57cec5SDimitry Andric SMTExprRef mkBitvector(const llvm::APSInt Int, unsigned BitWidth) override { 7415ffd83dbSDimitry Andric const Z3_sort Z3Sort = toZ3Sort(*getBitvectorSort(BitWidth)).Sort; 7425ffd83dbSDimitry Andric 7435ffd83dbSDimitry Andric // Slow path, when 64 bits are not enough. 7441ac55f4cSDimitry Andric if (LLVM_UNLIKELY(!Int.isRepresentableByInt64())) { 7455ffd83dbSDimitry Andric SmallString<40> Buffer; 7465ffd83dbSDimitry Andric Int.toString(Buffer, 10); 7475ffd83dbSDimitry Andric return newExprRef(Z3Expr( 7485ffd83dbSDimitry Andric Context, Z3_mk_numeral(Context.Context, Buffer.c_str(), Z3Sort))); 7495ffd83dbSDimitry Andric } 7505ffd83dbSDimitry Andric 7515ffd83dbSDimitry Andric const int64_t BitReprAsSigned = Int.getExtValue(); 7525ffd83dbSDimitry Andric const uint64_t BitReprAsUnsigned = 7535ffd83dbSDimitry Andric reinterpret_cast<const uint64_t &>(BitReprAsSigned); 7545ffd83dbSDimitry Andric 7555ffd83dbSDimitry Andric Z3_ast Literal = 7565ffd83dbSDimitry Andric Int.isSigned() 7575ffd83dbSDimitry Andric ? Z3_mk_int64(Context.Context, BitReprAsSigned, Z3Sort) 7585ffd83dbSDimitry Andric : Z3_mk_unsigned_int64(Context.Context, BitReprAsUnsigned, Z3Sort); 7595ffd83dbSDimitry Andric return newExprRef(Z3Expr(Context, Literal)); 7600b57cec5SDimitry Andric } 7610b57cec5SDimitry Andric 7620b57cec5SDimitry Andric SMTExprRef mkFloat(const llvm::APFloat Float) override { 7630b57cec5SDimitry Andric SMTSortRef Sort = 7640b57cec5SDimitry Andric getFloatSort(llvm::APFloat::semanticsSizeInBits(Float.getSemantics())); 7650b57cec5SDimitry Andric 7660b57cec5SDimitry Andric llvm::APSInt Int = llvm::APSInt(Float.bitcastToAPInt(), false); 7670b57cec5SDimitry Andric SMTExprRef Z3Int = mkBitvector(Int, Int.getBitWidth()); 7680b57cec5SDimitry Andric return newExprRef(Z3Expr( 7690b57cec5SDimitry Andric Context, Z3_mk_fpa_to_fp_bv(Context.Context, toZ3Expr(*Z3Int).AST, 7700b57cec5SDimitry Andric toZ3Sort(*Sort).Sort))); 7710b57cec5SDimitry Andric } 7720b57cec5SDimitry Andric 7730b57cec5SDimitry Andric SMTExprRef mkSymbol(const char *Name, SMTSortRef Sort) override { 7740b57cec5SDimitry Andric return newExprRef( 7750b57cec5SDimitry Andric Z3Expr(Context, Z3_mk_const(Context.Context, 7760b57cec5SDimitry Andric Z3_mk_string_symbol(Context.Context, Name), 7770b57cec5SDimitry Andric toZ3Sort(*Sort).Sort))); 7780b57cec5SDimitry Andric } 7790b57cec5SDimitry Andric 7800b57cec5SDimitry Andric llvm::APSInt getBitvector(const SMTExprRef &Exp, unsigned BitWidth, 7810b57cec5SDimitry Andric bool isUnsigned) override { 7820b57cec5SDimitry Andric return llvm::APSInt( 7830b57cec5SDimitry Andric llvm::APInt(BitWidth, 7840b57cec5SDimitry Andric Z3_get_numeral_string(Context.Context, toZ3Expr(*Exp).AST), 7850b57cec5SDimitry Andric 10), 7860b57cec5SDimitry Andric isUnsigned); 7870b57cec5SDimitry Andric } 7880b57cec5SDimitry Andric 7890b57cec5SDimitry Andric bool getBoolean(const SMTExprRef &Exp) override { 7900b57cec5SDimitry Andric return Z3_get_bool_value(Context.Context, toZ3Expr(*Exp).AST) == Z3_L_TRUE; 7910b57cec5SDimitry Andric } 7920b57cec5SDimitry Andric 7930b57cec5SDimitry Andric SMTExprRef getFloatRoundingMode() override { 7940b57cec5SDimitry Andric // TODO: Don't assume nearest ties to even rounding mode 7950b57cec5SDimitry Andric return newExprRef(Z3Expr(Context, Z3_mk_fpa_rne(Context.Context))); 7960b57cec5SDimitry Andric } 7970b57cec5SDimitry Andric 7980b57cec5SDimitry Andric bool toAPFloat(const SMTSortRef &Sort, const SMTExprRef &AST, 7990b57cec5SDimitry Andric llvm::APFloat &Float, bool useSemantics) { 8000b57cec5SDimitry Andric assert(Sort->isFloatSort() && "Unsupported sort to floating-point!"); 8010b57cec5SDimitry Andric 8020b57cec5SDimitry Andric llvm::APSInt Int(Sort->getFloatSortSize(), true); 8030b57cec5SDimitry Andric const llvm::fltSemantics &Semantics = 8040b57cec5SDimitry Andric getFloatSemantics(Sort->getFloatSortSize()); 8050b57cec5SDimitry Andric SMTSortRef BVSort = getBitvectorSort(Sort->getFloatSortSize()); 8060b57cec5SDimitry Andric if (!toAPSInt(BVSort, AST, Int, true)) { 8070b57cec5SDimitry Andric return false; 8080b57cec5SDimitry Andric } 8090b57cec5SDimitry Andric 8100b57cec5SDimitry Andric if (useSemantics && !areEquivalent(Float.getSemantics(), Semantics)) { 8110b57cec5SDimitry Andric assert(false && "Floating-point types don't match!"); 8120b57cec5SDimitry Andric return false; 8130b57cec5SDimitry Andric } 8140b57cec5SDimitry Andric 8150b57cec5SDimitry Andric Float = llvm::APFloat(Semantics, Int); 8160b57cec5SDimitry Andric return true; 8170b57cec5SDimitry Andric } 8180b57cec5SDimitry Andric 8190b57cec5SDimitry Andric bool toAPSInt(const SMTSortRef &Sort, const SMTExprRef &AST, 8200b57cec5SDimitry Andric llvm::APSInt &Int, bool useSemantics) { 8210b57cec5SDimitry Andric if (Sort->isBitvectorSort()) { 8220b57cec5SDimitry Andric if (useSemantics && Int.getBitWidth() != Sort->getBitvectorSortSize()) { 8230b57cec5SDimitry Andric assert(false && "Bitvector types don't match!"); 8240b57cec5SDimitry Andric return false; 8250b57cec5SDimitry Andric } 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric // FIXME: This function is also used to retrieve floating-point values, 8280b57cec5SDimitry Andric // which can be 16, 32, 64 or 128 bits long. Bitvectors can be anything 8290b57cec5SDimitry Andric // between 1 and 64 bits long, which is the reason we have this weird 8300b57cec5SDimitry Andric // guard. In the future, we need proper calls in the backend to retrieve 8310b57cec5SDimitry Andric // floating-points and its special values (NaN, +/-infinity, +/-zero), 8320b57cec5SDimitry Andric // then we can drop this weird condition. 8330b57cec5SDimitry Andric if (Sort->getBitvectorSortSize() <= 64 || 8340b57cec5SDimitry Andric Sort->getBitvectorSortSize() == 128) { 8350b57cec5SDimitry Andric Int = getBitvector(AST, Int.getBitWidth(), Int.isUnsigned()); 8360b57cec5SDimitry Andric return true; 8370b57cec5SDimitry Andric } 8380b57cec5SDimitry Andric 8390b57cec5SDimitry Andric assert(false && "Bitwidth not supported!"); 8400b57cec5SDimitry Andric return false; 8410b57cec5SDimitry Andric } 8420b57cec5SDimitry Andric 8430b57cec5SDimitry Andric if (Sort->isBooleanSort()) { 8440b57cec5SDimitry Andric if (useSemantics && Int.getBitWidth() < 1) { 8450b57cec5SDimitry Andric assert(false && "Boolean type doesn't match!"); 8460b57cec5SDimitry Andric return false; 8470b57cec5SDimitry Andric } 8480b57cec5SDimitry Andric 8490b57cec5SDimitry Andric Int = llvm::APSInt(llvm::APInt(Int.getBitWidth(), getBoolean(AST)), 8500b57cec5SDimitry Andric Int.isUnsigned()); 8510b57cec5SDimitry Andric return true; 8520b57cec5SDimitry Andric } 8530b57cec5SDimitry Andric 8540b57cec5SDimitry Andric llvm_unreachable("Unsupported sort to integer!"); 8550b57cec5SDimitry Andric } 8560b57cec5SDimitry Andric 8570b57cec5SDimitry Andric bool getInterpretation(const SMTExprRef &Exp, llvm::APSInt &Int) override { 8580b57cec5SDimitry Andric Z3Model Model(Context, Z3_solver_get_model(Context.Context, Solver)); 8590b57cec5SDimitry Andric Z3_func_decl Func = Z3_get_app_decl( 8600b57cec5SDimitry Andric Context.Context, Z3_to_app(Context.Context, toZ3Expr(*Exp).AST)); 8610b57cec5SDimitry Andric if (Z3_model_has_interp(Context.Context, Model.Model, Func) != Z3_L_TRUE) 8620b57cec5SDimitry Andric return false; 8630b57cec5SDimitry Andric 8640b57cec5SDimitry Andric SMTExprRef Assign = newExprRef( 8650b57cec5SDimitry Andric Z3Expr(Context, 8660b57cec5SDimitry Andric Z3_model_get_const_interp(Context.Context, Model.Model, Func))); 8670b57cec5SDimitry Andric SMTSortRef Sort = getSort(Assign); 8680b57cec5SDimitry Andric return toAPSInt(Sort, Assign, Int, true); 8690b57cec5SDimitry Andric } 8700b57cec5SDimitry Andric 8710b57cec5SDimitry Andric bool getInterpretation(const SMTExprRef &Exp, llvm::APFloat &Float) override { 8720b57cec5SDimitry Andric Z3Model Model(Context, Z3_solver_get_model(Context.Context, Solver)); 8730b57cec5SDimitry Andric Z3_func_decl Func = Z3_get_app_decl( 8740b57cec5SDimitry Andric Context.Context, Z3_to_app(Context.Context, toZ3Expr(*Exp).AST)); 8750b57cec5SDimitry Andric if (Z3_model_has_interp(Context.Context, Model.Model, Func) != Z3_L_TRUE) 8760b57cec5SDimitry Andric return false; 8770b57cec5SDimitry Andric 8780b57cec5SDimitry Andric SMTExprRef Assign = newExprRef( 8790b57cec5SDimitry Andric Z3Expr(Context, 8800b57cec5SDimitry Andric Z3_model_get_const_interp(Context.Context, Model.Model, Func))); 8810b57cec5SDimitry Andric SMTSortRef Sort = getSort(Assign); 8820b57cec5SDimitry Andric return toAPFloat(Sort, Assign, Float, true); 8830b57cec5SDimitry Andric } 8840b57cec5SDimitry Andric 885bdd1243dSDimitry Andric std::optional<bool> check() const override { 8860fca6ea1SDimitry Andric Z3_solver_set_params(Context.Context, Solver, Params); 8870b57cec5SDimitry Andric Z3_lbool res = Z3_solver_check(Context.Context, Solver); 8880b57cec5SDimitry Andric if (res == Z3_L_TRUE) 8890b57cec5SDimitry Andric return true; 8900b57cec5SDimitry Andric 8910b57cec5SDimitry Andric if (res == Z3_L_FALSE) 8920b57cec5SDimitry Andric return false; 8930b57cec5SDimitry Andric 894bdd1243dSDimitry Andric return std::nullopt; 8950b57cec5SDimitry Andric } 8960b57cec5SDimitry Andric 8970b57cec5SDimitry Andric void push() override { return Z3_solver_push(Context.Context, Solver); } 8980b57cec5SDimitry Andric 8990b57cec5SDimitry Andric void pop(unsigned NumStates = 1) override { 9000b57cec5SDimitry Andric assert(Z3_solver_get_num_scopes(Context.Context, Solver) >= NumStates); 9010b57cec5SDimitry Andric return Z3_solver_pop(Context.Context, Solver, NumStates); 9020b57cec5SDimitry Andric } 9030b57cec5SDimitry Andric 9040b57cec5SDimitry Andric bool isFPSupported() override { return true; } 9050b57cec5SDimitry Andric 9060b57cec5SDimitry Andric /// Reset the solver and remove all constraints. 9070b57cec5SDimitry Andric void reset() override { Z3_solver_reset(Context.Context, Solver); } 9080b57cec5SDimitry Andric 9090b57cec5SDimitry Andric void print(raw_ostream &OS) const override { 9100b57cec5SDimitry Andric OS << Z3_solver_to_string(Context.Context, Solver); 9110b57cec5SDimitry Andric } 9120fca6ea1SDimitry Andric 9130fca6ea1SDimitry Andric void setUnsignedParam(StringRef Key, unsigned Value) override { 9140fca6ea1SDimitry Andric Z3_symbol Sym = Z3_mk_string_symbol(Context.Context, Key.str().c_str()); 9150fca6ea1SDimitry Andric Z3_params_set_uint(Context.Context, Params, Sym, Value); 9160fca6ea1SDimitry Andric } 9170fca6ea1SDimitry Andric 9180fca6ea1SDimitry Andric void setBoolParam(StringRef Key, bool Value) override { 9190fca6ea1SDimitry Andric Z3_symbol Sym = Z3_mk_string_symbol(Context.Context, Key.str().c_str()); 9200fca6ea1SDimitry Andric Z3_params_set_bool(Context.Context, Params, Sym, Value); 9210fca6ea1SDimitry Andric } 9220fca6ea1SDimitry Andric 9230fca6ea1SDimitry Andric std::unique_ptr<SMTSolverStatistics> getStatistics() const override; 9240b57cec5SDimitry Andric }; // end class Z3Solver 9250b57cec5SDimitry Andric 9260fca6ea1SDimitry Andric class Z3Statistics final : public SMTSolverStatistics { 9270fca6ea1SDimitry Andric public: 9280fca6ea1SDimitry Andric double getDouble(StringRef Key) const override { 9290fca6ea1SDimitry Andric auto It = DoubleValues.find(Key.str()); 9300fca6ea1SDimitry Andric assert(It != DoubleValues.end()); 9310fca6ea1SDimitry Andric return It->second; 9320fca6ea1SDimitry Andric }; 9330fca6ea1SDimitry Andric unsigned getUnsigned(StringRef Key) const override { 9340fca6ea1SDimitry Andric auto It = UnsignedValues.find(Key.str()); 9350fca6ea1SDimitry Andric assert(It != UnsignedValues.end()); 9360fca6ea1SDimitry Andric return It->second; 9370fca6ea1SDimitry Andric }; 9380fca6ea1SDimitry Andric 9390fca6ea1SDimitry Andric void print(raw_ostream &OS) const override { 9400fca6ea1SDimitry Andric for (auto const &[K, V] : UnsignedValues) { 9410fca6ea1SDimitry Andric OS << K << ": " << V << '\n'; 9420fca6ea1SDimitry Andric } 9430fca6ea1SDimitry Andric for (auto const &[K, V] : DoubleValues) { 9440fca6ea1SDimitry Andric write_double(OS << K << ": ", V, FloatStyle::Fixed); 9450fca6ea1SDimitry Andric OS << '\n'; 9460fca6ea1SDimitry Andric } 9470fca6ea1SDimitry Andric } 9480fca6ea1SDimitry Andric 9490fca6ea1SDimitry Andric private: 9500fca6ea1SDimitry Andric friend class Z3Solver; 9510fca6ea1SDimitry Andric std::unordered_map<std::string, unsigned> UnsignedValues; 9520fca6ea1SDimitry Andric std::unordered_map<std::string, double> DoubleValues; 9530fca6ea1SDimitry Andric }; 9540fca6ea1SDimitry Andric 9550fca6ea1SDimitry Andric std::unique_ptr<SMTSolverStatistics> Z3Solver::getStatistics() const { 9560fca6ea1SDimitry Andric auto const &C = Context.Context; 9570fca6ea1SDimitry Andric Z3_stats S = Z3_solver_get_statistics(C, Solver); 9580fca6ea1SDimitry Andric Z3_stats_inc_ref(C, S); 9590fca6ea1SDimitry Andric auto StatsGuard = llvm::make_scope_exit([&C, &S] { Z3_stats_dec_ref(C, S); }); 9600fca6ea1SDimitry Andric Z3Statistics Result; 9610fca6ea1SDimitry Andric 9620fca6ea1SDimitry Andric unsigned NumKeys = Z3_stats_size(C, S); 9630fca6ea1SDimitry Andric for (unsigned Idx = 0; Idx < NumKeys; ++Idx) { 9640fca6ea1SDimitry Andric const char *Key = Z3_stats_get_key(C, S, Idx); 9650fca6ea1SDimitry Andric if (Z3_stats_is_uint(C, S, Idx)) { 9660fca6ea1SDimitry Andric auto Value = Z3_stats_get_uint_value(C, S, Idx); 9670fca6ea1SDimitry Andric Result.UnsignedValues.try_emplace(Key, Value); 9680fca6ea1SDimitry Andric } else { 9690fca6ea1SDimitry Andric assert(Z3_stats_is_double(C, S, Idx)); 9700fca6ea1SDimitry Andric auto Value = Z3_stats_get_double_value(C, S, Idx); 9710fca6ea1SDimitry Andric Result.DoubleValues.try_emplace(Key, Value); 9720fca6ea1SDimitry Andric } 9730fca6ea1SDimitry Andric } 9740fca6ea1SDimitry Andric return std::make_unique<Z3Statistics>(std::move(Result)); 9750fca6ea1SDimitry Andric } 9760fca6ea1SDimitry Andric 9770b57cec5SDimitry Andric } // end anonymous namespace 9780b57cec5SDimitry Andric 9790b57cec5SDimitry Andric #endif 9800b57cec5SDimitry Andric 9810b57cec5SDimitry Andric llvm::SMTSolverRef llvm::CreateZ3Solver() { 9820b57cec5SDimitry Andric #if LLVM_WITH_Z3 9838bcb0991SDimitry Andric return std::make_unique<Z3Solver>(); 9840b57cec5SDimitry Andric #else 9850b57cec5SDimitry Andric llvm::report_fatal_error("LLVM was not compiled with Z3 support, rebuild " 9860b57cec5SDimitry Andric "with -DLLVM_ENABLE_Z3_SOLVER=ON", 9870b57cec5SDimitry Andric false); 9880b57cec5SDimitry Andric return nullptr; 9890b57cec5SDimitry Andric #endif 9900b57cec5SDimitry Andric } 9910b57cec5SDimitry Andric 9920b57cec5SDimitry Andric LLVM_DUMP_METHOD void SMTSort::dump() const { print(llvm::errs()); } 9930b57cec5SDimitry Andric LLVM_DUMP_METHOD void SMTExpr::dump() const { print(llvm::errs()); } 9940b57cec5SDimitry Andric LLVM_DUMP_METHOD void SMTSolver::dump() const { print(llvm::errs()); } 9950fca6ea1SDimitry Andric LLVM_DUMP_METHOD void SMTSolverStatistics::dump() const { print(llvm::errs()); } 996