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/Config/config.h"
10 #include "llvm/Support/SMTAPI.h"
16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/ADT/Twine.h"
25 /// Configuration class for Z3
27 friend class Z3Context
;
32 Z3Config() : Config(Z3_mk_config()) {
33 // Enable model finding
34 Z3_set_param_value(Config
, "model", "true");
35 // Disable proof generation
36 Z3_set_param_value(Config
, "proof", "false");
37 // Set timeout to 15000ms = 15s
38 Z3_set_param_value(Config
, "timeout", "15000");
41 ~Z3Config() { Z3_del_config(Config
); }
42 }; // end class Z3Config
44 // Function used to report errors
45 void Z3ErrorHandler(Z3_context Context
, Z3_error_code Error
) {
46 llvm::report_fatal_error("Z3 error: " +
47 llvm::Twine(Z3_get_error_msg(Context
, Error
)));
50 /// Wrapper for Z3 context
56 Context
= Z3_mk_context_rc(Z3Config().Config
);
57 // The error function is set here because the context is the first object
58 // created by the backend
59 Z3_set_error_handler(Context
, Z3ErrorHandler
);
62 virtual ~Z3Context() {
63 Z3_del_context(Context
);
66 }; // end class Z3Context
68 /// Wrapper for Z3 Sort
69 class Z3Sort
: public SMTSort
{
70 friend class Z3Solver
;
77 /// Default constructor, mainly used by make_shared
78 Z3Sort(Z3Context
&C
, Z3_sort ZS
) : Context(C
), Sort(ZS
) {
79 Z3_inc_ref(Context
.Context
, reinterpret_cast<Z3_ast
>(Sort
));
82 /// Override implicit copy constructor for correct reference counting.
83 Z3Sort(const Z3Sort
&Other
) : Context(Other
.Context
), Sort(Other
.Sort
) {
84 Z3_inc_ref(Context
.Context
, reinterpret_cast<Z3_ast
>(Sort
));
87 /// Override implicit copy assignment constructor for correct reference
89 Z3Sort
&operator=(const Z3Sort
&Other
) {
90 Z3_inc_ref(Context
.Context
, reinterpret_cast<Z3_ast
>(Other
.Sort
));
91 Z3_dec_ref(Context
.Context
, reinterpret_cast<Z3_ast
>(Sort
));
96 Z3Sort(Z3Sort
&&Other
) = delete;
97 Z3Sort
&operator=(Z3Sort
&&Other
) = delete;
101 Z3_dec_ref(Context
.Context
, reinterpret_cast<Z3_ast
>(Sort
));
104 void Profile(llvm::FoldingSetNodeID
&ID
) const override
{
106 Z3_get_ast_id(Context
.Context
, reinterpret_cast<Z3_ast
>(Sort
)));
109 bool isBitvectorSortImpl() const override
{
110 return (Z3_get_sort_kind(Context
.Context
, Sort
) == Z3_BV_SORT
);
113 bool isFloatSortImpl() const override
{
114 return (Z3_get_sort_kind(Context
.Context
, Sort
) == Z3_FLOATING_POINT_SORT
);
117 bool isBooleanSortImpl() const override
{
118 return (Z3_get_sort_kind(Context
.Context
, Sort
) == Z3_BOOL_SORT
);
121 unsigned getBitvectorSortSizeImpl() const override
{
122 return Z3_get_bv_sort_size(Context
.Context
, Sort
);
125 unsigned getFloatSortSizeImpl() const override
{
126 return Z3_fpa_get_ebits(Context
.Context
, Sort
) +
127 Z3_fpa_get_sbits(Context
.Context
, Sort
);
130 bool equal_to(SMTSort
const &Other
) const override
{
131 return Z3_is_eq_sort(Context
.Context
, Sort
,
132 static_cast<const Z3Sort
&>(Other
).Sort
);
135 void print(raw_ostream
&OS
) const override
{
136 OS
<< Z3_sort_to_string(Context
.Context
, Sort
);
138 }; // end class Z3Sort
140 static const Z3Sort
&toZ3Sort(const SMTSort
&S
) {
141 return static_cast<const Z3Sort
&>(S
);
144 class Z3Expr
: public SMTExpr
{
145 friend class Z3Solver
;
152 Z3Expr(Z3Context
&C
, Z3_ast ZA
) : SMTExpr(), Context(C
), AST(ZA
) {
153 Z3_inc_ref(Context
.Context
, AST
);
156 /// Override implicit copy constructor for correct reference counting.
157 Z3Expr(const Z3Expr
&Copy
) : SMTExpr(), Context(Copy
.Context
), AST(Copy
.AST
) {
158 Z3_inc_ref(Context
.Context
, AST
);
161 /// Override implicit copy assignment constructor for correct reference
163 Z3Expr
&operator=(const Z3Expr
&Other
) {
164 Z3_inc_ref(Context
.Context
, Other
.AST
);
165 Z3_dec_ref(Context
.Context
, AST
);
170 Z3Expr(Z3Expr
&&Other
) = delete;
171 Z3Expr
&operator=(Z3Expr
&&Other
) = delete;
175 Z3_dec_ref(Context
.Context
, AST
);
178 void Profile(llvm::FoldingSetNodeID
&ID
) const override
{
179 ID
.AddInteger(Z3_get_ast_id(Context
.Context
, AST
));
182 /// Comparison of AST equality, not model equivalence.
183 bool equal_to(SMTExpr
const &Other
) const override
{
184 assert(Z3_is_eq_sort(Context
.Context
, Z3_get_sort(Context
.Context
, AST
),
185 Z3_get_sort(Context
.Context
,
186 static_cast<const Z3Expr
&>(Other
).AST
)) &&
187 "AST's must have the same sort");
188 return Z3_is_eq_ast(Context
.Context
, AST
,
189 static_cast<const Z3Expr
&>(Other
).AST
);
192 void print(raw_ostream
&OS
) const override
{
193 OS
<< Z3_ast_to_string(Context
.Context
, AST
);
195 }; // end class Z3Expr
197 static const Z3Expr
&toZ3Expr(const SMTExpr
&E
) {
198 return static_cast<const Z3Expr
&>(E
);
202 friend class Z3Solver
;
209 Z3Model(Z3Context
&C
, Z3_model ZM
) : Context(C
), Model(ZM
) {
210 Z3_model_inc_ref(Context
.Context
, Model
);
213 Z3Model(const Z3Model
&Other
) = delete;
214 Z3Model(Z3Model
&&Other
) = delete;
215 Z3Model
&operator=(Z3Model
&Other
) = delete;
216 Z3Model
&operator=(Z3Model
&&Other
) = delete;
220 Z3_model_dec_ref(Context
.Context
, Model
);
223 void print(raw_ostream
&OS
) const {
224 OS
<< Z3_model_to_string(Context
.Context
, Model
);
227 LLVM_DUMP_METHOD
void dump() const { print(llvm::errs()); }
228 }; // end class Z3Model
230 /// Get the corresponding IEEE floating-point type for a given bitwidth.
231 static const llvm::fltSemantics
&getFloatSemantics(unsigned BitWidth
) {
234 llvm_unreachable("Unsupported floating-point semantics!");
237 return llvm::APFloat::IEEEhalf();
239 return llvm::APFloat::IEEEsingle();
241 return llvm::APFloat::IEEEdouble();
243 return llvm::APFloat::IEEEquad();
247 // Determine whether two float semantics are equivalent
248 static bool areEquivalent(const llvm::fltSemantics
&LHS
,
249 const llvm::fltSemantics
&RHS
) {
250 return (llvm::APFloat::semanticsPrecision(LHS
) ==
251 llvm::APFloat::semanticsPrecision(RHS
)) &&
252 (llvm::APFloat::semanticsMinExponent(LHS
) ==
253 llvm::APFloat::semanticsMinExponent(RHS
)) &&
254 (llvm::APFloat::semanticsMaxExponent(LHS
) ==
255 llvm::APFloat::semanticsMaxExponent(RHS
)) &&
256 (llvm::APFloat::semanticsSizeInBits(LHS
) ==
257 llvm::APFloat::semanticsSizeInBits(RHS
));
260 class Z3Solver
: public SMTSolver
{
261 friend class Z3ConstraintManager
;
268 std::set
<Z3Sort
> CachedSorts
;
271 std::set
<Z3Expr
> CachedExprs
;
274 Z3Solver() : Solver(Z3_mk_simple_solver(Context
.Context
)) {
275 Z3_solver_inc_ref(Context
.Context
, Solver
);
278 Z3Solver(const Z3Solver
&Other
) = delete;
279 Z3Solver(Z3Solver
&&Other
) = delete;
280 Z3Solver
&operator=(Z3Solver
&Other
) = delete;
281 Z3Solver
&operator=(Z3Solver
&&Other
) = delete;
285 Z3_solver_dec_ref(Context
.Context
, Solver
);
288 void addConstraint(const SMTExprRef
&Exp
) const override
{
289 Z3_solver_assert(Context
.Context
, Solver
, toZ3Expr(*Exp
).AST
);
292 // Given an SMTSort, adds/retrives it from the cache and returns
293 // an SMTSortRef to the SMTSort in the cache
294 SMTSortRef
newSortRef(const SMTSort
&Sort
) {
295 auto It
= CachedSorts
.insert(toZ3Sort(Sort
));
299 // Given an SMTExpr, adds/retrives it from the cache and returns
300 // an SMTExprRef to the SMTExpr in the cache
301 SMTExprRef
newExprRef(const SMTExpr
&Exp
) {
302 auto It
= CachedExprs
.insert(toZ3Expr(Exp
));
306 SMTSortRef
getBoolSort() override
{
307 return newSortRef(Z3Sort(Context
, Z3_mk_bool_sort(Context
.Context
)));
310 SMTSortRef
getBitvectorSort(unsigned BitWidth
) override
{
312 Z3Sort(Context
, Z3_mk_bv_sort(Context
.Context
, BitWidth
)));
315 SMTSortRef
getSort(const SMTExprRef
&Exp
) override
{
317 Z3Sort(Context
, Z3_get_sort(Context
.Context
, toZ3Expr(*Exp
).AST
)));
320 SMTSortRef
getFloat16Sort() override
{
321 return newSortRef(Z3Sort(Context
, Z3_mk_fpa_sort_16(Context
.Context
)));
324 SMTSortRef
getFloat32Sort() override
{
325 return newSortRef(Z3Sort(Context
, Z3_mk_fpa_sort_32(Context
.Context
)));
328 SMTSortRef
getFloat64Sort() override
{
329 return newSortRef(Z3Sort(Context
, Z3_mk_fpa_sort_64(Context
.Context
)));
332 SMTSortRef
getFloat128Sort() override
{
333 return newSortRef(Z3Sort(Context
, Z3_mk_fpa_sort_128(Context
.Context
)));
336 SMTExprRef
mkBVNeg(const SMTExprRef
&Exp
) override
{
338 Z3Expr(Context
, Z3_mk_bvneg(Context
.Context
, toZ3Expr(*Exp
).AST
)));
341 SMTExprRef
mkBVNot(const SMTExprRef
&Exp
) override
{
343 Z3Expr(Context
, Z3_mk_bvnot(Context
.Context
, toZ3Expr(*Exp
).AST
)));
346 SMTExprRef
mkNot(const SMTExprRef
&Exp
) override
{
348 Z3Expr(Context
, Z3_mk_not(Context
.Context
, toZ3Expr(*Exp
).AST
)));
351 SMTExprRef
mkBVAdd(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
353 Z3Expr(Context
, Z3_mk_bvadd(Context
.Context
, toZ3Expr(*LHS
).AST
,
354 toZ3Expr(*RHS
).AST
)));
357 SMTExprRef
mkBVSub(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
359 Z3Expr(Context
, Z3_mk_bvsub(Context
.Context
, toZ3Expr(*LHS
).AST
,
360 toZ3Expr(*RHS
).AST
)));
363 SMTExprRef
mkBVMul(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
365 Z3Expr(Context
, Z3_mk_bvmul(Context
.Context
, toZ3Expr(*LHS
).AST
,
366 toZ3Expr(*RHS
).AST
)));
369 SMTExprRef
mkBVSRem(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
371 Z3Expr(Context
, Z3_mk_bvsrem(Context
.Context
, toZ3Expr(*LHS
).AST
,
372 toZ3Expr(*RHS
).AST
)));
375 SMTExprRef
mkBVURem(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
377 Z3Expr(Context
, Z3_mk_bvurem(Context
.Context
, toZ3Expr(*LHS
).AST
,
378 toZ3Expr(*RHS
).AST
)));
381 SMTExprRef
mkBVSDiv(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
383 Z3Expr(Context
, Z3_mk_bvsdiv(Context
.Context
, toZ3Expr(*LHS
).AST
,
384 toZ3Expr(*RHS
).AST
)));
387 SMTExprRef
mkBVUDiv(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
389 Z3Expr(Context
, Z3_mk_bvudiv(Context
.Context
, toZ3Expr(*LHS
).AST
,
390 toZ3Expr(*RHS
).AST
)));
393 SMTExprRef
mkBVShl(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
395 Z3Expr(Context
, Z3_mk_bvshl(Context
.Context
, toZ3Expr(*LHS
).AST
,
396 toZ3Expr(*RHS
).AST
)));
399 SMTExprRef
mkBVAshr(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
401 Z3Expr(Context
, Z3_mk_bvashr(Context
.Context
, toZ3Expr(*LHS
).AST
,
402 toZ3Expr(*RHS
).AST
)));
405 SMTExprRef
mkBVLshr(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
407 Z3Expr(Context
, Z3_mk_bvlshr(Context
.Context
, toZ3Expr(*LHS
).AST
,
408 toZ3Expr(*RHS
).AST
)));
411 SMTExprRef
mkBVXor(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
413 Z3Expr(Context
, Z3_mk_bvxor(Context
.Context
, toZ3Expr(*LHS
).AST
,
414 toZ3Expr(*RHS
).AST
)));
417 SMTExprRef
mkBVOr(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
419 Z3Expr(Context
, Z3_mk_bvor(Context
.Context
, toZ3Expr(*LHS
).AST
,
420 toZ3Expr(*RHS
).AST
)));
423 SMTExprRef
mkBVAnd(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
425 Z3Expr(Context
, Z3_mk_bvand(Context
.Context
, toZ3Expr(*LHS
).AST
,
426 toZ3Expr(*RHS
).AST
)));
429 SMTExprRef
mkBVUlt(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
431 Z3Expr(Context
, Z3_mk_bvult(Context
.Context
, toZ3Expr(*LHS
).AST
,
432 toZ3Expr(*RHS
).AST
)));
435 SMTExprRef
mkBVSlt(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
437 Z3Expr(Context
, Z3_mk_bvslt(Context
.Context
, toZ3Expr(*LHS
).AST
,
438 toZ3Expr(*RHS
).AST
)));
441 SMTExprRef
mkBVUgt(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
443 Z3Expr(Context
, Z3_mk_bvugt(Context
.Context
, toZ3Expr(*LHS
).AST
,
444 toZ3Expr(*RHS
).AST
)));
447 SMTExprRef
mkBVSgt(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
449 Z3Expr(Context
, Z3_mk_bvsgt(Context
.Context
, toZ3Expr(*LHS
).AST
,
450 toZ3Expr(*RHS
).AST
)));
453 SMTExprRef
mkBVUle(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
455 Z3Expr(Context
, Z3_mk_bvule(Context
.Context
, toZ3Expr(*LHS
).AST
,
456 toZ3Expr(*RHS
).AST
)));
459 SMTExprRef
mkBVSle(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
461 Z3Expr(Context
, Z3_mk_bvsle(Context
.Context
, toZ3Expr(*LHS
).AST
,
462 toZ3Expr(*RHS
).AST
)));
465 SMTExprRef
mkBVUge(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
467 Z3Expr(Context
, Z3_mk_bvuge(Context
.Context
, toZ3Expr(*LHS
).AST
,
468 toZ3Expr(*RHS
).AST
)));
471 SMTExprRef
mkBVSge(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
473 Z3Expr(Context
, Z3_mk_bvsge(Context
.Context
, toZ3Expr(*LHS
).AST
,
474 toZ3Expr(*RHS
).AST
)));
477 SMTExprRef
mkAnd(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
478 Z3_ast Args
[2] = {toZ3Expr(*LHS
).AST
, toZ3Expr(*RHS
).AST
};
479 return newExprRef(Z3Expr(Context
, Z3_mk_and(Context
.Context
, 2, Args
)));
482 SMTExprRef
mkOr(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
483 Z3_ast Args
[2] = {toZ3Expr(*LHS
).AST
, toZ3Expr(*RHS
).AST
};
484 return newExprRef(Z3Expr(Context
, Z3_mk_or(Context
.Context
, 2, Args
)));
487 SMTExprRef
mkEqual(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
489 Z3Expr(Context
, Z3_mk_eq(Context
.Context
, toZ3Expr(*LHS
).AST
,
490 toZ3Expr(*RHS
).AST
)));
493 SMTExprRef
mkFPNeg(const SMTExprRef
&Exp
) override
{
495 Z3Expr(Context
, Z3_mk_fpa_neg(Context
.Context
, toZ3Expr(*Exp
).AST
)));
498 SMTExprRef
mkFPIsInfinite(const SMTExprRef
&Exp
) override
{
499 return newExprRef(Z3Expr(
500 Context
, Z3_mk_fpa_is_infinite(Context
.Context
, toZ3Expr(*Exp
).AST
)));
503 SMTExprRef
mkFPIsNaN(const SMTExprRef
&Exp
) override
{
505 Z3Expr(Context
, Z3_mk_fpa_is_nan(Context
.Context
, toZ3Expr(*Exp
).AST
)));
508 SMTExprRef
mkFPIsNormal(const SMTExprRef
&Exp
) override
{
509 return newExprRef(Z3Expr(
510 Context
, Z3_mk_fpa_is_normal(Context
.Context
, toZ3Expr(*Exp
).AST
)));
513 SMTExprRef
mkFPIsZero(const SMTExprRef
&Exp
) override
{
514 return newExprRef(Z3Expr(
515 Context
, Z3_mk_fpa_is_zero(Context
.Context
, toZ3Expr(*Exp
).AST
)));
518 SMTExprRef
mkFPMul(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
519 SMTExprRef RoundingMode
= getFloatRoundingMode();
522 Z3_mk_fpa_mul(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
523 toZ3Expr(*LHS
).AST
, toZ3Expr(*RHS
).AST
)));
526 SMTExprRef
mkFPDiv(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
527 SMTExprRef RoundingMode
= getFloatRoundingMode();
530 Z3_mk_fpa_div(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
531 toZ3Expr(*LHS
).AST
, toZ3Expr(*RHS
).AST
)));
534 SMTExprRef
mkFPRem(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
536 Z3Expr(Context
, Z3_mk_fpa_rem(Context
.Context
, toZ3Expr(*LHS
).AST
,
537 toZ3Expr(*RHS
).AST
)));
540 SMTExprRef
mkFPAdd(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
541 SMTExprRef RoundingMode
= getFloatRoundingMode();
544 Z3_mk_fpa_add(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
545 toZ3Expr(*LHS
).AST
, toZ3Expr(*RHS
).AST
)));
548 SMTExprRef
mkFPSub(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
549 SMTExprRef RoundingMode
= getFloatRoundingMode();
552 Z3_mk_fpa_sub(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
553 toZ3Expr(*LHS
).AST
, toZ3Expr(*RHS
).AST
)));
556 SMTExprRef
mkFPLt(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
558 Z3Expr(Context
, Z3_mk_fpa_lt(Context
.Context
, toZ3Expr(*LHS
).AST
,
559 toZ3Expr(*RHS
).AST
)));
562 SMTExprRef
mkFPGt(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
564 Z3Expr(Context
, Z3_mk_fpa_gt(Context
.Context
, toZ3Expr(*LHS
).AST
,
565 toZ3Expr(*RHS
).AST
)));
568 SMTExprRef
mkFPLe(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
570 Z3Expr(Context
, Z3_mk_fpa_leq(Context
.Context
, toZ3Expr(*LHS
).AST
,
571 toZ3Expr(*RHS
).AST
)));
574 SMTExprRef
mkFPGe(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
576 Z3Expr(Context
, Z3_mk_fpa_geq(Context
.Context
, toZ3Expr(*LHS
).AST
,
577 toZ3Expr(*RHS
).AST
)));
580 SMTExprRef
mkFPEqual(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
582 Z3Expr(Context
, Z3_mk_fpa_eq(Context
.Context
, toZ3Expr(*LHS
).AST
,
583 toZ3Expr(*RHS
).AST
)));
586 SMTExprRef
mkIte(const SMTExprRef
&Cond
, const SMTExprRef
&T
,
587 const SMTExprRef
&F
) override
{
589 Z3Expr(Context
, Z3_mk_ite(Context
.Context
, toZ3Expr(*Cond
).AST
,
590 toZ3Expr(*T
).AST
, toZ3Expr(*F
).AST
)));
593 SMTExprRef
mkBVSignExt(unsigned i
, const SMTExprRef
&Exp
) override
{
594 return newExprRef(Z3Expr(
595 Context
, Z3_mk_sign_ext(Context
.Context
, i
, toZ3Expr(*Exp
).AST
)));
598 SMTExprRef
mkBVZeroExt(unsigned i
, const SMTExprRef
&Exp
) override
{
599 return newExprRef(Z3Expr(
600 Context
, Z3_mk_zero_ext(Context
.Context
, i
, toZ3Expr(*Exp
).AST
)));
603 SMTExprRef
mkBVExtract(unsigned High
, unsigned Low
,
604 const SMTExprRef
&Exp
) override
{
605 return newExprRef(Z3Expr(Context
, Z3_mk_extract(Context
.Context
, High
, Low
,
606 toZ3Expr(*Exp
).AST
)));
609 /// Creates a predicate that checks for overflow in a bitvector addition
611 SMTExprRef
mkBVAddNoOverflow(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
,
612 bool isSigned
) override
{
613 return newExprRef(Z3Expr(
614 Context
, Z3_mk_bvadd_no_overflow(Context
.Context
, toZ3Expr(*LHS
).AST
,
615 toZ3Expr(*RHS
).AST
, isSigned
)));
618 /// Creates a predicate that checks for underflow in a signed bitvector
619 /// addition operation
620 SMTExprRef
mkBVAddNoUnderflow(const SMTExprRef
&LHS
,
621 const SMTExprRef
&RHS
) override
{
622 return newExprRef(Z3Expr(
623 Context
, Z3_mk_bvadd_no_underflow(Context
.Context
, toZ3Expr(*LHS
).AST
,
624 toZ3Expr(*RHS
).AST
)));
627 /// Creates a predicate that checks for overflow in a signed bitvector
628 /// subtraction operation
629 SMTExprRef
mkBVSubNoOverflow(const SMTExprRef
&LHS
,
630 const SMTExprRef
&RHS
) override
{
631 return newExprRef(Z3Expr(
632 Context
, Z3_mk_bvsub_no_overflow(Context
.Context
, toZ3Expr(*LHS
).AST
,
633 toZ3Expr(*RHS
).AST
)));
636 /// Creates a predicate that checks for underflow in a bitvector subtraction
638 SMTExprRef
mkBVSubNoUnderflow(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
,
639 bool isSigned
) override
{
640 return newExprRef(Z3Expr(
641 Context
, Z3_mk_bvsub_no_underflow(Context
.Context
, toZ3Expr(*LHS
).AST
,
642 toZ3Expr(*RHS
).AST
, isSigned
)));
645 /// Creates a predicate that checks for overflow in a signed bitvector
646 /// division/modulus operation
647 SMTExprRef
mkBVSDivNoOverflow(const SMTExprRef
&LHS
,
648 const SMTExprRef
&RHS
) override
{
649 return newExprRef(Z3Expr(
650 Context
, Z3_mk_bvsdiv_no_overflow(Context
.Context
, toZ3Expr(*LHS
).AST
,
651 toZ3Expr(*RHS
).AST
)));
654 /// Creates a predicate that checks for overflow in a bitvector negation
656 SMTExprRef
mkBVNegNoOverflow(const SMTExprRef
&Exp
) override
{
657 return newExprRef(Z3Expr(
658 Context
, Z3_mk_bvneg_no_overflow(Context
.Context
, toZ3Expr(*Exp
).AST
)));
661 /// Creates a predicate that checks for overflow in a bitvector multiplication
663 SMTExprRef
mkBVMulNoOverflow(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
,
664 bool isSigned
) override
{
665 return newExprRef(Z3Expr(
666 Context
, Z3_mk_bvmul_no_overflow(Context
.Context
, toZ3Expr(*LHS
).AST
,
667 toZ3Expr(*RHS
).AST
, isSigned
)));
670 /// Creates a predicate that checks for underflow in a signed bitvector
671 /// multiplication operation
672 SMTExprRef
mkBVMulNoUnderflow(const SMTExprRef
&LHS
,
673 const SMTExprRef
&RHS
) override
{
674 return newExprRef(Z3Expr(
675 Context
, Z3_mk_bvmul_no_underflow(Context
.Context
, toZ3Expr(*LHS
).AST
,
676 toZ3Expr(*RHS
).AST
)));
679 SMTExprRef
mkBVConcat(const SMTExprRef
&LHS
, const SMTExprRef
&RHS
) override
{
681 Z3Expr(Context
, Z3_mk_concat(Context
.Context
, toZ3Expr(*LHS
).AST
,
682 toZ3Expr(*RHS
).AST
)));
685 SMTExprRef
mkFPtoFP(const SMTExprRef
&From
, const SMTSortRef
&To
) override
{
686 SMTExprRef RoundingMode
= getFloatRoundingMode();
687 return newExprRef(Z3Expr(
689 Z3_mk_fpa_to_fp_float(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
690 toZ3Expr(*From
).AST
, toZ3Sort(*To
).Sort
)));
693 SMTExprRef
mkSBVtoFP(const SMTExprRef
&From
, const SMTSortRef
&To
) override
{
694 SMTExprRef RoundingMode
= getFloatRoundingMode();
695 return newExprRef(Z3Expr(
697 Z3_mk_fpa_to_fp_signed(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
698 toZ3Expr(*From
).AST
, toZ3Sort(*To
).Sort
)));
701 SMTExprRef
mkUBVtoFP(const SMTExprRef
&From
, const SMTSortRef
&To
) override
{
702 SMTExprRef RoundingMode
= getFloatRoundingMode();
703 return newExprRef(Z3Expr(
705 Z3_mk_fpa_to_fp_unsigned(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
706 toZ3Expr(*From
).AST
, toZ3Sort(*To
).Sort
)));
709 SMTExprRef
mkFPtoSBV(const SMTExprRef
&From
, unsigned ToWidth
) override
{
710 SMTExprRef RoundingMode
= getFloatRoundingMode();
711 return newExprRef(Z3Expr(
712 Context
, Z3_mk_fpa_to_sbv(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
713 toZ3Expr(*From
).AST
, ToWidth
)));
716 SMTExprRef
mkFPtoUBV(const SMTExprRef
&From
, unsigned ToWidth
) override
{
717 SMTExprRef RoundingMode
= getFloatRoundingMode();
718 return newExprRef(Z3Expr(
719 Context
, Z3_mk_fpa_to_ubv(Context
.Context
, toZ3Expr(*RoundingMode
).AST
,
720 toZ3Expr(*From
).AST
, ToWidth
)));
723 SMTExprRef
mkBoolean(const bool b
) override
{
724 return newExprRef(Z3Expr(Context
, b
? Z3_mk_true(Context
.Context
)
725 : Z3_mk_false(Context
.Context
)));
728 SMTExprRef
mkBitvector(const llvm::APSInt Int
, unsigned BitWidth
) override
{
729 const Z3_sort Z3Sort
= toZ3Sort(*getBitvectorSort(BitWidth
)).Sort
;
731 // Slow path, when 64 bits are not enough.
732 if (LLVM_UNLIKELY(!Int
.isRepresentableByInt64())) {
733 SmallString
<40> Buffer
;
734 Int
.toString(Buffer
, 10);
735 return newExprRef(Z3Expr(
736 Context
, Z3_mk_numeral(Context
.Context
, Buffer
.c_str(), Z3Sort
)));
739 const int64_t BitReprAsSigned
= Int
.getExtValue();
740 const uint64_t BitReprAsUnsigned
=
741 reinterpret_cast<const uint64_t &>(BitReprAsSigned
);
745 ? Z3_mk_int64(Context
.Context
, BitReprAsSigned
, Z3Sort
)
746 : Z3_mk_unsigned_int64(Context
.Context
, BitReprAsUnsigned
, Z3Sort
);
747 return newExprRef(Z3Expr(Context
, Literal
));
750 SMTExprRef
mkFloat(const llvm::APFloat Float
) override
{
752 getFloatSort(llvm::APFloat::semanticsSizeInBits(Float
.getSemantics()));
754 llvm::APSInt Int
= llvm::APSInt(Float
.bitcastToAPInt(), false);
755 SMTExprRef Z3Int
= mkBitvector(Int
, Int
.getBitWidth());
756 return newExprRef(Z3Expr(
757 Context
, Z3_mk_fpa_to_fp_bv(Context
.Context
, toZ3Expr(*Z3Int
).AST
,
758 toZ3Sort(*Sort
).Sort
)));
761 SMTExprRef
mkSymbol(const char *Name
, SMTSortRef Sort
) override
{
763 Z3Expr(Context
, Z3_mk_const(Context
.Context
,
764 Z3_mk_string_symbol(Context
.Context
, Name
),
765 toZ3Sort(*Sort
).Sort
)));
768 llvm::APSInt
getBitvector(const SMTExprRef
&Exp
, unsigned BitWidth
,
769 bool isUnsigned
) override
{
771 llvm::APInt(BitWidth
,
772 Z3_get_numeral_string(Context
.Context
, toZ3Expr(*Exp
).AST
),
777 bool getBoolean(const SMTExprRef
&Exp
) override
{
778 return Z3_get_bool_value(Context
.Context
, toZ3Expr(*Exp
).AST
) == Z3_L_TRUE
;
781 SMTExprRef
getFloatRoundingMode() override
{
782 // TODO: Don't assume nearest ties to even rounding mode
783 return newExprRef(Z3Expr(Context
, Z3_mk_fpa_rne(Context
.Context
)));
786 bool toAPFloat(const SMTSortRef
&Sort
, const SMTExprRef
&AST
,
787 llvm::APFloat
&Float
, bool useSemantics
) {
788 assert(Sort
->isFloatSort() && "Unsupported sort to floating-point!");
790 llvm::APSInt
Int(Sort
->getFloatSortSize(), true);
791 const llvm::fltSemantics
&Semantics
=
792 getFloatSemantics(Sort
->getFloatSortSize());
793 SMTSortRef BVSort
= getBitvectorSort(Sort
->getFloatSortSize());
794 if (!toAPSInt(BVSort
, AST
, Int
, true)) {
798 if (useSemantics
&& !areEquivalent(Float
.getSemantics(), Semantics
)) {
799 assert(false && "Floating-point types don't match!");
803 Float
= llvm::APFloat(Semantics
, Int
);
807 bool toAPSInt(const SMTSortRef
&Sort
, const SMTExprRef
&AST
,
808 llvm::APSInt
&Int
, bool useSemantics
) {
809 if (Sort
->isBitvectorSort()) {
810 if (useSemantics
&& Int
.getBitWidth() != Sort
->getBitvectorSortSize()) {
811 assert(false && "Bitvector types don't match!");
815 // FIXME: This function is also used to retrieve floating-point values,
816 // which can be 16, 32, 64 or 128 bits long. Bitvectors can be anything
817 // between 1 and 64 bits long, which is the reason we have this weird
818 // guard. In the future, we need proper calls in the backend to retrieve
819 // floating-points and its special values (NaN, +/-infinity, +/-zero),
820 // then we can drop this weird condition.
821 if (Sort
->getBitvectorSortSize() <= 64 ||
822 Sort
->getBitvectorSortSize() == 128) {
823 Int
= getBitvector(AST
, Int
.getBitWidth(), Int
.isUnsigned());
827 assert(false && "Bitwidth not supported!");
831 if (Sort
->isBooleanSort()) {
832 if (useSemantics
&& Int
.getBitWidth() < 1) {
833 assert(false && "Boolean type doesn't match!");
837 Int
= llvm::APSInt(llvm::APInt(Int
.getBitWidth(), getBoolean(AST
)),
842 llvm_unreachable("Unsupported sort to integer!");
845 bool getInterpretation(const SMTExprRef
&Exp
, llvm::APSInt
&Int
) override
{
846 Z3Model
Model(Context
, Z3_solver_get_model(Context
.Context
, Solver
));
847 Z3_func_decl Func
= Z3_get_app_decl(
848 Context
.Context
, Z3_to_app(Context
.Context
, toZ3Expr(*Exp
).AST
));
849 if (Z3_model_has_interp(Context
.Context
, Model
.Model
, Func
) != Z3_L_TRUE
)
852 SMTExprRef Assign
= newExprRef(
854 Z3_model_get_const_interp(Context
.Context
, Model
.Model
, Func
)));
855 SMTSortRef Sort
= getSort(Assign
);
856 return toAPSInt(Sort
, Assign
, Int
, true);
859 bool getInterpretation(const SMTExprRef
&Exp
, llvm::APFloat
&Float
) override
{
860 Z3Model
Model(Context
, Z3_solver_get_model(Context
.Context
, Solver
));
861 Z3_func_decl Func
= Z3_get_app_decl(
862 Context
.Context
, Z3_to_app(Context
.Context
, toZ3Expr(*Exp
).AST
));
863 if (Z3_model_has_interp(Context
.Context
, Model
.Model
, Func
) != Z3_L_TRUE
)
866 SMTExprRef Assign
= newExprRef(
868 Z3_model_get_const_interp(Context
.Context
, Model
.Model
, Func
)));
869 SMTSortRef Sort
= getSort(Assign
);
870 return toAPFloat(Sort
, Assign
, Float
, true);
873 std::optional
<bool> check() const override
{
874 Z3_lbool res
= Z3_solver_check(Context
.Context
, Solver
);
875 if (res
== Z3_L_TRUE
)
878 if (res
== Z3_L_FALSE
)
884 void push() override
{ return Z3_solver_push(Context
.Context
, Solver
); }
886 void pop(unsigned NumStates
= 1) override
{
887 assert(Z3_solver_get_num_scopes(Context
.Context
, Solver
) >= NumStates
);
888 return Z3_solver_pop(Context
.Context
, Solver
, NumStates
);
891 bool isFPSupported() override
{ return true; }
893 /// Reset the solver and remove all constraints.
894 void reset() override
{ Z3_solver_reset(Context
.Context
, Solver
); }
896 void print(raw_ostream
&OS
) const override
{
897 OS
<< Z3_solver_to_string(Context
.Context
, Solver
);
899 }; // end class Z3Solver
901 } // end anonymous namespace
905 llvm::SMTSolverRef
llvm::CreateZ3Solver() {
907 return std::make_unique
<Z3Solver
>();
909 llvm::report_fatal_error("LLVM was not compiled with Z3 support, rebuild "
910 "with -DLLVM_ENABLE_Z3_SOLVER=ON",
916 LLVM_DUMP_METHOD
void SMTSort::dump() const { print(llvm::errs()); }
917 LLVM_DUMP_METHOD
void SMTExpr::dump() const { print(llvm::errs()); }
918 LLVM_DUMP_METHOD
void SMTSolver::dump() const { print(llvm::errs()); }