From e3a6923ecc6f6ca968399765492fe844d2da2f2b Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Tue, 16 Jun 2009 04:11:20 +0000 Subject: Add basic constant folding / simplification for Eq. git-svn-id: https://llvm.org/svn/llvm-project/klee/trunk@73467 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Expr/ExprBuilder.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'lib/Expr') diff --git a/lib/Expr/ExprBuilder.cpp b/lib/Expr/ExprBuilder.cpp index aaddb3e3..68a7fefd 100644 --- a/lib/Expr/ExprBuilder.cpp +++ b/lib/Expr/ExprBuilder.cpp @@ -931,6 +931,43 @@ namespace { const ref &RHS) { return Base->Xor(LHS, RHS); } + + ref Eq(const ref &LHS, + const ref &RHS) { + Expr::Width Width = LHS->getWidth(); + + if (Width == Expr::Bool) { + // true == X ==> X + if (LHS->isTrue()) + return RHS; + + // false == ... (not) + + // Eliminate double negation. + if (const EqExpr *EE = dyn_cast(RHS)) { + if (EE->left->getWidth() == Expr::Bool) { + // false == (false == X) ==> X + if (EE->left->isFalse()) + return EE->right; + // false == (X == false) ==> X + if (EE->right->isFalse()) + return EE->left; + } + } + } + + return Base->Eq(LHS, RHS); + } + + ref Eq(const ref &LHS, + const ref &RHS) { + return Eq(RHS, LHS); + } + + ref Eq(const ref &LHS, + const ref &RHS) { + return Base->Eq(LHS, RHS); + } }; typedef ConstantSpecializedExprBuilder @@ -941,6 +978,40 @@ namespace { SimplifyingBuilder(ExprBuilder *Builder, ExprBuilder *Base) : ChainedBuilder(Builder, Base) {} + ref Eq(const ref &LHS, + const ref &RHS) { + Expr::Width Width = LHS->getWidth(); + + if (Width == Expr::Bool) { + // true == X ==> X + if (LHS->isTrue()) + return RHS; + + // false == X (not) + + // Transform !(a or b) ==> !a and !b. + if (const OrExpr *OE = dyn_cast(RHS)) + return Builder->And(Builder->Not(OE->left), + Builder->Not(OE->right)); + } + + return Base->Eq(LHS, RHS); + } + + ref Eq(const ref &LHS, + const ref &RHS) { + return Eq(RHS, LHS); + } + + ref Eq(const ref &LHS, + const ref &RHS) { + // X == X ==> true + if (LHS == RHS) + return Builder->True(); + + return Base->Eq(LHS, RHS); + } + ref Ne(const ref &LHS, const ref &RHS) { // X != Y ==> !(X == Y) return Builder->Not(Builder->Eq(LHS, RHS)); -- cgit 1.4.1