12#include "llvm/Support/raw_ostream.h"
18void printOperandWarning(
const char *expected,
const Instruction *i, Type *ty,
21 llvm::raw_string_ostream ss(msg);
22 ss <<
"Found unexpected type (" << *ty <<
") at operand " << opNum
23 <<
". Expected " << expected <<
" in " << *i;
29bool checkOperandTypeIsScalarInt(
const Instruction *i,
unsigned opNum) {
30 assert(opNum < i->getNumOperands());
31 llvm::Type *ty = i->getOperand(opNum)->getType();
32 if (!(ty->isIntegerTy())) {
33 printOperandWarning(
"scalar integer", i, ty, opNum);
39bool checkOperandTypeIsScalarIntOrPointer(
const Instruction *i,
41 assert(opNum < i->getNumOperands());
42 llvm::Type *ty = i->getOperand(opNum)->getType();
43 if (!(ty->isIntegerTy() || ty->isPointerTy())) {
44 printOperandWarning(
"scalar integer or pointer", i, ty, opNum);
50bool checkOperandTypeIsScalarPointer(
const Instruction *i,
unsigned opNum) {
51 assert(opNum < i->getNumOperands());
52 llvm::Type *ty = i->getOperand(opNum)->getType();
53 if (!(ty->isPointerTy())) {
54 printOperandWarning(
"scalar pointer", i, ty, opNum);
60bool checkOperandTypeIsScalarFloat(
const Instruction *i,
unsigned opNum) {
61 assert(opNum < i->getNumOperands());
62 llvm::Type *ty = i->getOperand(opNum)->getType();
63 if (!(ty->isFloatingPointTy())) {
64 printOperandWarning(
"scalar float", i, ty, opNum);
70bool checkOperandsHaveSameType(
const Instruction *i,
unsigned opNum0,
72 assert(opNum0 < i->getNumOperands());
73 assert(opNum1 < i->getNumOperands());
74 llvm::Type *ty0 = i->getOperand(opNum0)->getType();
75 llvm::Type *ty1 = i->getOperand(opNum1)->getType();
78 llvm::raw_string_ostream ss(msg);
79 ss <<
"Found mismatched type (" << *ty0 <<
" != " << *ty1
80 <<
") for operands" << opNum0 <<
" and " << opNum1
81 <<
". Expected operand types to match in " << *i;
90bool checkInstruction(
const Instruction *i) {
91 switch (i->getOpcode()) {
92 case Instruction::Select: {
97 return checkOperandTypeIsScalarInt(i, 0) &
98 checkOperandsHaveSameType(i, 1, 2);
101 case Instruction::Add:
102 case Instruction::Sub:
103 case Instruction::Mul:
104 case Instruction::UDiv:
105 case Instruction::SDiv:
106 case Instruction::URem:
107 case Instruction::SRem:
108 case Instruction::And:
109 case Instruction::Or:
110 case Instruction::Xor:
111 case Instruction::Shl:
112 case Instruction::LShr:
113 case Instruction::AShr: {
114 return checkOperandTypeIsScalarInt(i, 0) &
115 checkOperandTypeIsScalarInt(i, 1);
118 case Instruction::ICmp: {
119 return checkOperandTypeIsScalarIntOrPointer(i, 0) &
120 checkOperandTypeIsScalarIntOrPointer(i, 1);
123 case Instruction::Trunc:
124 case Instruction::ZExt:
125 case Instruction::SExt:
126 case Instruction::IntToPtr: {
127 return checkOperandTypeIsScalarInt(i, 0);
129 case Instruction::PtrToInt: {
130 return checkOperandTypeIsScalarPointer(i, 0);
134 case Instruction::FAdd:
135 case Instruction::FSub:
136 case Instruction::FMul:
137 case Instruction::FDiv:
138 case Instruction::FRem: {
139 return checkOperandTypeIsScalarFloat(i, 0) &
140 checkOperandTypeIsScalarFloat(i, 1);
143 case Instruction::FPTrunc:
144 case Instruction::FPExt:
145 case Instruction::FPToUI:
146 case Instruction::FPToSI: {
147 return checkOperandTypeIsScalarFloat(i, 0);
149 case Instruction::UIToFP:
150 case Instruction::SIToFP: {
151 return checkOperandTypeIsScalarInt(i, 0);
154 case Instruction::FCmp: {
155 return checkOperandTypeIsScalarFloat(i, 0) &
156 checkOperandTypeIsScalarFloat(i, 1);
171 for (Module::iterator fi = M.begin(), fe = M.end(); fi != fe; ++fi) {
172 for (Function::iterator bi = fi->begin(), be = fi->end(); bi != be; ++bi) {
173 for (BasicBlock::iterator ii = bi->begin(), ie = bi->end(); ii != ie;
175 Instruction *i = &*ii;
bool runOnModule(llvm::Module &M) override
bool instructionOperandsConform
void void void klee_warning(const char *msg,...) __attribute__((format(printf