diff options
Diffstat (limited to 'instrumentation')
-rw-r--r-- | instrumentation/README.cmplog.md | 9 | ||||
-rw-r--r-- | instrumentation/README.gcc_plugin.md | 5 | ||||
-rw-r--r-- | instrumentation/README.laf-intel.md | 8 | ||||
-rw-r--r-- | instrumentation/README.llvm.md | 2 | ||||
-rw-r--r-- | instrumentation/SanitizerCoverageLTO.so.cc | 19 | ||||
-rw-r--r-- | instrumentation/SanitizerCoveragePCGUARD.so.cc | 23 | ||||
-rw-r--r-- | instrumentation/afl-llvm-pass.so.cc | 44 | ||||
-rw-r--r-- | instrumentation/cmplog-instructions-pass.cc | 6 | ||||
-rw-r--r-- | instrumentation/cmplog-routines-pass.cc | 48 | ||||
-rw-r--r-- | instrumentation/cmplog-switches-pass.cc | 6 | ||||
-rw-r--r-- | instrumentation/compare-transform-pass.so.cc | 12 | ||||
-rw-r--r-- | instrumentation/split-compares-pass.so.cc | 158 |
12 files changed, 259 insertions, 81 deletions
diff --git a/instrumentation/README.cmplog.md b/instrumentation/README.cmplog.md index 146b4620..668c07eb 100644 --- a/instrumentation/README.cmplog.md +++ b/instrumentation/README.cmplog.md @@ -11,12 +11,11 @@ see ## Build To use CmpLog, you have to build two versions of the instrumented target -program. +program: -The first version is built using the regular AFL++ instrumentation. - -The second one, the CmpLog binary, is built with setting AFL_LLVM_CMPLOG during -the compilation. +* The first version is built using the regular AFL++ instrumentation. +* The second one, the CmpLog binary, is built with setting `AFL_LLVM_CMPLOG` + during the compilation. For example: diff --git a/instrumentation/README.gcc_plugin.md b/instrumentation/README.gcc_plugin.md index ef38662b..ed39af9d 100644 --- a/instrumentation/README.gcc_plugin.md +++ b/instrumentation/README.gcc_plugin.md @@ -1,7 +1,8 @@ # GCC-based instrumentation for afl-fuzz -For the general instruction manual, see [../README.md](../README.md). For the -LLVM-based instrumentation, see [README.llvm.md](README.llvm.md). +For the general instruction manual, see [docs/README.md](../docs/README.md). + +For the LLVM-based instrumentation, see [README.llvm.md](README.llvm.md). This document describes how to build and use `afl-gcc-fast` and `afl-g++-fast`, which instrument the target with the help of gcc plugins. diff --git a/instrumentation/README.laf-intel.md b/instrumentation/README.laf-intel.md index 06e653ea..414be060 100644 --- a/instrumentation/README.laf-intel.md +++ b/instrumentation/README.laf-intel.md @@ -39,13 +39,11 @@ AFL_LLVM_LAF_SPLIT_COMPARES_BITW=<bit_width>`, where bit_width may be 64, 32, or 16. For example, a bit_width of 16 would split larger comparisons down to 16 bit comparisons. -A new experimental feature is splitting floating point comparisons into a series +A new unique feature is splitting floating point comparisons into a series of sign, exponent and mantissa comparisons followed by splitting each of them into 8 bit comparisons when necessary. It is activated with the -`AFL_LLVM_LAF_SPLIT_FLOATS` setting. Note that full IEEE 754 functionality is -not preserved, that is values of nan and infinity will probably behave -differently. +`AFL_LLVM_LAF_SPLIT_FLOATS` setting. Note that setting this automatically activates `AFL_LLVM_LAF_SPLIT_COMPARES`. -You can also set `AFL_LLVM_LAF_ALL` and have all of the above enabled. :-) \ No newline at end of file +You can also set `AFL_LLVM_LAF_ALL` and have all of the above enabled. :-) diff --git a/instrumentation/README.llvm.md b/instrumentation/README.llvm.md index d220e52c..7855a987 100644 --- a/instrumentation/README.llvm.md +++ b/instrumentation/README.llvm.md @@ -1,6 +1,6 @@ # Fast LLVM-based instrumentation for afl-fuzz -For the general instruction manual, see [../README.md](../README.md). +For the general instruction manual, see [docs/README.md](../docs/README.md). For the GCC-based instrumentation, see [README.gcc_plugin.md](README.gcc_plugin.md). diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 8d7f0c80..aa1826cd 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -1123,7 +1123,7 @@ bool ModuleSanitizerCoverage::instrumentModule( M, PointerType::get(Int8Tyi, 0), false, GlobalValue::ExternalLinkage, 0, "__afl_dictionary"); - Value *AFLDictOff = IRB.CreateGEP(AFLInternalDictionary, Zero); + Value *AFLDictOff = IRB.CreateGEP(Int8Ty, AFLInternalDictionary, Zero); Value *AFLDictPtr = IRB.CreatePointerCast(AFLDictOff, PointerType::get(Int8Tyi, 0)); StoreInst *StoreDict = IRB.CreateStore(AFLDictPtr, AFLDictionary); @@ -1388,7 +1388,8 @@ void ModuleSanitizerCoverage::instrumentFunction( local_selects++; uint32_t vector_cur = 0; /* Load SHM pointer */ - LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr); + LoadInst *MapPtr = + IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr); ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr); while (1) { @@ -1399,12 +1400,12 @@ void ModuleSanitizerCoverage::instrumentFunction( /* Load counter for CurLoc */ if (!vector_cnt) { - MapPtrIdx = IRB.CreateGEP(MapPtr, result); + MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, result); } else { auto element = IRB.CreateExtractElement(result, vector_cur++); - MapPtrIdx = IRB.CreateGEP(MapPtr, element); + MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, element); } @@ -1418,7 +1419,7 @@ void ModuleSanitizerCoverage::instrumentFunction( } else { - LoadInst *Counter = IRB.CreateLoad(MapPtrIdx); + LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx); ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter); /* Update bitmap */ @@ -1672,13 +1673,13 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, if (map_addr) { - MapPtrIdx = IRB.CreateGEP(MapPtrFixed, CurLoc); + MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtrFixed, CurLoc); } else { - LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr); + LoadInst *MapPtr = IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr); ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr); - MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc); + MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, CurLoc); } @@ -1693,7 +1694,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } else { - LoadInst *Counter = IRB.CreateLoad(MapPtrIdx); + LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx); ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter); Value *Incr = IRB.CreateAdd(Counter, One); diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index d5746cc7..7b1d1d40 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -937,7 +937,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, ConstantInt::get(IntptrTy, (++special + AllBlocks.size()) * 4)), Int32PtrTy); - LoadInst *Idx = IRB.CreateLoad(GuardPtr); + LoadInst *Idx = IRB.CreateLoad(IRB.getInt32Ty(), GuardPtr); ModuleSanitizerCoverage::SetNoSanitizeMetadata(Idx); callInst->setOperand(1, Idx); @@ -1059,7 +1059,8 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, /* Load SHM pointer */ - LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr); + LoadInst *MapPtr = + IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr); ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr); /* @@ -1078,17 +1079,17 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, /* Load counter for CurLoc */ if (!vector_cnt) { - CurLoc = IRB.CreateLoad(result); + CurLoc = IRB.CreateLoad(IRB.getInt32Ty(), result); ModuleSanitizerCoverage::SetNoSanitizeMetadata(CurLoc); - MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc); + MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, CurLoc); } else { auto element = IRB.CreateExtractElement(result, vector_cur++); auto elementptr = IRB.CreateIntToPtr(element, Int32PtrTy); - auto elementld = IRB.CreateLoad(elementptr); + auto elementld = IRB.CreateLoad(IRB.getInt32Ty(), elementptr); ModuleSanitizerCoverage::SetNoSanitizeMetadata(elementld); - MapPtrIdx = IRB.CreateGEP(MapPtr, elementld); + MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, elementld); } @@ -1102,7 +1103,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, } else { - LoadInst *Counter = IRB.CreateLoad(MapPtrIdx); + LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx); ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter); /* Update bitmap */ @@ -1347,17 +1348,17 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, ConstantInt::get(IntptrTy, Idx * 4)), Int32PtrTy); - LoadInst *CurLoc = IRB.CreateLoad(GuardPtr); + LoadInst *CurLoc = IRB.CreateLoad(IRB.getInt32Ty(), GuardPtr); ModuleSanitizerCoverage::SetNoSanitizeMetadata(CurLoc); /* Load SHM pointer */ - LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr); + LoadInst *MapPtr = IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr); ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr); /* Load counter for CurLoc */ - Value *MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc); + Value *MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, CurLoc); if (use_threadsafe_counters) { @@ -1369,7 +1370,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } else { - LoadInst *Counter = IRB.CreateLoad(MapPtrIdx); + LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx); ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter); /* Update bitmap */ diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index 8e22fde8..640aa4dd 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -454,7 +454,11 @@ bool AFLCoverage::runOnModule(Module &M) { #ifdef AFL_HAVE_VECTOR_INTRINSICS if (ctx_k) { - PrevCaller = IRB.CreateLoad(AFLPrevCaller); + PrevCaller = IRB.CreateLoad( + #if LLVM_VERSION_MAJOR >= 14 + IRB.getInt32Ty(), + #endif + AFLPrevCaller); PrevCaller->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); PrevCtx = @@ -467,7 +471,11 @@ bool AFLCoverage::runOnModule(Module &M) { // load the context ID of the previous function and write to to a // local variable on the stack - LoadInst *PrevCtxLoad = IRB.CreateLoad(AFLContext); + LoadInst *PrevCtxLoad = IRB.CreateLoad( +#if LLVM_VERSION_MAJOR >= 14 + IRB.getInt32Ty(), +#endif + AFLContext); PrevCtxLoad->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); PrevCtx = PrevCtxLoad; @@ -620,7 +628,11 @@ bool AFLCoverage::runOnModule(Module &M) { /* Load prev_loc */ - LoadInst *PrevLoc = IRB.CreateLoad(AFLPrevLoc); + LoadInst *PrevLoc = IRB.CreateLoad( +#if LLVM_VERSION_MAJOR >= 14 + IRB.getInt32Ty(), +#endif + AFLPrevLoc); PrevLoc->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); Value *PrevLocTrans; @@ -644,20 +656,28 @@ bool AFLCoverage::runOnModule(Module &M) { /* Load SHM pointer */ - LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr); + LoadInst *MapPtr = IRB.CreateLoad( +#if LLVM_VERSION_MAJOR >= 14 + PointerType::get(Int8Ty, 0), +#endif + AFLMapPtr); MapPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); Value *MapPtrIdx; #ifdef AFL_HAVE_VECTOR_INTRINSICS if (ngram_size) MapPtrIdx = IRB.CreateGEP( - MapPtr, + Int8Ty, MapPtr, IRB.CreateZExt( IRB.CreateXor(PrevLocTrans, IRB.CreateZExt(CurLoc, Int32Ty)), Int32Ty)); else #endif - MapPtrIdx = IRB.CreateGEP(MapPtr, IRB.CreateXor(PrevLocTrans, CurLoc)); + MapPtrIdx = IRB.CreateGEP( +#if LLVM_VERSION_MAJOR >= 14 + Int8Ty, +#endif + MapPtr, IRB.CreateXor(PrevLocTrans, CurLoc)); /* Update bitmap */ @@ -676,7 +696,11 @@ bool AFLCoverage::runOnModule(Module &M) { } else { - LoadInst *Counter = IRB.CreateLoad(MapPtrIdx); + LoadInst *Counter = IRB.CreateLoad( +#if LLVM_VERSION_MAJOR >= 14 + IRB.getInt8Ty(), +#endif + MapPtrIdx); Counter->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); Value *Incr = IRB.CreateAdd(Counter, One); @@ -813,7 +837,11 @@ bool AFLCoverage::runOnModule(Module &M) { IRBuilder<> IRB(&(*it0)); // load the old counter value atomically - LoadInst *Counter = IRB.CreateLoad(MapPtrIdx); + LoadInst *Counter = IRB.CreateLoad( + #if LLVM_VERSION_MAJOR >= 14 + IRB.getInt8Ty(), + #endif + MapPtrIdx); Counter->setAlignment(llvm::Align()); Counter->setAtomic(llvm::AtomicOrdering::Monotonic); Counter->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index 07f80b2c..054caee2 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -264,7 +264,11 @@ bool CmpLogInstructions::hookInstrs(Module &M) { IRBuilder<> IRB2(selectcmpInst->getParent()); IRB2.SetInsertPoint(selectcmpInst); - LoadInst *CmpPtr = IRB2.CreateLoad(AFLCmplogPtr); + LoadInst *CmpPtr = IRB2.CreateLoad( +#if LLVM_VERSION_MAJOR >= 14 + PointerType::get(Int8Ty, 0), +#endif + AFLCmplogPtr); CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null); auto ThenTerm = diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc index 0565875e..82c2fa4d 100644 --- a/instrumentation/cmplog-routines-pass.cc +++ b/instrumentation/cmplog-routines-pass.cc @@ -448,7 +448,11 @@ bool CmpLogRoutines::hookRtns(Module &M) { IRBuilder<> IRB2(callInst->getParent()); IRB2.SetInsertPoint(callInst); - LoadInst *CmpPtr = IRB2.CreateLoad(AFLCmplogPtr); + LoadInst *CmpPtr = IRB2.CreateLoad( +#if LLVM_VERSION_MAJOR >= 14 + PointerType::get(Int8Ty, 0), +#endif + AFLCmplogPtr); CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null); auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false); @@ -475,7 +479,11 @@ bool CmpLogRoutines::hookRtns(Module &M) { IRBuilder<> IRB2(callInst->getParent()); IRB2.SetInsertPoint(callInst); - LoadInst *CmpPtr = IRB2.CreateLoad(AFLCmplogPtr); + LoadInst *CmpPtr = IRB2.CreateLoad( +#if LLVM_VERSION_MAJOR >= 14 + PointerType::get(Int8Ty, 0), +#endif + AFLCmplogPtr); CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null); auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false); @@ -506,7 +514,11 @@ bool CmpLogRoutines::hookRtns(Module &M) { IRBuilder<> IRB2(callInst->getParent()); IRB2.SetInsertPoint(callInst); - LoadInst *CmpPtr = IRB2.CreateLoad(AFLCmplogPtr); + LoadInst *CmpPtr = IRB2.CreateLoad( +#if LLVM_VERSION_MAJOR >= 14 + PointerType::get(Int8Ty, 0), +#endif + AFLCmplogPtr); CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null); auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false); @@ -533,7 +545,11 @@ bool CmpLogRoutines::hookRtns(Module &M) { IRBuilder<> IRB2(callInst->getParent()); IRB2.SetInsertPoint(callInst); - LoadInst *CmpPtr = IRB2.CreateLoad(AFLCmplogPtr); + LoadInst *CmpPtr = IRB2.CreateLoad( +#if LLVM_VERSION_MAJOR >= 14 + PointerType::get(Int8Ty, 0), +#endif + AFLCmplogPtr); CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null); auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false); @@ -564,7 +580,11 @@ bool CmpLogRoutines::hookRtns(Module &M) { IRBuilder<> IRB2(callInst->getParent()); IRB2.SetInsertPoint(callInst); - LoadInst *CmpPtr = IRB2.CreateLoad(AFLCmplogPtr); + LoadInst *CmpPtr = IRB2.CreateLoad( +#if LLVM_VERSION_MAJOR >= 14 + PointerType::get(Int8Ty, 0), +#endif + AFLCmplogPtr); CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null); auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false); @@ -590,7 +610,11 @@ bool CmpLogRoutines::hookRtns(Module &M) { IRBuilder<> IRB2(callInst->getParent()); IRB2.SetInsertPoint(callInst); - LoadInst *CmpPtr = IRB2.CreateLoad(AFLCmplogPtr); + LoadInst *CmpPtr = IRB2.CreateLoad( +#if LLVM_VERSION_MAJOR >= 14 + PointerType::get(Int8Ty, 0), +#endif + AFLCmplogPtr); CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null); auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false); @@ -616,7 +640,11 @@ bool CmpLogRoutines::hookRtns(Module &M) { IRBuilder<> IRB2(callInst->getParent()); IRB2.SetInsertPoint(callInst); - LoadInst *CmpPtr = IRB2.CreateLoad(AFLCmplogPtr); + LoadInst *CmpPtr = IRB2.CreateLoad( +#if LLVM_VERSION_MAJOR >= 14 + PointerType::get(Int8Ty, 0), +#endif + AFLCmplogPtr); CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null); auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false); @@ -642,7 +670,11 @@ bool CmpLogRoutines::hookRtns(Module &M) { IRBuilder<> IRB2(callInst->getParent()); IRB2.SetInsertPoint(callInst); - LoadInst *CmpPtr = IRB2.CreateLoad(AFLCmplogPtr); + LoadInst *CmpPtr = IRB2.CreateLoad( +#if LLVM_VERSION_MAJOR >= 14 + PointerType::get(Int8Ty, 0), +#endif + AFLCmplogPtr); CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null); auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false); diff --git a/instrumentation/cmplog-switches-pass.cc b/instrumentation/cmplog-switches-pass.cc index bcd5f8bd..4f6f2eca 100644 --- a/instrumentation/cmplog-switches-pass.cc +++ b/instrumentation/cmplog-switches-pass.cc @@ -246,7 +246,11 @@ bool CmpLogInstructions::hookInstrs(Module &M) { IRBuilder<> IRB2(SI->getParent()); IRB2.SetInsertPoint(SI); - LoadInst *CmpPtr = IRB2.CreateLoad(AFLCmplogPtr); + LoadInst *CmpPtr = IRB2.CreateLoad( +#if LLVM_VERSION_MAJOR >= 14 + PointerType::get(Int8Ty, 0), +#endif + AFLCmplogPtr); CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null); auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, SI, false); diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index ef3bd66b..2ced37c5 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -529,8 +529,16 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, IRBuilder<> cur_cmp_IRB(&*(cur_cmp_bb->getFirstInsertionPt())); Value *v = ConstantInt::get(Int64Ty, i); - Value *ele = cur_cmp_IRB.CreateInBoundsGEP(VarStr, v, "empty"); - Value *load = cur_cmp_IRB.CreateLoad(ele); + Value *ele = cur_cmp_IRB.CreateInBoundsGEP( +#if LLVM_VERSION_MAJOR >= 14 + Int8Ty, +#endif + VarStr, v, "empty"); + Value *load = cur_cmp_IRB.CreateLoad( +#if LLVM_VERSION_MAJOR >= 14 + Int8Ty, +#endif + ele); if (isCaseInsensitive) { diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc index 95485be9..451258d9 100644 --- a/instrumentation/split-compares-pass.so.cc +++ b/instrumentation/split-compares-pass.so.cc @@ -882,6 +882,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { // BUG FIXME TODO: u64 does not work for > 64 bit ... e.g. 80 and 128 bit if (sizeInBits > 64) { continue; } + IntegerType * intType = IntegerType::get(C, op_size); const unsigned int precision = sizeInBits == 32 ? 24 : sizeInBits == 64 ? 53 : sizeInBits == 128 ? 113 @@ -913,14 +914,106 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(FcmpInst)); /* create the integers from floats directly */ - Instruction *b_op0, *b_op1; - b_op0 = CastInst::Create(Instruction::BitCast, op0, - IntegerType::get(C, op_size)); - bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), b_op0); + Instruction *bpre_op0, *bpre_op1; + bpre_op0 = CastInst::Create(Instruction::BitCast, op0, + IntegerType::get(C, op_size)); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), + bpre_op0); + + bpre_op1 = CastInst::Create(Instruction::BitCast, op1, + IntegerType::get(C, op_size)); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), + bpre_op1); + + /* Check if any operand is NaN. + * If so, all comparisons except unequal (which yields true) yield false */ + + /* build mask for NaN */ + const unsigned long long NaN_lowend = mask_exponent << precision; + // errs() << "Fractions: IntFractionTy size " << + // IntFractionTy->getPrimitiveSizeInBits() << ", op_size " << op_size << + // ", mask_fraction 0x"; + // errs().write_hex(mask_fraction); + // errs() << ", precision " << precision << + // ", NaN_lowend 0x"; + // errs().write_hex(NaN_lowend); errs() << "\n"; + + /* Check op0 for NaN */ + /* Shift left 1 Bit, ignore sign bit */ + Instruction *nan_op0, *nan_op1; + nan_op0 = BinaryOperator::Create(Instruction::Shl, bpre_op0, + ConstantInt::get(bpre_op0->getType(), 1)); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), + nan_op0); + + /* compare to NaN interval */ + Instruction *is_op0_nan = + CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, nan_op0, + ConstantInt::get(intType, NaN_lowend)); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), + is_op0_nan); + + /* Check op1 for NaN */ + /* Shift right 1 Bit, ignore sign bit */ + nan_op1 = BinaryOperator::Create(Instruction::Shl, bpre_op1, + ConstantInt::get(bpre_op1->getType(), 1)); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), + nan_op1); + + /* compare to NaN interval */ + Instruction *is_op1_nan = + CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, nan_op1, + ConstantInt::get(intType, NaN_lowend)); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), + is_op1_nan); + + /* combine checks */ + Instruction *is_nan = + BinaryOperator::Create(Instruction::Or, is_op0_nan, is_op1_nan); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), is_nan); + + /* the result of the comparison, when at least one op is NaN + is true only for the "NOT EQUAL" predicates. */ + bool NaNcmp_result = FcmpInst->getPredicate() == CmpInst::FCMP_ONE || + FcmpInst->getPredicate() == CmpInst::FCMP_UNE; + + BasicBlock *nonan_bb = + BasicBlock::Create(C, "noNaN", end_bb->getParent(), end_bb); - b_op1 = CastInst::Create(Instruction::BitCast, op1, - IntegerType::get(C, op_size)); - bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), b_op1); + BranchInst::Create(end_bb, nonan_bb); + + auto term = bb->getTerminator(); + /* if no operand is NaN goto nonan_bb else to handleNaN_bb */ + BranchInst::Create(end_bb, nonan_bb, is_nan, bb); + term->eraseFromParent(); + + /*** now working in nonan_bb ***/ + + /* Treat -0.0 as equal to +0.0, that is for -0.0 make it +0.0 */ + Instruction * b_op0, *b_op1; + Instruction * isMzero_op0, *isMzero_op1; + const unsigned long long MinusZero = 1UL << (sizeInBits - 1U); + const unsigned long long PlusZero = 0; + + isMzero_op0 = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, bpre_op0, + ConstantInt::get(intType, MinusZero)); + nonan_bb->getInstList().insert( + BasicBlock::iterator(nonan_bb->getTerminator()), isMzero_op0); + + isMzero_op1 = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, bpre_op1, + ConstantInt::get(intType, MinusZero)); + nonan_bb->getInstList().insert( + BasicBlock::iterator(nonan_bb->getTerminator()), isMzero_op1); + + b_op0 = SelectInst::Create(isMzero_op0, ConstantInt::get(intType, PlusZero), + bpre_op0); + nonan_bb->getInstList().insert( + BasicBlock::iterator(nonan_bb->getTerminator()), b_op0); + + b_op1 = SelectInst::Create(isMzero_op1, ConstantInt::get(intType, PlusZero), + bpre_op1); + nonan_bb->getInstList().insert( + BasicBlock::iterator(nonan_bb->getTerminator()), b_op1); /* isolate signs of value of floating point type */ @@ -931,22 +1024,26 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { s_s0 = BinaryOperator::Create(Instruction::LShr, b_op0, ConstantInt::get(b_op0->getType(), op_size - 1)); - bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), s_s0); + nonan_bb->getInstList().insert( + BasicBlock::iterator(nonan_bb->getTerminator()), s_s0); t_s0 = new TruncInst(s_s0, Int1Ty); - bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), t_s0); + nonan_bb->getInstList().insert( + BasicBlock::iterator(nonan_bb->getTerminator()), t_s0); s_s1 = BinaryOperator::Create(Instruction::LShr, b_op1, ConstantInt::get(b_op1->getType(), op_size - 1)); - bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), s_s1); + nonan_bb->getInstList().insert( + BasicBlock::iterator(nonan_bb->getTerminator()), s_s1); t_s1 = new TruncInst(s_s1, Int1Ty); - bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), t_s1); + nonan_bb->getInstList().insert( + BasicBlock::iterator(nonan_bb->getTerminator()), t_s1); /* compare of the sign bits */ icmp_sign_bit = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, t_s0, t_s1); - bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), - icmp_sign_bit); + nonan_bb->getInstList().insert( + BasicBlock::iterator(nonan_bb->getTerminator()), icmp_sign_bit); /* create a new basic block which is executed if the signedness bits are * equal */ @@ -962,9 +1059,9 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { BranchInst::Create(end_bb, middle_bb); - auto term = bb->getTerminator(); + term = nonan_bb->getTerminator(); /* if the signs are different goto end_bb else to signequal_bb */ - BranchInst::Create(signequal_bb, end_bb, icmp_sign_bit, bb); + BranchInst::Create(signequal_bb, end_bb, icmp_sign_bit, nonan_bb); term->eraseFromParent(); /* insert code for equal signs */ @@ -1261,7 +1358,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { } - PHINode *PN = PHINode::Create(Int1Ty, 3, ""); + PHINode *PN = PHINode::Create(Int1Ty, 4, ""); switch (FcmpInst->getPredicate()) { @@ -1269,37 +1366,45 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { case CmpInst::FCMP_OEQ: /* unequal signs cannot be equal values */ /* goto false branch */ - PN->addIncoming(ConstantInt::get(Int1Ty, 0), bb); + PN->addIncoming(ConstantInt::get(Int1Ty, 0), nonan_bb); /* unequal exponents cannot be equal values, too */ PN->addIncoming(ConstantInt::get(Int1Ty, 0), signequal_bb); /* fractions comparison */ PN->addIncoming(icmp_fraction_result, middle2_bb); + /* NaNs */ + PN->addIncoming(ConstantInt::get(Int1Ty, NaNcmp_result), bb); break; case CmpInst::FCMP_ONE: case CmpInst::FCMP_UNE: /* unequal signs are unequal values */ /* goto true branch */ - PN->addIncoming(ConstantInt::get(Int1Ty, 1), bb); + PN->addIncoming(ConstantInt::get(Int1Ty, 1), nonan_bb); /* unequal exponents are unequal values, too */ PN->addIncoming(icmp_exponent_result, signequal_bb); /* fractions comparison */ PN->addIncoming(icmp_fraction_result, middle2_bb); + /* NaNs */ + PN->addIncoming(ConstantInt::get(Int1Ty, NaNcmp_result), bb); break; case CmpInst::FCMP_OGT: case CmpInst::FCMP_UGT: /* if op1 is negative goto true branch, else go on comparing */ - PN->addIncoming(t_s1, bb); + PN->addIncoming(t_s1, nonan_bb); PN->addIncoming(icmp_exponent_result, signequal2_bb); PN->addIncoming(PN2, middle2_bb); + /* NaNs */ + PN->addIncoming(ConstantInt::get(Int1Ty, NaNcmp_result), bb); break; case CmpInst::FCMP_OLT: case CmpInst::FCMP_ULT: /* if op0 is negative goto true branch, else go on comparing */ - PN->addIncoming(t_s0, bb); + PN->addIncoming(t_s0, nonan_bb); PN->addIncoming(icmp_exponent_result, signequal2_bb); PN->addIncoming(PN2, middle2_bb); + /* NaNs */ + PN->addIncoming(ConstantInt::get(Int1Ty, NaNcmp_result), bb); break; default: continue; @@ -1341,18 +1446,15 @@ bool SplitComparesTransform::runOnModule(Module &M) { if (enableFPSplit) { + simplifyFPCompares(M); count = splitFPCompares(M); - /* - if (!be_quiet) { + if (!be_quiet && !debug) { - errs() << "Split-floatingpoint-compare-pass: " << count - << " FP comparisons split\n"; + errs() << "Split-floatingpoint-compare-pass: " << count + << " FP comparisons splitted\n"; - } - - */ - simplifyFPCompares(M); + } } |