result = bm.CreateZeroConst(width);
else if (children[1].isConstant())
result = BEEV::Simplifier::convertKnownShiftAmount(kind, children, bm, &hashing);
+ else if(children[0].isConstant() && children[0] == bm.CreateOneConst(width) && width > 1)
+ result = NodeFactory::CreateTerm(BEEV::ITE,width, NodeFactory::CreateNode(BEEV::EQ, children[1], bm.CreateZeroConst(width)), children[0], bm.CreateZeroConst(width));
+
}
break;
result = BEEV::Simplifier::convertArithmeticKnownShiftAmount(kind, children, bm, &hashing);
else if (children[1].GetKind() == BEEV::BVUMINUS && children[0] == children[1][0])
result = NodeFactory::CreateTerm(BEEV::BVSRSHIFT,width, children[0], children[1][0]);
+ else if(children[0].isConstant() && !CONSTANTBV::BitVector_bit_test(children[0].GetBVConst(), width-1))
+ result = NodeFactory::CreateTerm(BEEV::BVRIGHTSHIFT,width, children[0], children[1]);
}
break;
result = BEEV::ArrayTransformer::TranslateSignedDivModRem(hashing.CreateTerm(kind, width, children),this,&bm);
break;
-
case BEEV::BVDIV:
if (children[1].isConstant() && children[1] == bm.CreateOneConst(width))
result = children[0];
result = bm.CreateOneConst(width);
else if (bm.UserFlags.division_by_zero_returns_one_flag && children[0] == children[1])
result = bm.CreateOneConst(width);
+ else if (bm.UserFlags.division_by_zero_returns_one_flag && children[0].isConstant() && CONSTANTBV::BitVector_is_empty(children[0].GetBVConst()))
+ result = NodeFactory::CreateTerm(BEEV::ITE,width, NodeFactory::CreateNode(BEEV::EQ, children[1], bm.CreateZeroConst(width)), children[0], bm.CreateZeroConst(width));
break;
result = children[0];
else if (children[0] == children[1] && bm.UserFlags.division_by_zero_returns_one_flag)
result = bm.CreateOneConst(width);
+ else if (children[1].GetKind() == BEEV::BVUMINUS && children[0] == children[1][0] && bm.UserFlags.division_by_zero_returns_one_flag)
+ result = NodeFactory::CreateTerm(BEEV::SBVDIV,width, children[1], children[0]);
else
- result = BEEV::ArrayTransformer::TranslateSignedDivModRem(hashing.CreateTerm(kind, width, children),this,&bm);
+ result = BEEV::ArrayTransformer::TranslateSignedDivModRem(hashing.CreateTerm(kind, width, children),this,&bm);
break;
}
- // If the rhs of a left or right shift is known. Then replace it with a concat / extract.
+ // If the rhs of a left or right shift is known.
ASTNode Simplifier::convertKnownShiftAmount(const Kind k, const ASTVec& children, STPMgr& bm, NodeFactory *nf)
{
const ASTNode a =children[0];
{
if (k == BVLEFTSHIFT)
{
- ASTNode zero = bm.CreateZeroConst(shift);
- ASTNode hi = bm.CreateBVConst(32, width - shift -1);
- ASTNode low = bm.CreateZeroConst(32);
- ASTNode extract =
- nf->CreateTerm(BVEXTRACT, width - shift,
- a, hi, low);
- BVTypeCheck(extract);
+ CBV cbv = CONSTANTBV::BitVector_Create(width,true);
+ CONSTANTBV::BitVector_Bit_On(cbv,shift);
+ ASTNode c = bm.CreateBVConst(cbv,width);
+
output =
- nf->CreateTerm(BVCONCAT, width,
- extract, zero);
+ nf->CreateTerm(BVMULT, width,
+ a, c);
BVTypeCheck(output);
+ //cout << output;
+ //cout << a << b << endl;
}
else if (k == BVRIGHTSHIFT)
{
return output;
}
-
-
//This function simplifies terms based on their kind
ASTNode
Simplifier::SimplifyTerm(const ASTNode& actualInputterm,
output = nf->CreateTerm(BVSUB, inputValueWidth, a0[1], a0[0]);
break;
}
- case ITE:
+ case BVAND:
+ if (a0.Degree() == 2 && (a0[1].GetKind() == BVUMINUS) && a0[1][0] == a0[0])
+ {
+ output = nf->CreateTerm(BVOR, inputValueWidth, a0[0], a0[1]);
+ }
+ break;
+ case BVOR:
+ if (a0.Degree() == 2 && (a0[1].GetKind() == BVUMINUS) && a0[1][0] == a0[0])
+ {
+ output = nf->CreateTerm(BVAND, inputValueWidth, a0[0], a0[1]);
+ }
+ break;
+ case BVLEFTSHIFT:
+ if (a0[0].GetKind() == BVCONST)
+ output = nf->CreateTerm(BVLEFTSHIFT, inputValueWidth, nf->CreateTerm(BVUMINUS, inputValueWidth, a0[0]),
+ a0[1]);
+ break;
+ case ITE:
{
//BVUMINUS(ITE(c,t1,t2)) <==> ITE(c,BVUMINUS(t1),BVUMINUS(t2))
ASTNode c = a0[0];