diff options
author | Martin Nowack <m.nowack@imperial.ac.uk> | 2018-07-29 15:56:54 +0100 |
---|---|---|
committer | Cristian Cadar <c.cadar@imperial.ac.uk> | 2018-10-24 14:15:25 +0300 |
commit | cdff297692a1edbf9159d1c998648c6e609025ef (patch) | |
tree | ca4e5abc6408f65f51fb181cdaac33b61d3b27f3 /lib/Module | |
parent | 56e4c597a8d7e641604aea1ecfff4600fbf8dea9 (diff) | |
download | klee-cdff297692a1edbf9159d1c998648c6e609025ef.tar.gz |
Use llvm::Builder for DivCheck instrumentation
Use llvm::Builder instead of raw `*Inst::create()` functions. Builder automatically manages metadata (e.g. debug, TBAA, ..) such that we don't have to take care of this automatically. Updated code to C++11 and clang-formated it.
Diffstat (limited to 'lib/Module')
-rw-r--r-- | lib/Module/Checks.cpp | 80 |
1 files changed, 38 insertions, 42 deletions
diff --git a/lib/Module/Checks.cpp b/lib/Module/Checks.cpp index aac63e1d..a9ef0dd4 100644 --- a/lib/Module/Checks.cpp +++ b/lib/Module/Checks.cpp @@ -12,16 +12,17 @@ #include "klee/Config/Version.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" -#include "llvm/IR/Module.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #include "llvm/IR/Type.h" -#include "llvm/IR/DataLayout.h" #include "llvm/Pass.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" @@ -31,50 +32,45 @@ using namespace klee; char DivCheckPass::ID; -bool DivCheckPass::runOnModule(Module &M) { - Function *divZeroCheckFunction = 0; - LLVMContext &ctx = M.getContext(); - - bool moduleChanged = false; - - for (Module::iterator f = M.begin(), fe = M.end(); f != fe; ++f) { - for (Function::iterator b = f->begin(), be = f->end(); b != be; ++b) { - for (BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; ++i) { - if (BinaryOperator* binOp = dyn_cast<BinaryOperator>(i)) { - // find all [s|u][div|mod] instructions - Instruction::BinaryOps opcode = binOp->getOpcode(); - if (opcode == Instruction::SDiv || opcode == Instruction::UDiv || - opcode == Instruction::SRem || opcode == Instruction::URem) { - - CastInst *denominator = - CastInst::CreateIntegerCast(i->getOperand(1), - Type::getInt64Ty(ctx), - false, /* sign doesn't matter */ - "int_cast_to_i64", - &*i); - - // Lazily bind the function to avoid always importing it. - if (!divZeroCheckFunction) { - Constant *fc = M.getOrInsertFunction("klee_div_zero_check", - Type::getVoidTy(ctx), - Type::getInt64Ty(ctx), - NULL); - divZeroCheckFunction = cast<Function>(fc); - } - - CallInst * ci = CallInst::Create(divZeroCheckFunction, denominator, "", &*i); - - // Set debug location of checking call to that of the div/rem - // operation so error locations are reported in the correct - // location. - ci->setDebugLoc(binOp->getDebugLoc()); - moduleChanged = true; - } +bool DivCheckPass::runOnModule(Module &M) { + std::vector<llvm::BinaryOperator *> divInstruction; + + for (auto &F : M) { + for (auto &BB : F) { + for (auto &I : BB) { + auto binOp = dyn_cast<BinaryOperator>(&I); + if (!binOp) + continue; + + // find all [s|u][div|rem] instructions + auto opcode = binOp->getOpcode(); + if (opcode != Instruction::SDiv && opcode != Instruction::UDiv && + opcode != Instruction::SRem && opcode != Instruction::URem) + continue; } } } } - return moduleChanged; + + // If nothing to do, return + if (divInstruction.empty()) + return false; + + LLVMContext &ctx = M.getContext(); + auto divZeroCheckFunction = cast<Function>( + M.getOrInsertFunction("klee_div_zero_check", Type::getVoidTy(ctx), + Type::getInt64Ty(ctx), NULL)); + + for (auto &divInst : divInstruction) { + llvm::IRBuilder<> Builder(divInst /* Inserts before divInst*/); + auto denominator = + Builder.CreateIntCast(divInst->getOperand(1), Type::getInt64Ty(ctx), + false, /* sign doesn't matter */ + "int_cast_to_i64"); + Builder.CreateCall(divZeroCheckFunction, denominator); + } + + return true; } char OvershiftCheckPass::ID; |