1 //== Z3Solver.cpp -----------------------------------------------*- C++ -*--==//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/SmallString.h"
10 #include "llvm/ADT/Twine.h"
11 #include "llvm/Config/config.h"
12 #include "llvm/Support/SMTAPI.h"
23 /// Configuration class for Z3
25 friend class Z3Context
;
30 Z3Config() : Config(Z3_mk_config()) {
31 // Enable model finding
32 Z3_set_param_value(Config
, "model", "true");
33 // Disable proof generation
34 Z3_set_param_value(Config
, "proof", "false");
35 // Set timeout to 15000ms = 15s
36 Z3_set_param_value(Config
, "timeout", "15000");
39 ~Z3Config() { Z3_del_config(Config
); }
40 }; // end class Z3Config
42 // Function used to report errors
43 void Z3ErrorHandler(Z3_context Context
, Z3_error_code Error
) {
44 llvm::report_fatal_error("Z3 error: " +
45 llvm::Twine(Z3_get_error_msg(Context
, Error
)));
48 /// Wrapper for Z3 context
54 Context
= Z3_mk_context_rc(Z3Config().Config
);
55 // The error function is set here because the context is the first object
56 // created by the backend
57 Z3_set_error_handler(Context
, Z3ErrorHandler
);
60 virtual ~Z3Context() {
61 Z3_del_context(Context
);
64 }; // end class Z3Context
66 /// Wrapper for Z3 Sort
67 class Z3Sort
: public SMTSort
{
68 friend class Z3Solver
;
75 /// Default constructor, mainly used by make_shared
76 Z3Sort(Z3Context
&C
, Z3_sort ZS
) : Context(C
), Sort(ZS
) {
77 Z3_inc_ref(Context
.Context
, reinterpret_cast<Z3_ast
>(Sort
));
80 /// Override implicit copy constructor for correct reference counting.
81 Z3Sort(const Z3Sort
&Other
) : Context(Other
.Context
), Sort(Other
.Sort
) {
82 Z3_inc_ref(Context
.Context
, reinterpret_cast<Z3_ast
>(Sort
));
85 /// Override implicit copy assignment constructor for correct reference
87 Z3Sort
&operator=(const Z3Sort
&Other
) {
88 Z3_inc_ref(Context
.Context
, reinterpret_cast<Z3_ast
>(Other
.Sort
));
89 Z3_dec_ref(Context
.Context
, reinterpret_cast<Z3_ast
>(Sort
));
94 Z3Sort(Z3Sort
&&Other
) = delete;
95 Z3Sort
&operator=(Z3Sort
&&Other
) = delete;
99 Z3_dec_ref(Context
.Context
, reinterpret_cast<Z3_ast
>(Sort
));
102 void Profile(llvm::FoldingSetNodeID
&ID
) const override
{
104 Z3_get_ast_id(Context
.Context
, reinterpret_cast<Z3_ast
>(Sort
)));
107 bool isBitvectorSortImpl() const override
{
108 return (Z3_get_sort_kind(Context
.Context
, Sort
) == Z3_BV_SORT
);
111 bool isFloatSortImpl() const override
{
112 return (Z3_get_sort_kind(Context
.Context
, Sort
) == Z3_FLOATING_POINT_SORT
);
115 bool isBooleanSortImpl() const override
{
116 return (Z3_get_sort_kind(Context
.Context
, Sort
) == Z3_BOOL_SORT
);
119 unsigned getBitvectorSortSizeImpl() const override
{
120 return Z3_get_bv_sort_size(Context
.Context
, Sort
);
123 unsigned getFloatSortSizeImpl() const override
{
124 return Z3_fpa_get_ebits(Context
.Context
, Sort
) +
125 Z3_fpa_get_sbits(Context
.Context
, Sort
);
128 bool equal_to(SMTSort
const &Other
) const override
{
129 return Z3_is_eq_sort(Context
.Context
, Sort
,
130 static_cast<const Z3Sort
&>(Other
).Sort
);
133 void print(raw_ostream
&OS
) const override
{
134 OS
<< Z3_sort_to_string(Context
.Context
, Sort
);
136 }; // end class Z3Sort
138 static const Z3Sort
&toZ3Sort(const SMTSort
&S
) {
139 return static_cast<const Z3Sort
&>(S
);
142 class Z3Expr
: public SMTExpr
{
143 friend class Z3Solver
;
150 Z3Expr(Z3Context
&C
, Z3_ast ZA
) : SMTExpr(), Context(C
), AST(ZA
) {
151 Z3_inc_ref(Context
.Context
, AST
);
154 /// Override implicit copy constructor for correct reference counting.
155 Z3Expr(const Z3Expr
&Copy
) : SMTExpr(), Context(Copy
.Context
), AST(Copy
.AST
) {
156 Z3_inc_ref(Context
.Context
, AST
);
159 /// Override implicit copy assignment constructor for correct reference
161 Z3Expr
&operator=(const Z3Expr
&Other
) {
162 Z3_inc_ref(Context
.Context
, Other
.AST
);
163 Z3_dec_ref(Context
.Context
, AST
);
168 Z3Expr(Z3Expr
&&Other
) = delete;
169 Z3Expr
&operator=(Z3Expr
&&Other
) = delete;
173 Z3_dec_ref(Context
.Context
, AST
);
176 void Profile(llvm::FoldingSetNodeID
&ID
) const override
{
177 ID
.AddInteger(Z3_get_ast_id(Context
.Context
, AST
));
180 /// Comparison of AST equality, not model equivalence.
181 bool equal_to(SMTExpr
const &Other
) const override
{
182 assert(Z3_is_eq_sort(Context
.Context
, Z3_get_sort(Context
.Context
, AST
),
183 Z3_get_sort(Context
.Context
,
184 static_cast<const Z3Expr
&>(Other
).AST
)) &&
185 "AST's must have the same sort");
186 return Z3_is_eq_ast(Context
.Context
, AST
,
187 static_cast<const Z3Expr
&>(Other
).AST
);
190 void print(raw_ostream
&OS
) const override
{
191 OS
<< Z3_ast_to_string(Context
.Context
, AST
);
193 }; // end class Z3Expr
195 static const Z3Expr
&toZ3Expr(const SMTExpr
&E
) {
196 return static_cast<const Z3Expr
&>(E
);
200 friend class Z3Solver
;
207 Z3Model(Z3Context
&C
, Z3_model ZM
) : Context(C
), Model(ZM
) {
208 Z3_model_inc_ref(Context
.Context
, Model
);
211 Z3Model(const Z3Model
&Other
) = delete;
212 Z3Model(Z3Model
&&Other
) = delete;
213 Z3Model
&operator=(Z3Model
&Other
) = delete;
214 Z3Model
&operator=(Z3Model
&&Other
) = delete;
218 Z3_model_dec_ref(Context
.Context
, Model
);
221 void print(raw_ostream
&OS
) const {
222 OS
<< Z3_model_to_string(Context
.Context
, Model
);
225 LLVM_DUMP_METHOD
void dump() const { print(llvm::errs()); }
226 }; // end class Z3Model
228 /// Get the corresponding IEEE floating-point type for a given bitwidth.
229 static const llvm::fltSemantics
&getFloatSemantics(unsigned BitWidth
) {
232 llvm_unreachable("Unsupported floating-point semantics!");
235 return llvm::APFloat::IEEEhalf();
237 return llvm::APFloat::IEEEsingle();
239 return llvm::APFloat::IEEEdouble();
241 return llvm::APFloat::IEEEquad();
245 // Determine whether two float semantics are equivalent
246 static bool areEquivalent(const llvm::fltSemantics
&LHS
,
247 const llvm::fltSemantics
&RHS
) {
248 return (llvm::APFloat::semanticsPrecision(LHS
) ==
249 llvm::APFloat::semanticsPrecision(RHS
)) &&
250 (llvm::APFloat::semanticsMinExponent(LHS
) ==
251 llvm::APFloat::semanticsMinExponent(RHS
)) &&
252 (llvm::APFloat::semanticsMaxExponent(LHS
) ==
253 llvm::APFloat::semanticsMaxExponent(RHS
)) &&
254 (llvm::APFloat::semanticsSizeInBits(LHS
) ==
255 llvm::APFloat::semanticsSizeInBits(RHS
));
258 class Z3Solver
: public SMTSolver
{
259 friend class Z3ConstraintManager
;
266 std::set
<Z3Sort
> CachedSorts
;
269 std::set
<Z3Expr
> CachedExprs
;
272 Z3Solver() : Solver(Z3_mk_simple_solver(Context
.Context
)) {
273 Z3_solver_inc_ref(Context
.Context
, Solver
);
276 Z3Solver(const Z3Solver
&Other
) = delete;
277 Z3Solver(Z3Solver
&&Other
) = delete;
278 Z3Solver
&operator=(Z3Solver
&Other
) = delete;
279 Z3Solver
&operator=(Z3Solver
&&Other
) = delete;
283 Z3_solver_dec_ref(Context
.Context
, Solver
);
286 void addConstraint(const SMTExprRef
&Exp
) const override
{
287 Z3_solver_assert(Context
.Context
, Solver
, toZ3Expr(*Exp
).AST
);
290 // Given an SMTSort, adds/retrives it from the cache and returns
291 // an SMTSortRef to the SMTSort in the cache
292 SMTSortRef
newSortRef(const SMTSort
&Sort
) {
293 auto It
= CachedSorts
.insert(toZ3Sort(Sort
));
297 // Given an SMTExpr, adds/retrives it from the cache and returns
298 // an SMTExprRef to the SMTExpr in the cache
299 SMTExprRef
newExprRef(const SMTExpr
&Exp
) {
300 auto It
= CachedExprs
.insert(toZ3Expr(Exp
));
304 SMTSortRef
getBoolSort() override
{
305 return newSortRef(Z3Sort(Context
, Z3_mk_bool_sort(Context
.Context
)));
308 SMTSortRef
getBitvectorSort(unsigned BitWidth
) override
{
310 Z3Sort(Context
, Z3_mk_bv_sort(Context
.Context
, BitWidth
)));
313 SMTSortRef
getSort(const SMTExprRef
&Exp
) override
{
315 Z3Sort(Context
, Z3_get_sort(Context
.Context
, toZ3Expr(*Exp
).AST
)));
318 SMTSortRef
getFloat16Sort() override
{
319 return newSortRef(Z3Sort(Context
, Z3_mk_fpa_sort_16(Context
.Context
)));
322 SMTSortRef
getFloat32Sort() override
{
323 return newSortRef(Z3Sort(Context
, Z3_mk_fpa_sort_32(Context
.Context
)));
326 SMTSortRef
getFloat64Sort() override
{
327 return newSortRef(Z3Sort(Context
, Z3_mk_fpa_sort_64(Context
.Context
)));
330 SMTSortRef
getFloat128Sort() override
{
331 return newSortRef(Z3Sort(Context
, Z3_mk_fpa_sort_128(Context
.Context
)));
334 SMTExprRef
mkBVNeg(const SMTExprRef
&Exp
) override
{
336 Z3Expr(Context
, Z3_mk_bvneg(Context
.Context
, toZ3Expr(*Exp
).AST
)));
339 SMTExprRef
mkBVNot(const SMTExprRef
&Exp
) override
{
341 Z3Expr(Context
, Z3_mk_bvnot(Context
.Context
, toZ3Expr(*Exp
).AST
)));
344 SMTExprRef
mkNot(const SMTExprRef
&Exp
) override
{
346 Z3Expr(Context
, Z3_mk_not(Context
.Context
, toZ3Expr(*Exp
).AST
)));
349 SMTExprRef
mkBVAdd(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
351 Z3Expr(Context
, Z3_mk_bvadd(Context
.Context
, toZ3Expr(*LHS
).AST
,
352 toZ3Expr(*RHS
).AST
)));
355 SMTExprRef
mkBVSub(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
357 Z3Expr(Context
, Z3_mk_bvsub(Context
.Context
, toZ3Expr(*LHS
).AST
,
358 toZ3Expr(*RHS
).AST
)));
361 SMTExprRef
mkBVMul(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
363 Z3Expr(Context
, Z3_mk_bvmul(Context
.Context
, toZ3Expr(*LHS
).AST
,
364 toZ3Expr(*RHS
).AST
)));
367 SMTExprRef
mkBVSRem(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
369 Z3Expr(Context
, Z3_mk_bvsrem(Context
.Context
, toZ3Expr(*LHS
).AST
,
370 toZ3Expr(*RHS
).AST
)));
373 SMTExprRef
mkBVURem(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
375 Z3Expr(Context
, Z3_mk_bvurem(Context
.Context
, toZ3Expr(*LHS
).AST
,
376 toZ3Expr(*RHS
).AST
)));
379 SMTExprRef
mkBVSDiv(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
381 Z3Expr(Context
, Z3_mk_bvsdiv(Context
.Context
, toZ3Expr(*LHS
).AST
,
382 toZ3Expr(*RHS
).AST
)));
385 SMTExprRef
mkBVUDiv(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
387 Z3Expr(Context
, Z3_mk_bvudiv(Context
.Context
, toZ3Expr(*LHS
).AST
,
388 toZ3Expr(*RHS
).AST
)));
391 SMTExprRef
mkBVShl(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
393 Z3Expr(Context
, Z3_mk_bvshl(Context
.Context
, toZ3Expr(*LHS
).AST
,
394 toZ3Expr(*RHS
).AST
)));
397 SMTExprRef
mkBVAshr(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
399 Z3Expr(Context
, Z3_mk_bvashr(Context
.Context
, toZ3Expr(*LHS
).AST
,
400 toZ3Expr(*RHS
).AST
)));
403 SMTExprRef
mkBVLshr(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
405 Z3Expr(Context
, Z3_mk_bvlshr(Context
.Context
, toZ3Expr(*LHS
).AST
,
406 toZ3Expr(*RHS
).AST
)));
409 SMTExprRef
mkBVXor(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
411 Z3Expr(Context
, Z3_mk_bvxor(Context
.Context
, toZ3Expr(*LHS
).AST
,
412 toZ3Expr(*RHS
).AST
)));
415 SMTExprRef
mkBVOr(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
417 Z3Expr(Context
, Z3_mk_bvor(Context
.Context
, toZ3Expr(*LHS
).AST
,
418 toZ3Expr(*RHS
).AST
)));
421 SMTExprRef
mkBVAnd(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
423 Z3Expr(Context
, Z3_mk_bvand(Context
.Context
, toZ3Expr(*LHS
).AST
,
424 toZ3Expr(*RHS
).AST
)));
427 SMTExprRef
mkBVUlt(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
429 Z3Expr(Context
, Z3_mk_bvult(Context
.Context
, toZ3Expr(*LHS
).AST
,
430 toZ3Expr(*RHS
).AST
)));
433 SMTExprRef
mkBVSlt(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
435 Z3Expr(Context
, Z3_mk_bvslt(Context
.Context
, toZ3Expr(*LHS
).AST
,
436 toZ3Expr(*RHS
).AST
)));
439 SMTExprRef
mkBVUgt(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
441 Z3Expr(Context
, Z3_mk_bvugt(Context
.Context
, toZ3Expr(*LHS
).AST
,
442 toZ3Expr(*RHS
).AST
)));
445 SMTExprRef
mkBVSgt(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
447 Z3Expr(Context
, Z3_mk_bvsgt(Context
.Context
, toZ3Expr(*LHS
).AST
,
448 toZ3Expr(*RHS
).AST
)));
451 SMTExprRef
mkBVUle(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
453 Z3Expr(Context
, Z3_mk_bvule(Context
.Context
, toZ3Expr(*LHS
).AST
,
454 toZ3Expr(*RHS
).AST
)));
457 SMTExprRef
mkBVSle(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
459 Z3Expr(Context
, Z3_mk_bvsle(Context
.Context
, toZ3Expr(*LHS
).AST
,
460 toZ3Expr(*RHS
).AST
)));
463 SMTExprRef
mkBVUge(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
465 Z3Expr(Context
, Z3_mk_bvuge(Context
.Context
, toZ3Expr(*LHS
).AST
,
466 toZ3Expr(*RHS
).AST
)));
469 SMTExprRef
mkBVSge(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
471 Z3Expr(Context
, Z3_mk_bvsge(Context
.Context
, toZ3Expr(*LHS
).AST
,
472 toZ3Expr(*RHS
).AST
)));
475 SMTExprRef
mkAnd(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
476 Z3_ast Args
[2] = {toZ3Expr(*LHS
).AST
, toZ3Expr(*RHS
).AST
};
477 return newExprRef(Z3Expr(Context
, Z3_mk_and(Context
.Context
, 2, Args
)));
480 SMTExprRef
mkOr(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
481 Z3_ast Args
[2] = {toZ3Expr(*LHS
).AST
, toZ3Expr(*RHS
).AST
};
482 return newExprRef(Z3Expr(Context
, Z3_mk_or(Context
.Context
, 2, Args
)));
485 SMTExprRef
mkEqual(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
487 Z3Expr(Context
, Z3_mk_eq(Context
.Context
, toZ3Expr(*LHS
).AST
,
488 toZ3Expr(*RHS
).AST
)));
491 SMTExprRef
mkFPNeg(const SMTExprRef
&Exp
) override
{
493 Z3Expr(Context
, Z3_mk_fpa_neg(Context
.Context
, toZ3Expr(*Exp
).AST
)));
496 SMTExprRef
mkFPIsInfinite(const SMTExprRef
&Exp
) override
{
497 return newExprRef(Z3Expr(
498 Context
, Z3_mk_fpa_is_infinite(Context
.Context
, toZ3Expr(*Exp
).AST
)));
501 SMTExprRef
mkFPIsNaN(const SMTExprRef
&Exp
) override
{
503 Z3Expr(Context
, Z3_mk_fpa_is_nan(Context
.Context
, toZ3Expr(*Exp
).AST
)));
506 SMTExprRef
mkFPIsNormal(const SMTExprRef
&Exp
) override
{
507 return newExprRef(Z3Expr(
508 Context
, Z3_mk_fpa_is_normal(Context
.Context
, toZ3Expr(*Exp
).AST
)));
511 SMTExprRef
mkFPIsZero(const SMTExprRef
&Exp
) override
{
512 return newExprRef(Z3Expr(
513 Context
, Z3_mk_fpa_is_zero(Context
.Context
, toZ3Expr(*Exp
).AST
)));
516 SMTExprRef
mkFPMul(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
517 SMTExprRef RoundingMode
= getFloatRoundingMode();
520 Z3_mk_fpa_mul(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
521 toZ3Expr(*LHS
).AST
, toZ3Expr(*RHS
).AST
)));
524 SMTExprRef
mkFPDiv(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
525 SMTExprRef RoundingMode
= getFloatRoundingMode();
528 Z3_mk_fpa_div(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
529 toZ3Expr(*LHS
).AST
, toZ3Expr(*RHS
).AST
)));
532 SMTExprRef
mkFPRem(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
534 Z3Expr(Context
, Z3_mk_fpa_rem(Context
.Context
, toZ3Expr(*LHS
).AST
,
535 toZ3Expr(*RHS
).AST
)));
538 SMTExprRef
mkFPAdd(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
539 SMTExprRef RoundingMode
= getFloatRoundingMode();
542 Z3_mk_fpa_add(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
543 toZ3Expr(*LHS
).AST
, toZ3Expr(*RHS
).AST
)));
546 SMTExprRef
mkFPSub(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
547 SMTExprRef RoundingMode
= getFloatRoundingMode();
550 Z3_mk_fpa_sub(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
551 toZ3Expr(*LHS
).AST
, toZ3Expr(*RHS
).AST
)));
554 SMTExprRef
mkFPLt(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
556 Z3Expr(Context
, Z3_mk_fpa_lt(Context
.Context
, toZ3Expr(*LHS
).AST
,
557 toZ3Expr(*RHS
).AST
)));
560 SMTExprRef
mkFPGt(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
562 Z3Expr(Context
, Z3_mk_fpa_gt(Context
.Context
, toZ3Expr(*LHS
).AST
,
563 toZ3Expr(*RHS
).AST
)));
566 SMTExprRef
mkFPLe(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
568 Z3Expr(Context
, Z3_mk_fpa_leq(Context
.Context
, toZ3Expr(*LHS
).AST
,
569 toZ3Expr(*RHS
).AST
)));
572 SMTExprRef
mkFPGe(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
574 Z3Expr(Context
, Z3_mk_fpa_geq(Context
.Context
, toZ3Expr(*LHS
).AST
,
575 toZ3Expr(*RHS
).AST
)));
578 SMTExprRef
mkFPEqual(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
580 Z3Expr(Context
, Z3_mk_fpa_eq(Context
.Context
, toZ3Expr(*LHS
).AST
,
581 toZ3Expr(*RHS
).AST
)));
584 SMTExprRef
mkIte(const SMTExprRef
&Cond
, const SMTExprRef
&T
,
585 const SMTExprRef
&F
) override
{
587 Z3Expr(Context
, Z3_mk_ite(Context
.Context
, toZ3Expr(*Cond
).AST
,
588 toZ3Expr(*T
).AST
, toZ3Expr(*F
).AST
)));
591 SMTExprRef
mkBVSignExt(unsigned i
, const SMTExprRef
&Exp
) override
{
592 return newExprRef(Z3Expr(
593 Context
, Z3_mk_sign_ext(Context
.Context
, i
, toZ3Expr(*Exp
).AST
)));
596 SMTExprRef
mkBVZeroExt(unsigned i
, const SMTExprRef
&Exp
) override
{
597 return newExprRef(Z3Expr(
598 Context
, Z3_mk_zero_ext(Context
.Context
, i
, toZ3Expr(*Exp
).AST
)));
601 SMTExprRef
mkBVExtract(unsigned High
, unsigned Low
,
602 const SMTExprRef
&Exp
) override
{
603 return newExprRef(Z3Expr(Context
, Z3_mk_extract(Context
.Context
, High
, Low
,
604 toZ3Expr(*Exp
).AST
)));
607 /// Creates a predicate that checks for overflow in a bitvector addition
609 SMTExprRef
mkBVAddNoOverflow(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
,
610 bool isSigned
) override
{
611 return newExprRef(Z3Expr(
612 Context
, Z3_mk_bvadd_no_overflow(Context
.Context
, toZ3Expr(*LHS
).AST
,
613 toZ3Expr(*RHS
).AST
, isSigned
)));
616 /// Creates a predicate that checks for underflow in a signed bitvector
617 /// addition operation
618 SMTExprRef
mkBVAddNoUnderflow(const SMTExprRef
&LHS
,
619 const SMTExprRef
&RHS
) override
{
620 return newExprRef(Z3Expr(
621 Context
, Z3_mk_bvadd_no_underflow(Context
.Context
, toZ3Expr(*LHS
).AST
,
622 toZ3Expr(*RHS
).AST
)));
625 /// Creates a predicate that checks for overflow in a signed bitvector
626 /// subtraction operation
627 SMTExprRef
mkBVSubNoOverflow(const SMTExprRef
&LHS
,
628 const SMTExprRef
&RHS
) override
{
629 return newExprRef(Z3Expr(
630 Context
, Z3_mk_bvsub_no_overflow(Context
.Context
, toZ3Expr(*LHS
).AST
,
631 toZ3Expr(*RHS
).AST
)));
634 /// Creates a predicate that checks for underflow in a bitvector subtraction
636 SMTExprRef
mkBVSubNoUnderflow(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
,
637 bool isSigned
) override
{
638 return newExprRef(Z3Expr(
639 Context
, Z3_mk_bvsub_no_underflow(Context
.Context
, toZ3Expr(*LHS
).AST
,
640 toZ3Expr(*RHS
).AST
, isSigned
)));
643 /// Creates a predicate that checks for overflow in a signed bitvector
644 /// division/modulus operation
645 SMTExprRef
mkBVSDivNoOverflow(const SMTExprRef
&LHS
,
646 const SMTExprRef
&RHS
) override
{
647 return newExprRef(Z3Expr(
648 Context
, Z3_mk_bvsdiv_no_overflow(Context
.Context
, toZ3Expr(*LHS
).AST
,
649 toZ3Expr(*RHS
).AST
)));
652 /// Creates a predicate that checks for overflow in a bitvector negation
654 SMTExprRef
mkBVNegNoOverflow(const SMTExprRef
&Exp
) override
{
655 return newExprRef(Z3Expr(
656 Context
, Z3_mk_bvneg_no_overflow(Context
.Context
, toZ3Expr(*Exp
).AST
)));
659 /// Creates a predicate that checks for overflow in a bitvector multiplication
661 SMTExprRef
mkBVMulNoOverflow(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
,
662 bool isSigned
) override
{
663 return newExprRef(Z3Expr(
664 Context
, Z3_mk_bvmul_no_overflow(Context
.Context
, toZ3Expr(*LHS
).AST
,
665 toZ3Expr(*RHS
).AST
, isSigned
)));
668 /// Creates a predicate that checks for underflow in a signed bitvector
669 /// multiplication operation
670 SMTExprRef
mkBVMulNoUnderflow(const SMTExprRef
&LHS
,
671 const SMTExprRef
&RHS
) override
{
672 return newExprRef(Z3Expr(
673 Context
, Z3_mk_bvmul_no_underflow(Context
.Context
, toZ3Expr(*LHS
).AST
,
674 toZ3Expr(*RHS
).AST
)));
677 SMTExprRef
mkBVConcat(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
679 Z3Expr(Context
, Z3_mk_concat(Context
.Context
, toZ3Expr(*LHS
).AST
,
680 toZ3Expr(*RHS
).AST
)));
683 SMTExprRef
mkFPtoFP(const SMTExprRef
&From
, const SMTSortRef
&To
) override
{
684 SMTExprRef RoundingMode
= getFloatRoundingMode();
685 return newExprRef(Z3Expr(
687 Z3_mk_fpa_to_fp_float(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
688 toZ3Expr(*From
).AST
, toZ3Sort(*To
).Sort
)));
691 SMTExprRef
mkSBVtoFP(const SMTExprRef
&From
, const SMTSortRef
&To
) override
{
692 SMTExprRef RoundingMode
= getFloatRoundingMode();
693 return newExprRef(Z3Expr(
695 Z3_mk_fpa_to_fp_signed(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
696 toZ3Expr(*From
).AST
, toZ3Sort(*To
).Sort
)));
699 SMTExprRef
mkUBVtoFP(const SMTExprRef
&From
, const SMTSortRef
&To
) override
{
700 SMTExprRef RoundingMode
= getFloatRoundingMode();
701 return newExprRef(Z3Expr(
703 Z3_mk_fpa_to_fp_unsigned(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
704 toZ3Expr(*From
).AST
, toZ3Sort(*To
).Sort
)));
707 SMTExprRef
mkFPtoSBV(const SMTExprRef
&From
, unsigned ToWidth
) override
{
708 SMTExprRef RoundingMode
= getFloatRoundingMode();
709 return newExprRef(Z3Expr(
710 Context
, Z3_mk_fpa_to_sbv(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
711 toZ3Expr(*From
).AST
, ToWidth
)));
714 SMTExprRef
mkFPtoUBV(const SMTExprRef
&From
, unsigned ToWidth
) override
{
715 SMTExprRef RoundingMode
= getFloatRoundingMode();
716 return newExprRef(Z3Expr(
717 Context
, Z3_mk_fpa_to_ubv(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
718 toZ3Expr(*From
).AST
, ToWidth
)));
721 SMTExprRef
mkBoolean(const bool b
) override
{
722 return newExprRef(Z3Expr(Context
, b
? Z3_mk_true(Context
.Context
)
723 : Z3_mk_false(Context
.Context
)));
726 SMTExprRef
mkBitvector(const llvm::APSInt Int
, unsigned BitWidth
) override
{
727 const Z3_sort Z3Sort
= toZ3Sort(*getBitvectorSort(BitWidth
)).Sort
;
729 // Slow path, when 64 bits are not enough.
730 if (LLVM_UNLIKELY(Int
.getBitWidth() > 64u)) {
731 SmallString
<40> Buffer
;
732 Int
.toString(Buffer
, 10);
733 return newExprRef(Z3Expr(
734 Context
, Z3_mk_numeral(Context
.Context
, Buffer
.c_str(), Z3Sort
)));
737 const int64_t BitReprAsSigned
= Int
.getExtValue();
738 const uint64_t BitReprAsUnsigned
=
739 reinterpret_cast<const uint64_t &>(BitReprAsSigned
);
743 ? Z3_mk_int64(Context
.Context
, BitReprAsSigned
, Z3Sort
)
744 : Z3_mk_unsigned_int64(Context
.Context
, BitReprAsUnsigned
, Z3Sort
);
745 return newExprRef(Z3Expr(Context
, Literal
));
748 SMTExprRef
mkFloat(const llvm::APFloat Float
) override
{
750 getFloatSort(llvm::APFloat::semanticsSizeInBits(Float
.getSemantics()));
752 llvm::APSInt Int
= llvm::APSInt(Float
.bitcastToAPInt(), false);
753 SMTExprRef Z3Int
= mkBitvector(Int
, Int
.getBitWidth());
754 return newExprRef(Z3Expr(
755 Context
, Z3_mk_fpa_to_fp_bv(Context
.Context
, toZ3Expr(*Z3Int
).AST
,
756 toZ3Sort(*Sort
).Sort
)));
759 SMTExprRef
mkSymbol(const char *Name
, SMTSortRef Sort
) override
{
761 Z3Expr(Context
, Z3_mk_const(Context
.Context
,
762 Z3_mk_string_symbol(Context
.Context
, Name
),
763 toZ3Sort(*Sort
).Sort
)));
766 llvm::APSInt
getBitvector(const SMTExprRef
&Exp
, unsigned BitWidth
,
767 bool isUnsigned
) override
{
769 llvm::APInt(BitWidth
,
770 Z3_get_numeral_string(Context
.Context
, toZ3Expr(*Exp
).AST
),
775 bool getBoolean(const SMTExprRef
&Exp
) override
{
776 return Z3_get_bool_value(Context
.Context
, toZ3Expr(*Exp
).AST
) == Z3_L_TRUE
;
779 SMTExprRef
getFloatRoundingMode() override
{
780 // TODO: Don't assume nearest ties to even rounding mode
781 return newExprRef(Z3Expr(Context
, Z3_mk_fpa_rne(Context
.Context
)));
784 bool toAPFloat(const SMTSortRef
&Sort
, const SMTExprRef
&AST
,
785 llvm::APFloat
&Float
, bool useSemantics
) {
786 assert(Sort
->isFloatSort() && "Unsupported sort to floating-point!");
788 llvm::APSInt
Int(Sort
->getFloatSortSize(), true);
789 const llvm::fltSemantics
&Semantics
=
790 getFloatSemantics(Sort
->getFloatSortSize());
791 SMTSortRef BVSort
= getBitvectorSort(Sort
->getFloatSortSize());
792 if (!toAPSInt(BVSort
, AST
, Int
, true)) {
796 if (useSemantics
&& !areEquivalent(Float
.getSemantics(), Semantics
)) {
797 assert(false && "Floating-point types don't match!");
801 Float
= llvm::APFloat(Semantics
, Int
);
805 bool toAPSInt(const SMTSortRef
&Sort
, const SMTExprRef
&AST
,
806 llvm::APSInt
&Int
, bool useSemantics
) {
807 if (Sort
->isBitvectorSort()) {
808 if (useSemantics
&& Int
.getBitWidth() != Sort
->getBitvectorSortSize()) {
809 assert(false && "Bitvector types don't match!");
813 // FIXME: This function is also used to retrieve floating-point values,
814 // which can be 16, 32, 64 or 128 bits long. Bitvectors can be anything
815 // between 1 and 64 bits long, which is the reason we have this weird
816 // guard. In the future, we need proper calls in the backend to retrieve
817 // floating-points and its special values (NaN, +/-infinity, +/-zero),
818 // then we can drop this weird condition.
819 if (Sort
->getBitvectorSortSize() <= 64 ||
820 Sort
->getBitvectorSortSize() == 128) {
821 Int
= getBitvector(AST
, Int
.getBitWidth(), Int
.isUnsigned());
825 assert(false && "Bitwidth not supported!");
829 if (Sort
->isBooleanSort()) {
830 if (useSemantics
&& Int
.getBitWidth() < 1) {
831 assert(false && "Boolean type doesn't match!");
835 Int
= llvm::APSInt(llvm::APInt(Int
.getBitWidth(), getBoolean(AST
)),
840 llvm_unreachable("Unsupported sort to integer!");
843 bool getInterpretation(const SMTExprRef
&Exp
, llvm::APSInt
&Int
) override
{
844 Z3Model
Model(Context
, Z3_solver_get_model(Context
.Context
, Solver
));
845 Z3_func_decl Func
= Z3_get_app_decl(
846 Context
.Context
, Z3_to_app(Context
.Context
, toZ3Expr(*Exp
).AST
));
847 if (Z3_model_has_interp(Context
.Context
, Model
.Model
, Func
) != Z3_L_TRUE
)
850 SMTExprRef Assign
= newExprRef(
852 Z3_model_get_const_interp(Context
.Context
, Model
.Model
, Func
)));
853 SMTSortRef Sort
= getSort(Assign
);
854 return toAPSInt(Sort
, Assign
, Int
, true);
857 bool getInterpretation(const SMTExprRef
&Exp
, llvm::APFloat
&Float
) override
{
858 Z3Model
Model(Context
, Z3_solver_get_model(Context
.Context
, Solver
));
859 Z3_func_decl Func
= Z3_get_app_decl(
860 Context
.Context
, Z3_to_app(Context
.Context
, toZ3Expr(*Exp
).AST
));
861 if (Z3_model_has_interp(Context
.Context
, Model
.Model
, Func
) != Z3_L_TRUE
)
864 SMTExprRef Assign
= newExprRef(
866 Z3_model_get_const_interp(Context
.Context
, Model
.Model
, Func
)));
867 SMTSortRef Sort
= getSort(Assign
);
868 return toAPFloat(Sort
, Assign
, Float
, true);
871 Optional
<bool> check() const override
{
872 Z3_lbool res
= Z3_solver_check(Context
.Context
, Solver
);
873 if (res
== Z3_L_TRUE
)
876 if (res
== Z3_L_FALSE
)
879 return Optional
<bool>();
882 void push() override
{ return Z3_solver_push(Context
.Context
, Solver
); }
884 void pop(unsigned NumStates
= 1) override
{
885 assert(Z3_solver_get_num_scopes(Context
.Context
, Solver
) >= NumStates
);
886 return Z3_solver_pop(Context
.Context
, Solver
, NumStates
);
889 bool isFPSupported() override
{ return true; }
891 /// Reset the solver and remove all constraints.
892 void reset() override
{ Z3_solver_reset(Context
.Context
, Solver
); }
894 void print(raw_ostream
&OS
) const override
{
895 OS
<< Z3_solver_to_string(Context
.Context
, Solver
);
897 }; // end class Z3Solver
899 } // end anonymous namespace
903 llvm::SMTSolverRef
llvm::CreateZ3Solver() {
905 return std::make_unique
<Z3Solver
>();
907 llvm::report_fatal_error("LLVM was not compiled with Z3 support, rebuild "
908 "with -DLLVM_ENABLE_Z3_SOLVER=ON",
914 LLVM_DUMP_METHOD
void SMTSort::dump() const { print(llvm::errs()); }
915 LLVM_DUMP_METHOD
void SMTExpr::dump() const { print(llvm::errs()); }
916 LLVM_DUMP_METHOD
void SMTSolver::dump() const { print(llvm::errs()); }