From caf68e5bf25a8a73bcc21b870499b640e7702d85 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 3 Nov 2021 12:34:26 +0100 Subject: support vectorized cmps --- instrumentation/cmplog-instructions-pass.cc | 205 ++++++++++++++++++++-------- 1 file changed, 148 insertions(+), 57 deletions(-) (limited to 'instrumentation/cmplog-instructions-pass.cc') diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index 0562c5b2..86e206f1 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -274,14 +274,15 @@ 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 args; - - CmpInst *cmpInst = dyn_cast(selectcmpInst); + IntegerType *intTyOp0 = NULL; + IntegerType *intTyOp1 = NULL; + unsigned max_size = 0, cast_size = 0; + unsigned attr = 0, vector_cnt = 0; + CmpInst * cmpInst = dyn_cast(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(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(op0->getType()); - intTyOp1 = dyn_cast(op1->getType()); + if (ty0->isVectorTy()) { + + VectorType *tt = dyn_cast(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(ty0); + intTyOp1 = dyn_cast(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,67 +441,110 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } - // errs() << "[CMPLOG] cmp " << *cmpInst << "(in function " << - // cmpInst->getFunction()->getName() << ")\n"; + uint64_t cur = 0, last_val0 = 0, last_val1 = 0, cur_val; - // 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) - 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())); - Value *V1 = - IRB.CreateIntCast(op1_i, IntegerType::get(C, cast_size), false); - args.push_back(V1); + while (1) { - // errs() << "[CMPLOG] casted parameters:\n0: " << *V0 << "\n1: " << *V1 - // << "\n"; + std::vector args; + uint32_t skip = 0; - ConstantInt *attribute = ConstantInt::get(Int8Ty, attr); - args.push_back(attribute); + if (vector_cnt) { - if (cast_size != max_size) { + op0 = IRB.CreateExtractElement(op0_saved, cur); + op1 = IRB.CreateExtractElement(op1_saved, cur); + ConstantInt *i0 = dyn_cast(op0); + ConstantInt *i1 = dyn_cast(op1); + if (i0 && i0->uge(0xffffffffffffffff) == false) { - ConstantInt *bitsize = ConstantInt::get(Int8Ty, (max_size / 8) - 1); - args.push_back(bitsize); + cur_val = i0->getZExtValue(); + if (last_val0 && last_val0 == cur_val) { skip = 1; } + last_val0 = cur_val; - } + } - // fprintf(stderr, "_ExtInt(%u) castTo %u with attr %u didcast %u\n", - // max_size, cast_size, attr); + if (i1 && i1->uge(0xffffffffffffffff) == false) { - switch (cast_size) { + cur_val = i1->getZExtValue(); + if (last_val1 && last_val1 == cur_val) { skip = 1; } + last_val1 = cur_val; - case 8: - IRB.CreateCall(cmplogHookIns1, args); - break; - case 16: - IRB.CreateCall(cmplogHookIns2, args); - break; - case 32: - IRB.CreateCall(cmplogHookIns4, args); - break; - case 64: - IRB.CreateCall(cmplogHookIns8, args); - break; - case 128: - if (max_size == 128) { + } + + } + + 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, 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, 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 + // << "\n"; - IRB.CreateCall(cmplogHookIns16, args); + ConstantInt *attribute = ConstantInt::get(Int8Ty, attr); + args.push_back(attribute); - } else { + if (cast_size != max_size) { - IRB.CreateCall(cmplogHookInsN, args); + ConstantInt *bitsize = ConstantInt::get(Int8Ty, (max_size / 8) - 1); + args.push_back(bitsize); } - break; + // fprintf(stderr, "_ExtInt(%u) castTo %u with attr %u didcast %u\n", + // max_size, cast_size, attr); + + switch (cast_size) { + + case 8: + IRB.CreateCall(cmplogHookIns1, args); + break; + case 16: + IRB.CreateCall(cmplogHookIns2, args); + break; + case 32: + IRB.CreateCall(cmplogHookIns4, args); + break; + case 64: + IRB.CreateCall(cmplogHookIns8, args); + break; + case 128: + if (max_size == 128) { + + IRB.CreateCall(cmplogHookIns16, args); + + } else { + + IRB.CreateCall(cmplogHookInsN, args); + + } + + break; + + } + + } + + /* else fprintf(stderr, "skipped\n"); */ + + ++cur; + if (cur >= vector_cnt) { break; } } -- cgit 1.4.1 From ccded9fc5cfead1b88104484c4acde12e81e0afe Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 3 Nov 2021 12:49:54 +0100 Subject: vectorized coverage only possible for llvm 14 :( --- instrumentation/SanitizerCoverageLTO.so.cc | 10 ++++++++-- instrumentation/SanitizerCoveragePCGUARD.so.cc | 17 +++++++++++++++-- instrumentation/cmplog-instructions-pass.cc | 1 - 3 files changed, 23 insertions(+), 5 deletions(-) (limited to 'instrumentation/cmplog-instructions-pass.cc') diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index b3a6ba45..fbbe24a2 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -1313,7 +1313,10 @@ void ModuleSanitizerCoverage::instrumentFunction( result = IRB.CreateSelect(condition, val1, val2); inst += 2; - } else if (t->getTypeID() == llvm::Type::FixedVectorTyID) { + } + +#if LLVM_VERSION_MAJOR > 13 + else if (t->getTypeID() == llvm::Type::FixedVectorTyID) { FixedVectorType *tt = dyn_cast(t); if (tt) { @@ -1355,7 +1358,10 @@ void ModuleSanitizerCoverage::instrumentFunction( } - } else { + } else + +#endif + { unhandled++; continue; diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index 70af2ee2..10c9430e 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -895,6 +895,12 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, CallInst *callInst = nullptr; + /* + std::string errMsg; + raw_string_ostream os(errMsg); + IN.print(os); + fprintf(stderr, "X: %s\n", os.str().c_str()); + */ if ((callInst = dyn_cast(&IN))) { Function *Callee = callInst->getCalledFunction(); @@ -948,7 +954,10 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, result = IRB.CreateSelect(condition, GuardPtr1, GuardPtr2); - } else if (t->getTypeID() == llvm::Type::FixedVectorTyID) { + } else + +#if LLVM_VERSION_MAJOR > 13 + if (t->getTypeID() == llvm::Type::FixedVectorTyID) { FixedVectorType *tt = dyn_cast(t); if (tt) { @@ -1015,9 +1024,13 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, } - } else { + } else + +#endif + { unhandled++; + continue; } diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index 86e206f1..cb149e9a 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -377,7 +377,6 @@ bool CmpLogInstructions::hookInstrs(Module &M) { vector_cnt = tt->getElementCount().getFixedValue(); ty1 = ty0 = tt->getElementType(); - fprintf(stderr, "vec %u\n", vector_cnt); } -- cgit 1.4.1 From 7a7630ae91c87e000b40f63c592fad9e09ad45d3 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 3 Nov 2021 13:18:02 +0100 Subject: support llvm >= 11 --- instrumentation/SanitizerCoverageLTO.so.cc | 18 ++++++++++-------- instrumentation/SanitizerCoveragePCGUARD.so.cc | 7 ++++++- instrumentation/cmplog-instructions-pass.cc | 11 ++++++++++- 3 files changed, 26 insertions(+), 10 deletions(-) (limited to 'instrumentation/cmplog-instructions-pass.cc') diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index fbbe24a2..ee8c317e 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -1296,6 +1296,12 @@ void ModuleSanitizerCoverage::instrumentFunction( SelectInst *selectInst = nullptr; + /* + std::string errMsg; + raw_string_ostream os(errMsg); + IN.print(os); + fprintf(stderr, "X(%u): %s\n", skip_next, os.str().c_str()); + */ if (!skip_next && (selectInst = dyn_cast(&IN))) { uint32_t vector_cnt = 0; @@ -1311,12 +1317,13 @@ void ModuleSanitizerCoverage::instrumentFunction( Value *val1 = ConstantInt::get(Int32Ty, ++afl_global_id); Value *val2 = ConstantInt::get(Int32Ty, ++afl_global_id); result = IRB.CreateSelect(condition, val1, val2); + skip_next = 1; inst += 2; - } + } else #if LLVM_VERSION_MAJOR > 13 - else if (t->getTypeID() == llvm::Type::FixedVectorTyID) { + if (t->getTypeID() == llvm::Type::FixedVectorTyID) { FixedVectorType *tt = dyn_cast(t); if (tt) { @@ -1346,13 +1353,8 @@ void ModuleSanitizerCoverage::instrumentFunction( } - /* - std::string errMsg; - raw_string_ostream os(errMsg); - x->print(os); - fprintf(stderr, "X: %s\n", os.str().c_str()); - */ result = IRB.CreateSelect(condition, x, y); + skip_next = 1; } diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index 10c9430e..be3f4f49 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -865,7 +865,10 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, cnt_sel++; cnt_sel_inc += 2; - } else if (t->getTypeID() == llvm::Type::FixedVectorTyID) { + } + +#if LLVM__MAJOR > 11 + else if (t->getTypeID() == llvm::Type::FixedVectorTyID) { FixedVectorType *tt = dyn_cast(t); if (tt) { @@ -877,6 +880,8 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, } +#endif + } } diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index cb149e9a..01a8a637 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -338,8 +338,10 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } +#if LLVM_MAJOR > 11 vector_cnt = tt->getElementCount().getFixedValue(); ty0 = tt->getElementType(); +#endif } @@ -357,9 +359,11 @@ bool CmpLogInstructions::hookInstrs(Module &M) { max_size = 80; else if (ty0->isFP128Ty() || ty0->isPPC_FP128Ty()) max_size = 128; +#if LLVM_MAJOR > 11 else if (ty0->getTypeID() != llvm::Type::PointerTyID && !be_quiet) fprintf(stderr, "Warning: unsupported cmp type for cmplog: %u!\n", ty0->getTypeID()); +#endif attr += 8; @@ -367,6 +371,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) { if (ty0->isVectorTy()) { +#if LLVM_MAJOR > 11 VectorType *tt = dyn_cast(ty0); if (!tt) { @@ -377,6 +382,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) { vector_cnt = tt->getElementCount().getFixedValue(); ty1 = ty0 = tt->getElementType(); +#endif } @@ -391,13 +397,16 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } else { +#if LLVM_MAJOR > 11 if (ty0->getTypeID() != llvm::Type::PointerTyID && !be_quiet) { - fprintf(stderr, "Warning: unsupported cmp type for cmplog: %u!\n", + fprintf(stderr, "Warning: unsupported cmp type for cmplog: %u\n", ty0->getTypeID()); } +#endif + } } -- cgit 1.4.1