New methods to check for under-/overflow in the SMT API
authorMikhail R. Gadelha <mikhail.ramalho@gmail.com>
Wed, 27 Mar 2019 16:54:12 +0000 (16:54 +0000)
committerMikhail R. Gadelha <mikhail.ramalho@gmail.com>
Wed, 27 Mar 2019 16:54:12 +0000 (16:54 +0000)
Summary: Added methods to check for under-/overflow in additions, subtractions, signed divisions/modulus, negations, and multiplications.

Reviewers: ddcc, gou4shi1

Reviewed By: ddcc, gou4shi1

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D59796

llvm-svn: 357088

llvm/include/llvm/Support/SMTAPI.h
llvm/lib/Support/Z3Solver.cpp

index 8891faa..24dcd12 100644 (file)
@@ -279,6 +279,48 @@ public:
   virtual SMTExprRef mkBVConcat(const SMTExprRef &LHS,
                                 const SMTExprRef &RHS) = 0;
 
+  /// Creates a predicate that checks for overflow in a bitvector addition
+  /// operation
+  virtual SMTExprRef mkBVAddNoOverflow(const SMTExprRef &LHS,
+                                       const SMTExprRef &RHS,
+                                       bool isSigned) = 0;
+
+  /// Creates a predicate that checks for underflow in a signed bitvector
+  /// addition operation
+  virtual SMTExprRef mkBVAddNoUnderflow(const SMTExprRef &LHS,
+                                        const SMTExprRef &RHS) = 0;
+
+  /// Creates a predicate that checks for overflow in a signed bitvector
+  /// subtraction operation
+  virtual SMTExprRef mkBVSubNoOverflow(const SMTExprRef &LHS,
+                                       const SMTExprRef &RHS) = 0;
+
+  /// Creates a predicate that checks for underflow in a bitvector subtraction
+  /// operation
+  virtual SMTExprRef mkBVSubNoUnderflow(const SMTExprRef &LHS,
+                                        const SMTExprRef &RHS,
+                                        bool isSigned) = 0;
+
+  /// Creates a predicate that checks for overflow in a signed bitvector
+  /// division/modulus operation
+  virtual SMTExprRef mkBVSDivNoOverflow(const SMTExprRef &LHS,
+                                        const SMTExprRef &RHS) = 0;
+
+  /// Creates a predicate that checks for overflow in a bitvector negation
+  /// operation
+  virtual SMTExprRef mkBVNegNoOverflow(const SMTExprRef &Exp) = 0;
+
+  /// Creates a predicate that checks for overflow in a bitvector multiplication
+  /// operation
+  virtual SMTExprRef mkBVMulNoOverflow(const SMTExprRef &LHS,
+                                       const SMTExprRef &RHS,
+                                       bool isSigned) = 0;
+
+  /// Creates a predicate that checks for underflow in a signed bitvector
+  /// multiplication operation
+  virtual SMTExprRef mkBVMulNoUnderflow(const SMTExprRef &LHS,
+                                        const SMTExprRef &RHS) = 0;
+
   /// Creates a floating-point negation operation
   virtual SMTExprRef mkFPNeg(const SMTExprRef &Exp) = 0;
 
index 5e40831..f1a6fdf 100644 (file)
@@ -603,6 +603,76 @@ public:
                                                     toZ3Expr(*Exp).AST)));
   }
 
+  /// Creates a predicate that checks for overflow in a bitvector addition
+  /// operation
+  SMTExprRef mkBVAddNoOverflow(const SMTExprRef &LHS, const SMTExprRef &RHS,
+                               bool isSigned) override {
+    return newExprRef(Z3Expr(
+        Context, Z3_mk_bvadd_no_overflow(Context.Context, toZ3Expr(*LHS).AST,
+                                         toZ3Expr(*RHS).AST, isSigned)));
+  }
+
+  /// Creates a predicate that checks for underflow in a signed bitvector
+  /// addition operation
+  SMTExprRef mkBVAddNoUnderflow(const SMTExprRef &LHS,
+                                const SMTExprRef &RHS) override {
+    return newExprRef(Z3Expr(
+        Context, Z3_mk_bvadd_no_underflow(Context.Context, toZ3Expr(*LHS).AST,
+                                          toZ3Expr(*RHS).AST)));
+  }
+
+  /// Creates a predicate that checks for overflow in a signed bitvector
+  /// subtraction operation
+  SMTExprRef mkBVSubNoOverflow(const SMTExprRef &LHS,
+                               const SMTExprRef &RHS) override {
+    return newExprRef(Z3Expr(
+        Context, Z3_mk_bvsub_no_overflow(Context.Context, toZ3Expr(*LHS).AST,
+                                         toZ3Expr(*RHS).AST)));
+  }
+
+  /// Creates a predicate that checks for underflow in a bitvector subtraction
+  /// operation
+  SMTExprRef mkBVSubNoUnderflow(const SMTExprRef &LHS, const SMTExprRef &RHS,
+                                bool isSigned) override {
+    return newExprRef(Z3Expr(
+        Context, Z3_mk_bvsub_no_underflow(Context.Context, toZ3Expr(*LHS).AST,
+                                          toZ3Expr(*RHS).AST, isSigned)));
+  }
+
+  /// Creates a predicate that checks for overflow in a signed bitvector
+  /// division/modulus operation
+  SMTExprRef mkBVSDivNoOverflow(const SMTExprRef &LHS,
+                                const SMTExprRef &RHS) override {
+    return newExprRef(Z3Expr(
+        Context, Z3_mk_bvsdiv_no_overflow(Context.Context, toZ3Expr(*LHS).AST,
+                                          toZ3Expr(*RHS).AST)));
+  }
+
+  /// Creates a predicate that checks for overflow in a bitvector negation
+  /// operation
+  SMTExprRef mkBVNegNoOverflow(const SMTExprRef &Exp) override {
+    return newExprRef(Z3Expr(
+        Context, Z3_mk_bvneg_no_overflow(Context.Context, toZ3Expr(*Exp).AST)));
+  }
+
+  /// Creates a predicate that checks for overflow in a bitvector multiplication
+  /// operation
+  SMTExprRef mkBVMulNoOverflow(const SMTExprRef &LHS, const SMTExprRef &RHS,
+                               bool isSigned) override {
+    return newExprRef(Z3Expr(
+        Context, Z3_mk_bvmul_no_overflow(Context.Context, toZ3Expr(*LHS).AST,
+                                         toZ3Expr(*RHS).AST, isSigned)));
+  }
+
+  /// Creates a predicate that checks for underflow in a signed bitvector
+  /// multiplication operation
+  SMTExprRef mkBVMulNoUnderflow(const SMTExprRef &LHS,
+                                const SMTExprRef &RHS) override {
+    return newExprRef(Z3Expr(
+        Context, Z3_mk_bvmul_no_underflow(Context.Context, toZ3Expr(*LHS).AST,
+                                          toZ3Expr(*RHS).AST)));
+  }
+
   SMTExprRef mkBVConcat(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
     return newExprRef(
         Z3Expr(Context, Z3_mk_concat(Context.Context, toZ3Expr(*LHS).AST,