20#include "llvm/IR/Constants.h"
21#include "llvm/IR/DataLayout.h"
22#include "llvm/IR/Function.h"
23#include "llvm/IR/GetElementPtrTypeIterator.h"
24#include "llvm/IR/Instructions.h"
25#include "llvm/IR/Module.h"
26#include "llvm/IR/Operator.h"
27#include "llvm/Support/raw_ostream.h"
43 if (
const llvm::ConstantExpr *ce = dyn_cast<llvm::ConstantExpr>(c)) {
46 if (
const ConstantInt *ci = dyn_cast<ConstantInt>(c)) {
48 }
else if (
const ConstantFP *cf = dyn_cast<ConstantFP>(c)) {
50 }
else if (
const GlobalValue *gv = dyn_cast<GlobalValue>(c)) {
54 }
else if (isa<ConstantPointerNull>(c)) {
56 }
else if (isa<UndefValue>(c) || isa<ConstantAggregateZero>(c)) {
58 if (isa<llvm::LandingPadInst>(ki->
inst)) {
59 klee_warning_once(0,
"Using zero size array fix for landingpad instruction filter");
64 }
else if (
const ConstantDataSequential *cds =
65 dyn_cast<ConstantDataSequential>(c)) {
68 std::vector<ref<Expr> > kids;
69 for (
unsigned i = cds->getNumElements(); i != 0; --i) {
74 "FIXME:Broken for big endian");
76 return cast<ConstantExpr>(res);
77 }
else if (
const ConstantStruct *cs = dyn_cast<ConstantStruct>(c)) {
78 const StructLayout *sl =
kmodule->targetData->getStructLayout(cs->getType());
79 llvm::SmallVector<ref<Expr>, 4> kids;
80 for (
unsigned i = cs->getNumOperands(); i != 0; --i) {
84 uint64_t thisOffset = sl->getElementOffsetInBits(op),
85 nextOffset = (op == cs->getNumOperands() - 1)
87 : sl->getElementOffsetInBits(op+1);
88 if (nextOffset-thisOffset > kid->
getWidth()) {
89 uint64_t paddingWidth = nextOffset-thisOffset-kid->
getWidth();
96 "FIXME:Broken for big endian");
98 return cast<ConstantExpr>(res);
99 }
else if (
const ConstantArray *ca = dyn_cast<ConstantArray>(c)){
100 llvm::SmallVector<ref<Expr>, 4> kids;
101 for (
unsigned i = ca->getNumOperands(); i != 0; --i) {
107 "FIXME:Broken for big endian");
109 return cast<ConstantExpr>(res);
110 }
else if (
const ConstantVector *cv = dyn_cast<ConstantVector>(c)) {
111 llvm::SmallVector<ref<Expr>, 8> kids;
112 const size_t numOperands = cv->getNumOperands();
113 kids.reserve(numOperands);
114 for (
unsigned i = numOperands; i != 0; --i) {
115 kids.push_back(
evalConstant(cv->getOperand(i - 1), ki));
118 "FIXME:Broken for big endian");
120 assert(isa<ConstantExpr>(res) &&
121 "result of constant vector built is not a constant");
122 return cast<ConstantExpr>(res);
123 }
else if (
const BlockAddress * ba = dyn_cast<BlockAddress>(c)) {
125 const auto arg_bb = (BasicBlock *) ba->getOperand(1);
127 return cast<ConstantExpr>(res);
129 std::string msg(
"Cannot handle constant ");
130 llvm::raw_string_ostream os(msg);
131 os <<
"'" << *c <<
"' at location "
140 llvm::Type *type = ce->getType();
143 int numOperands = ce->getNumOperands();
145 if (numOperands > 0) op1 =
evalConstant(ce->getOperand(0), ki);
146 if (numOperands > 1) op2 =
evalConstant(ce->getOperand(1), ki);
147 if (numOperands > 2) op3 =
evalConstant(ce->getOperand(2), ki);
150 switch (ce->getOpcode()) {
151 case Instruction::SDiv:
152 case Instruction::UDiv:
153 case Instruction::SRem:
154 case Instruction::URem:
155 if (op2->getLimitedValue() == 0) {
156 std::string msg(
"Division/modulo by zero during constant folding at location ");
157 llvm::raw_string_ostream os(msg);
162 case Instruction::Shl:
163 case Instruction::LShr:
164 case Instruction::AShr:
165 if (op2->getLimitedValue() >= op1->getWidth()) {
166 std::string msg(
"Overshift during constant folding at location ");
167 llvm::raw_string_ostream os(msg);
173 std::string msg(
"Unknown ConstantExpr type");
174 llvm::raw_string_ostream os(msg);
176 switch (ce->getOpcode()) {
178 os <<
"'" << *ce <<
"' at location "
182 case Instruction::Trunc:
186 case Instruction::Add:
return op1->Add(op2);
187 case Instruction::Sub:
return op1->Sub(op2);
188 case Instruction::Mul:
return op1->Mul(op2);
189 case Instruction::SDiv:
return op1->SDiv(op2);
190 case Instruction::UDiv:
return op1->UDiv(op2);
191 case Instruction::SRem:
return op1->SRem(op2);
192 case Instruction::URem:
return op1->URem(op2);
193 case Instruction::And:
return op1->And(op2);
194 case Instruction::Or:
return op1->Or(op2);
195 case Instruction::Xor:
return op1->Xor(op2);
196 case Instruction::Shl:
return op1->Shl(op2);
197 case Instruction::LShr:
return op1->LShr(op2);
198 case Instruction::AShr:
return op1->AShr(op2);
199 case Instruction::BitCast:
return op1;
201 case Instruction::IntToPtr:
204 case Instruction::PtrToInt:
207 case Instruction::GetElementPtr: {
213 if (indexOp->isZero())
217 if (
auto STy = ii.getStructTypeOrNull()) {
218 unsigned ElementIdx = indexOp->getZExtValue();
219 const StructLayout *SL =
kmodule->targetData->getStructLayout(STy);
222 SL->getElementOffset(ElementIdx))));
231 kmodule->targetData->getTypeAllocSize(
232 ii.getIndexedType())))));
237 case Instruction::ICmp: {
238 switch(ce->getPredicate()) {
239 default: assert(0 &&
"unhandled ICmp predicate");
240 case ICmpInst::ICMP_EQ:
return op1->Eq(op2);
241 case ICmpInst::ICMP_NE:
return op1->Ne(op2);
242 case ICmpInst::ICMP_UGT:
return op1->Ugt(op2);
243 case ICmpInst::ICMP_UGE:
return op1->Uge(op2);
244 case ICmpInst::ICMP_ULT:
return op1->Ult(op2);
245 case ICmpInst::ICMP_ULE:
return op1->Ule(op2);
246 case ICmpInst::ICMP_SGT:
return op1->Sgt(op2);
247 case ICmpInst::ICMP_SGE:
return op1->Sge(op2);
248 case ICmpInst::ICMP_SLT:
return op1->Slt(op2);
249 case ICmpInst::ICMP_SLE:
return op1->Sle(op2);
253 case Instruction::Select:
254 return op1->isTrue() ? op2 : op3;
256 case Instruction::FAdd:
257 case Instruction::FSub:
258 case Instruction::FMul:
259 case Instruction::FDiv:
260 case Instruction::FRem:
261 case Instruction::FPTrunc:
262 case Instruction::FPExt:
263 case Instruction::UIToFP:
264 case Instruction::SIToFP:
265 case Instruction::FPToUI:
266 case Instruction::FPToSI:
267 case Instruction::FCmp:
268 assert(0 &&
"floating point ConstantExprs unsupported");
270 llvm_unreachable(
"Unsupported expression in evalConstantExpr");
static ref< Expr > createN(unsigned nKids, const ref< Expr > kids[])
Shortcuts to create larger concats. The chain returned is unbalanced to the right.
static ref< ConstantExpr > create(uint64_t v, Width w)
static ref< ConstantExpr > alloc(const llvm::APInt &v)
Expr::Width getPointerWidth() const
Returns width of the pointer in bits.
static const Context & get()
get - Return the global singleton instance of the Context.
std::map< const llvm::GlobalValue *, ref< ConstantExpr > > globalAddresses
Expr::Width getWidthForLLVMType(llvm::Type *type) const
ref< klee::ConstantExpr > evalConstantExpr(const llvm::ConstantExpr *c, const KInstruction *ki=NULL)
std::unique_ptr< KModule > kmodule
ref< klee::ConstantExpr > evalConstant(const llvm::Constant *c, const KInstruction *ki=NULL)
virtual Width getWidth() const =0
static ref< ConstantExpr > createPointer(uint64_t v)
gep_type_iterator gep_type_begin(const llvm::User *GEP)
void klee_error(const char *msg,...) __attribute__((format(printf
void void void void klee_warning_once(const void *id, const char *msg,...) __attribute__((format(printf
gep_type_iterator gep_type_end(const llvm::User *GEP)
std::string getSourceLocation() const