16#include "llvm/IR/Constants.h"
17#include "llvm/IR/DataLayout.h"
18#include "llvm/IR/DerivedTypes.h"
19#include "llvm/IR/Function.h"
20#include "llvm/IR/IRBuilder.h"
21#include "llvm/IR/InstrTypes.h"
22#include "llvm/IR/Instruction.h"
23#include "llvm/IR/Instructions.h"
24#include "llvm/IR/IntrinsicInst.h"
25#include "llvm/IR/LLVMContext.h"
26#include "llvm/IR/Module.h"
27#include "llvm/IR/Type.h"
29#include "llvm/Transforms/Scalar.h"
30#include "llvm/Transforms/Utils/BasicBlockUtils.h"
37bool DivCheckPass::runOnModule(Module &M) {
38 std::vector<llvm::BinaryOperator *> divInstruction;
43 auto binOp = dyn_cast<BinaryOperator>(&I);
48 auto opcode = binOp->getOpcode();
49 if (opcode != Instruction::SDiv && opcode != Instruction::UDiv &&
50 opcode != Instruction::SRem && opcode != Instruction::URem)
54 const auto &operand = binOp->getOperand(1);
55 if (
const auto &coOp = dyn_cast<llvm::Constant>(operand)) {
56 if (!coOp->isZeroValue())
63 divInstruction.push_back(binOp);
69 if (divInstruction.empty())
72 LLVMContext &ctx = M.getContext();
74 auto divZeroCheckFunction =
75 M.getOrInsertFunction(
"klee_div_zero_check", Type::getVoidTy(ctx),
76 Type::getInt64Ty(ctx));
78 for (
auto &divInst : divInstruction) {
79 llvm::IRBuilder<> Builder(divInst );
81 Builder.CreateIntCast(divInst->getOperand(1), Type::getInt64Ty(ctx),
84 Builder.CreateCall(divZeroCheckFunction, denominator);
94 std::vector<llvm::BinaryOperator *> shiftInstructions;
98 auto binOp = dyn_cast<BinaryOperator>(&I);
103 auto opcode = binOp->getOpcode();
104 if (opcode != Instruction::Shl && opcode != Instruction::LShr &&
105 opcode != Instruction::AShr)
109 auto operand = binOp->getOperand(1);
110 if (
auto coOp = dyn_cast<llvm::ConstantInt>(operand)) {
112 binOp->getOperand(0)->getType()->getScalarSizeInBits();
115 if (!coOp->isNegative() && coOp->getZExtValue() < typeWidth)
122 shiftInstructions.push_back(binOp);
127 if (shiftInstructions.empty())
131 auto &ctx = M.getContext();
133 auto overshiftCheckFunction = M.getOrInsertFunction(
134 "klee_overshift_check", Type::getVoidTy(ctx), Type::getInt64Ty(ctx),
135 Type::getInt64Ty(ctx));
137 for (
auto &shiftInst : shiftInstructions) {
138 llvm::IRBuilder<> Builder(shiftInst);
140 std::vector<llvm::Value *> args;
143 uint64_t bitWidth = shiftInst->getOperand(0)->getType()->getScalarSizeInBits();
144 auto bitWidthC = ConstantInt::get(Type::getInt64Ty(ctx), bitWidth,
false);
145 args.push_back(bitWidthC);
148 Builder.CreateIntCast(shiftInst->getOperand(1), Type::getInt64Ty(ctx),
151 args.push_back(shiftValue);
153 Builder.CreateCall(overshiftCheckFunction, args);
bool runOnModule(llvm::Module &M) override