support vectorized cmps
MODIFY
instrumentation/cmplog-instructions-pass.cc
instrumentation/cmplog-instructions-pass.cc
@@ -274,13 +274,14 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
Value *op0 = selectcmpInst->getOperand(0);
Value *op1 = selectcmpInst->getOperand(1);
+ Value *op0_saved = op0, *op1_saved = op1;
+ auto ty0 = op0->getType();
+ auto ty1 = op1->getType();
IntegerType *intTyOp0 = NULL;
IntegerType *intTyOp1 = NULL;
unsigned max_size = 0, cast_size = 0;
- unsigned char attr = 0;
- std::vector<Value *> args;
-
+ unsigned attr = 0, vector_cnt = 0;
CmpInst * cmpInst = dyn_cast<CmpInst>(selectcmpInst);
if (!cmpInst) { continue; }
@@ -327,7 +328,21 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
if (selectcmpInst->getOpcode() == Instruction::FCmp) {
- auto ty0 = op0->getType();
+ if (ty0->isVectorTy()) {
+
+ VectorType *tt = dyn_cast<VectorType>(ty0);
+ if (!tt) {
+
+ fprintf(stderr, "Warning: cmplog cmp vector is not a vector!\n");
+ continue;
+
+ }
+
+ vector_cnt = tt->getElementCount().getFixedValue();
+ ty0 = tt->getElementType();
+
+ }
+
if (ty0->isHalfTy()
#if LLVM_VERSION_MAJOR >= 11
|| ty0->isBFloatTy()
@@ -342,13 +357,32 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
max_size = 80;
else if (ty0->isFP128Ty() || ty0->isPPC_FP128Ty())
max_size = 128;
+ else if (ty0->getTypeID() != llvm::Type::PointerTyID && !be_quiet)
+ fprintf(stderr, "Warning: unsupported cmp type for cmplog: %u!\n",
+ ty0->getTypeID());
attr += 8;
} else {
- intTyOp0 = dyn_cast<IntegerType>(op0->getType());
- intTyOp1 = dyn_cast<IntegerType>(op1->getType());
+ if (ty0->isVectorTy()) {
+
+ VectorType *tt = dyn_cast<VectorType>(ty0);
+ if (!tt) {
+
+ fprintf(stderr, "Warning: cmplog cmp vector is not a vector!\n");
+ continue;
+
+ }
+
+ vector_cnt = tt->getElementCount().getFixedValue();
+ ty1 = ty0 = tt->getElementType();
+ fprintf(stderr, "vec %u\n", vector_cnt);
+
+ }
+
+ intTyOp0 = dyn_cast<IntegerType>(ty0);
+ intTyOp1 = dyn_cast<IntegerType>(ty1);
if (intTyOp0 && intTyOp1) {
@@ -356,11 +390,25 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
? intTyOp0->getBitWidth()
: intTyOp1->getBitWidth();
+ } else {
+
+ if (ty0->getTypeID() != llvm::Type::PointerTyID && !be_quiet) {
+
+ fprintf(stderr, "Warning: unsupported cmp type for cmplog: %u!\n",
+ ty0->getTypeID());
+
+ }
+
}
}
- if (!max_size || max_size < 16) { continue; }
+ if (!max_size || max_size < 16) {
+
+ // fprintf(stderr, "too small\n");
+ continue;
+
+ }
if (max_size % 8) { max_size = (((max_size / 8) + 1) * 8); }
@@ -393,26 +441,60 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
}
+ uint64_t cur = 0, last_val0 = 0, last_val1 = 0, cur_val;
+
+ while (1) {
+
+ std::vector<Value *> args;
+ uint32_t skip = 0;
+
+ if (vector_cnt) {
+
+ op0 = IRB.CreateExtractElement(op0_saved, cur);
+ op1 = IRB.CreateExtractElement(op1_saved, cur);
+ ConstantInt *i0 = dyn_cast<ConstantInt>(op0);
+ ConstantInt *i1 = dyn_cast<ConstantInt>(op1);
+ if (i0 && i0->uge(0xffffffffffffffff) == false) {
+
+ cur_val = i0->getZExtValue();
+ if (last_val0 && last_val0 == cur_val) { skip = 1; }
+ last_val0 = cur_val;
+
+ }
+
+ if (i1 && i1->uge(0xffffffffffffffff) == false) {
+
+ cur_val = i1->getZExtValue();
+ if (last_val1 && last_val1 == cur_val) { skip = 1; }
+ last_val1 = cur_val;
+
+ }
+
+ }
+
+ if (!skip) {
+
// errs() << "[CMPLOG] cmp " << *cmpInst << "(in function " <<
// cmpInst->getFunction()->getName() << ")\n";
// first bitcast to integer type of the same bitsize as the original
// type (this is a nop, if already integer)
Value *op0_i = IRB.CreateBitCast(
- op0, IntegerType::get(C, op0->getType()->getPrimitiveSizeInBits()));
- // then create a int cast, which does zext, trunc or bitcast. In our case
- // usually zext to the next larger supported type (this is a nop if
- // already the right type)
+ op0, IntegerType::get(C, ty0->getPrimitiveSizeInBits()));
+ // then create a int cast, which does zext, trunc or bitcast. In our
+ // case usually zext to the next larger supported type (this is a nop
+ // if already the right type)
Value *V0 =
IRB.CreateIntCast(op0_i, IntegerType::get(C, cast_size), false);
args.push_back(V0);
Value *op1_i = IRB.CreateBitCast(
- op1, IntegerType::get(C, op1->getType()->getPrimitiveSizeInBits()));
+ op1, IntegerType::get(C, ty1->getPrimitiveSizeInBits()));
Value *V1 =
IRB.CreateIntCast(op1_i, IntegerType::get(C, cast_size), false);
args.push_back(V1);
- // errs() << "[CMPLOG] casted parameters:\n0: " << *V0 << "\n1: " << *V1
+ // errs() << "[CMPLOG] casted parameters:\n0: " << *V0 << "\n1: " <<
+ // *V1
// << "\n";
ConstantInt *attribute = ConstantInt::get(Int8Ty, attr);
@@ -459,6 +541,15 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
}
+ /* else fprintf(stderr, "skipped\n"); */
+
+ ++cur;
+ if (cur >= vector_cnt) { break; }
+
+ }
+
+ }
+
}
if (icomps.size())

support vectorized cmps