10b57cec5SDimitry Andric //===-- IRMutator.cpp -----------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/FuzzMutate/IRMutator.h" 10bdd1243dSDimitry Andric #include "llvm/ADT/STLExtras.h" 11bdd1243dSDimitry Andric #include "llvm/ADT/SmallSet.h" 120b57cec5SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h" 1381ad6265SDimitry Andric #include "llvm/Bitcode/BitcodeReader.h" 1481ad6265SDimitry Andric #include "llvm/Bitcode/BitcodeWriter.h" 150b57cec5SDimitry Andric #include "llvm/FuzzMutate/Operations.h" 160b57cec5SDimitry Andric #include "llvm/FuzzMutate/Random.h" 170b57cec5SDimitry Andric #include "llvm/FuzzMutate/RandomIRBuilder.h" 180b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h" 19bdd1243dSDimitry Andric #include "llvm/IR/FMF.h" 200b57cec5SDimitry Andric #include "llvm/IR/Function.h" 210b57cec5SDimitry Andric #include "llvm/IR/InstIterator.h" 220b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 230b57cec5SDimitry Andric #include "llvm/IR/Module.h" 24bdd1243dSDimitry Andric #include "llvm/IR/Operator.h" 25*0fca6ea1SDimitry Andric #include "llvm/IR/PassInstrumentation.h" 2681ad6265SDimitry Andric #include "llvm/IR/Verifier.h" 2781ad6265SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 2881ad6265SDimitry Andric #include "llvm/Support/SourceMgr.h" 290b57cec5SDimitry Andric #include "llvm/Transforms/Scalar/DCE.h" 30bdd1243dSDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h" 3106c3fb27SDimitry Andric #include <map> 32bdd1243dSDimitry Andric #include <optional> 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric using namespace llvm; 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric void IRMutationStrategy::mutate(Module &M, RandomIRBuilder &IB) { 370b57cec5SDimitry Andric auto RS = makeSampler<Function *>(IB.Rand); 380b57cec5SDimitry Andric for (Function &F : M) 390b57cec5SDimitry Andric if (!F.isDeclaration()) 400b57cec5SDimitry Andric RS.sample(&F, /*Weight=*/1); 4181ad6265SDimitry Andric 4206c3fb27SDimitry Andric while (RS.totalWeight() < IB.MinFunctionNum) { 4306c3fb27SDimitry Andric Function *F = IB.createFunctionDefinition(M); 4406c3fb27SDimitry Andric RS.sample(F, /*Weight=*/1); 4506c3fb27SDimitry Andric } 460b57cec5SDimitry Andric mutate(*RS.getSelection(), IB); 470b57cec5SDimitry Andric } 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric void IRMutationStrategy::mutate(Function &F, RandomIRBuilder &IB) { 5006c3fb27SDimitry Andric auto Range = make_filter_range(make_pointer_range(F), 5106c3fb27SDimitry Andric [](BasicBlock *BB) { return !BB->isEHPad(); }); 5206c3fb27SDimitry Andric 5306c3fb27SDimitry Andric mutate(*makeSampler(IB.Rand, Range).getSelection(), IB); 540b57cec5SDimitry Andric } 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric void IRMutationStrategy::mutate(BasicBlock &BB, RandomIRBuilder &IB) { 570b57cec5SDimitry Andric mutate(*makeSampler(IB.Rand, make_pointer_range(BB)).getSelection(), IB); 580b57cec5SDimitry Andric } 590b57cec5SDimitry Andric 6006c3fb27SDimitry Andric size_t llvm::IRMutator::getModuleSize(const Module &M) { 6106c3fb27SDimitry Andric return M.getInstructionCount() + M.size() + M.global_size() + M.alias_size(); 6206c3fb27SDimitry Andric } 6306c3fb27SDimitry Andric 6406c3fb27SDimitry Andric void IRMutator::mutateModule(Module &M, int Seed, size_t MaxSize) { 650b57cec5SDimitry Andric std::vector<Type *> Types; 660b57cec5SDimitry Andric for (const auto &Getter : AllowedTypes) 670b57cec5SDimitry Andric Types.push_back(Getter(M.getContext())); 680b57cec5SDimitry Andric RandomIRBuilder IB(Seed, Types); 690b57cec5SDimitry Andric 7006c3fb27SDimitry Andric size_t CurSize = IRMutator::getModuleSize(M); 710b57cec5SDimitry Andric auto RS = makeSampler<IRMutationStrategy *>(IB.Rand); 720b57cec5SDimitry Andric for (const auto &Strategy : Strategies) 730b57cec5SDimitry Andric RS.sample(Strategy.get(), 740b57cec5SDimitry Andric Strategy->getWeight(CurSize, MaxSize, RS.totalWeight())); 7506c3fb27SDimitry Andric if (RS.totalWeight() == 0) 7606c3fb27SDimitry Andric return; 770b57cec5SDimitry Andric auto Strategy = RS.getSelection(); 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric Strategy->mutate(M, IB); 800b57cec5SDimitry Andric } 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric static void eliminateDeadCode(Function &F) { 830b57cec5SDimitry Andric FunctionPassManager FPM; 840b57cec5SDimitry Andric FPM.addPass(DCEPass()); 850b57cec5SDimitry Andric FunctionAnalysisManager FAM; 860b57cec5SDimitry Andric FAM.registerPass([&] { return TargetLibraryAnalysis(); }); 870b57cec5SDimitry Andric FAM.registerPass([&] { return PassInstrumentationAnalysis(); }); 880b57cec5SDimitry Andric FPM.run(F, FAM); 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric void InjectorIRStrategy::mutate(Function &F, RandomIRBuilder &IB) { 920b57cec5SDimitry Andric IRMutationStrategy::mutate(F, IB); 930b57cec5SDimitry Andric eliminateDeadCode(F); 940b57cec5SDimitry Andric } 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric std::vector<fuzzerop::OpDescriptor> InjectorIRStrategy::getDefaultOps() { 970b57cec5SDimitry Andric std::vector<fuzzerop::OpDescriptor> Ops; 980b57cec5SDimitry Andric describeFuzzerIntOps(Ops); 990b57cec5SDimitry Andric describeFuzzerFloatOps(Ops); 1000b57cec5SDimitry Andric describeFuzzerControlFlowOps(Ops); 1010b57cec5SDimitry Andric describeFuzzerPointerOps(Ops); 1020b57cec5SDimitry Andric describeFuzzerAggregateOps(Ops); 1030b57cec5SDimitry Andric describeFuzzerVectorOps(Ops); 1040b57cec5SDimitry Andric return Ops; 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric 107bdd1243dSDimitry Andric std::optional<fuzzerop::OpDescriptor> 1080b57cec5SDimitry Andric InjectorIRStrategy::chooseOperation(Value *Src, RandomIRBuilder &IB) { 1090b57cec5SDimitry Andric auto OpMatchesPred = [&Src](fuzzerop::OpDescriptor &Op) { 1100b57cec5SDimitry Andric return Op.SourcePreds[0].matches({}, Src); 1110b57cec5SDimitry Andric }; 1120b57cec5SDimitry Andric auto RS = makeSampler(IB.Rand, make_filter_range(Operations, OpMatchesPred)); 1130b57cec5SDimitry Andric if (RS.isEmpty()) 114bdd1243dSDimitry Andric return std::nullopt; 1150b57cec5SDimitry Andric return *RS; 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric 11806c3fb27SDimitry Andric static inline iterator_range<BasicBlock::iterator> 11906c3fb27SDimitry Andric getInsertionRange(BasicBlock &BB) { 12006c3fb27SDimitry Andric auto End = BB.getTerminatingMustTailCall() ? std::prev(BB.end()) : BB.end(); 12106c3fb27SDimitry Andric return make_range(BB.getFirstInsertionPt(), End); 12206c3fb27SDimitry Andric } 12306c3fb27SDimitry Andric 1240b57cec5SDimitry Andric void InjectorIRStrategy::mutate(BasicBlock &BB, RandomIRBuilder &IB) { 1250b57cec5SDimitry Andric SmallVector<Instruction *, 32> Insts; 12606c3fb27SDimitry Andric for (Instruction &I : getInsertionRange(BB)) 12706c3fb27SDimitry Andric Insts.push_back(&I); 1280b57cec5SDimitry Andric if (Insts.size() < 1) 1290b57cec5SDimitry Andric return; 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric // Choose an insertion point for our new instruction. 1320b57cec5SDimitry Andric size_t IP = uniform<size_t>(IB.Rand, 0, Insts.size() - 1); 1330b57cec5SDimitry Andric 134bdd1243dSDimitry Andric auto InstsBefore = ArrayRef(Insts).slice(0, IP); 135bdd1243dSDimitry Andric auto InstsAfter = ArrayRef(Insts).slice(IP); 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric // Choose a source, which will be used to constrain the operation selection. 1380b57cec5SDimitry Andric SmallVector<Value *, 2> Srcs; 1390b57cec5SDimitry Andric Srcs.push_back(IB.findOrCreateSource(BB, InstsBefore)); 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric // Choose an operation that's constrained to be valid for the type of the 1420b57cec5SDimitry Andric // source, collect any other sources it needs, and then build it. 1430b57cec5SDimitry Andric auto OpDesc = chooseOperation(Srcs[0], IB); 1440b57cec5SDimitry Andric // Bail if no operation was found 1450b57cec5SDimitry Andric if (!OpDesc) 1460b57cec5SDimitry Andric return; 1470b57cec5SDimitry Andric 148bdd1243dSDimitry Andric for (const auto &Pred : ArrayRef(OpDesc->SourcePreds).slice(1)) 1490b57cec5SDimitry Andric Srcs.push_back(IB.findOrCreateSource(BB, InstsBefore, Srcs, Pred)); 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric if (Value *Op = OpDesc->BuilderFunc(Srcs, Insts[IP])) { 1520b57cec5SDimitry Andric // Find a sink and wire up the results of the operation. 1530b57cec5SDimitry Andric IB.connectToSink(BB, InstsAfter, Op); 1540b57cec5SDimitry Andric } 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric uint64_t InstDeleterIRStrategy::getWeight(size_t CurrentSize, size_t MaxSize, 1580b57cec5SDimitry Andric uint64_t CurrentWeight) { 1590b57cec5SDimitry Andric // If we have less than 200 bytes, panic and try to always delete. 1600b57cec5SDimitry Andric if (CurrentSize > MaxSize - 200) 1610b57cec5SDimitry Andric return CurrentWeight ? CurrentWeight * 100 : 1; 1620b57cec5SDimitry Andric // Draw a line starting from when we only have 1k left and increasing linearly 1630b57cec5SDimitry Andric // to double the current weight. 164fe6060f1SDimitry Andric int64_t Line = (-2 * static_cast<int64_t>(CurrentWeight)) * 165fe6060f1SDimitry Andric (static_cast<int64_t>(MaxSize) - 166fe6060f1SDimitry Andric static_cast<int64_t>(CurrentSize) - 1000) / 167fe6060f1SDimitry Andric 1000; 1680b57cec5SDimitry Andric // Clamp negative weights to zero. 1690b57cec5SDimitry Andric if (Line < 0) 1700b57cec5SDimitry Andric return 0; 1710b57cec5SDimitry Andric return Line; 1720b57cec5SDimitry Andric } 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric void InstDeleterIRStrategy::mutate(Function &F, RandomIRBuilder &IB) { 1750b57cec5SDimitry Andric auto RS = makeSampler<Instruction *>(IB.Rand); 1760b57cec5SDimitry Andric for (Instruction &Inst : instructions(F)) { 1770b57cec5SDimitry Andric // TODO: We can't handle these instructions. 178bdd1243dSDimitry Andric if (Inst.isTerminator() || Inst.isEHPad() || Inst.isSwiftError() || 179bdd1243dSDimitry Andric isa<PHINode>(Inst)) 1800b57cec5SDimitry Andric continue; 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric RS.sample(&Inst, /*Weight=*/1); 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric if (RS.isEmpty()) 1850b57cec5SDimitry Andric return; 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric // Delete the instruction. 1880b57cec5SDimitry Andric mutate(*RS.getSelection(), IB); 1890b57cec5SDimitry Andric // Clean up any dead code that's left over after removing the instruction. 1900b57cec5SDimitry Andric eliminateDeadCode(F); 1910b57cec5SDimitry Andric } 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric void InstDeleterIRStrategy::mutate(Instruction &Inst, RandomIRBuilder &IB) { 1940b57cec5SDimitry Andric assert(!Inst.isTerminator() && "Deleting terminators invalidates CFG"); 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric if (Inst.getType()->isVoidTy()) { 1970b57cec5SDimitry Andric // Instructions with void type (ie, store) have no uses to worry about. Just 1980b57cec5SDimitry Andric // erase it and move on. 1990b57cec5SDimitry Andric Inst.eraseFromParent(); 2000b57cec5SDimitry Andric return; 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric // Otherwise we need to find some other value with the right type to keep the 2040b57cec5SDimitry Andric // users happy. 2050b57cec5SDimitry Andric auto Pred = fuzzerop::onlyType(Inst.getType()); 2060b57cec5SDimitry Andric auto RS = makeSampler<Value *>(IB.Rand); 2070b57cec5SDimitry Andric SmallVector<Instruction *, 32> InstsBefore; 2080b57cec5SDimitry Andric BasicBlock *BB = Inst.getParent(); 2090b57cec5SDimitry Andric for (auto I = BB->getFirstInsertionPt(), E = Inst.getIterator(); I != E; 2100b57cec5SDimitry Andric ++I) { 2110b57cec5SDimitry Andric if (Pred.matches({}, &*I)) 2120b57cec5SDimitry Andric RS.sample(&*I, /*Weight=*/1); 2130b57cec5SDimitry Andric InstsBefore.push_back(&*I); 2140b57cec5SDimitry Andric } 2150b57cec5SDimitry Andric if (!RS) 2160b57cec5SDimitry Andric RS.sample(IB.newSource(*BB, InstsBefore, {}, Pred), /*Weight=*/1); 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric Inst.replaceAllUsesWith(RS.getSelection()); 2190b57cec5SDimitry Andric Inst.eraseFromParent(); 2200b57cec5SDimitry Andric } 221e8d8bef9SDimitry Andric 222e8d8bef9SDimitry Andric void InstModificationIRStrategy::mutate(Instruction &Inst, 223e8d8bef9SDimitry Andric RandomIRBuilder &IB) { 224e8d8bef9SDimitry Andric SmallVector<std::function<void()>, 8> Modifications; 225e8d8bef9SDimitry Andric CmpInst *CI = nullptr; 226e8d8bef9SDimitry Andric GetElementPtrInst *GEP = nullptr; 227e8d8bef9SDimitry Andric switch (Inst.getOpcode()) { 228e8d8bef9SDimitry Andric default: 229e8d8bef9SDimitry Andric break; 230bdd1243dSDimitry Andric // Add nsw, nuw flag 231e8d8bef9SDimitry Andric case Instruction::Add: 232e8d8bef9SDimitry Andric case Instruction::Mul: 233e8d8bef9SDimitry Andric case Instruction::Sub: 234e8d8bef9SDimitry Andric case Instruction::Shl: 235bdd1243dSDimitry Andric Modifications.push_back( 236bdd1243dSDimitry Andric [&Inst]() { Inst.setHasNoSignedWrap(!Inst.hasNoSignedWrap()); }); 237bdd1243dSDimitry Andric Modifications.push_back( 238bdd1243dSDimitry Andric [&Inst]() { Inst.setHasNoUnsignedWrap(!Inst.hasNoUnsignedWrap()); }); 239e8d8bef9SDimitry Andric break; 240e8d8bef9SDimitry Andric case Instruction::ICmp: 241e8d8bef9SDimitry Andric CI = cast<ICmpInst>(&Inst); 242bdd1243dSDimitry Andric for (unsigned p = CmpInst::FIRST_ICMP_PREDICATE; 243bdd1243dSDimitry Andric p <= CmpInst::LAST_ICMP_PREDICATE; p++) { 244bdd1243dSDimitry Andric Modifications.push_back( 245bdd1243dSDimitry Andric [CI, p]() { CI->setPredicate(static_cast<CmpInst::Predicate>(p)); }); 246bdd1243dSDimitry Andric } 247e8d8bef9SDimitry Andric break; 248bdd1243dSDimitry Andric // Add inbound flag. 249e8d8bef9SDimitry Andric case Instruction::GetElementPtr: 250e8d8bef9SDimitry Andric GEP = cast<GetElementPtrInst>(&Inst); 251bdd1243dSDimitry Andric Modifications.push_back( 252bdd1243dSDimitry Andric [GEP]() { GEP->setIsInBounds(!GEP->isInBounds()); }); 253e8d8bef9SDimitry Andric break; 254bdd1243dSDimitry Andric // Add exact flag. 255bdd1243dSDimitry Andric case Instruction::UDiv: 256bdd1243dSDimitry Andric case Instruction::SDiv: 257bdd1243dSDimitry Andric case Instruction::LShr: 258bdd1243dSDimitry Andric case Instruction::AShr: 259bdd1243dSDimitry Andric Modifications.push_back([&Inst] { Inst.setIsExact(!Inst.isExact()); }); 260bdd1243dSDimitry Andric break; 261bdd1243dSDimitry Andric 262bdd1243dSDimitry Andric case Instruction::FCmp: 26306c3fb27SDimitry Andric CI = cast<FCmpInst>(&Inst); 264bdd1243dSDimitry Andric for (unsigned p = CmpInst::FIRST_FCMP_PREDICATE; 265bdd1243dSDimitry Andric p <= CmpInst::LAST_FCMP_PREDICATE; p++) { 266bdd1243dSDimitry Andric Modifications.push_back( 267bdd1243dSDimitry Andric [CI, p]() { CI->setPredicate(static_cast<CmpInst::Predicate>(p)); }); 268bdd1243dSDimitry Andric } 269bdd1243dSDimitry Andric break; 270bdd1243dSDimitry Andric } 271bdd1243dSDimitry Andric 272bdd1243dSDimitry Andric // Add fast math flag if possible. 273bdd1243dSDimitry Andric if (isa<FPMathOperator>(&Inst)) { 274bdd1243dSDimitry Andric // Try setting everything unless they are already on. 275bdd1243dSDimitry Andric Modifications.push_back( 276bdd1243dSDimitry Andric [&Inst] { Inst.setFast(!Inst.getFastMathFlags().all()); }); 277bdd1243dSDimitry Andric // Try unsetting everything unless they are already off. 278bdd1243dSDimitry Andric Modifications.push_back( 279bdd1243dSDimitry Andric [&Inst] { Inst.setFast(!Inst.getFastMathFlags().none()); }); 280bdd1243dSDimitry Andric // Individual setting by flipping the bit 281bdd1243dSDimitry Andric Modifications.push_back( 282bdd1243dSDimitry Andric [&Inst] { Inst.setHasAllowReassoc(!Inst.hasAllowReassoc()); }); 283bdd1243dSDimitry Andric Modifications.push_back([&Inst] { Inst.setHasNoNaNs(!Inst.hasNoNaNs()); }); 284bdd1243dSDimitry Andric Modifications.push_back([&Inst] { Inst.setHasNoInfs(!Inst.hasNoInfs()); }); 285bdd1243dSDimitry Andric Modifications.push_back( 286bdd1243dSDimitry Andric [&Inst] { Inst.setHasNoSignedZeros(!Inst.hasNoSignedZeros()); }); 287bdd1243dSDimitry Andric Modifications.push_back( 288bdd1243dSDimitry Andric [&Inst] { Inst.setHasAllowReciprocal(!Inst.hasAllowReciprocal()); }); 289bdd1243dSDimitry Andric Modifications.push_back( 290bdd1243dSDimitry Andric [&Inst] { Inst.setHasAllowContract(!Inst.hasAllowContract()); }); 291bdd1243dSDimitry Andric Modifications.push_back( 292bdd1243dSDimitry Andric [&Inst] { Inst.setHasApproxFunc(!Inst.hasApproxFunc()); }); 293bdd1243dSDimitry Andric } 294bdd1243dSDimitry Andric 295bdd1243dSDimitry Andric // Randomly switch operands of instructions 296bdd1243dSDimitry Andric std::pair<int, int> NoneItem({-1, -1}), ShuffleItems(NoneItem); 297bdd1243dSDimitry Andric switch (Inst.getOpcode()) { 298bdd1243dSDimitry Andric case Instruction::SDiv: 299bdd1243dSDimitry Andric case Instruction::UDiv: 300bdd1243dSDimitry Andric case Instruction::SRem: 301bdd1243dSDimitry Andric case Instruction::URem: 302bdd1243dSDimitry Andric case Instruction::FDiv: 303bdd1243dSDimitry Andric case Instruction::FRem: { 304bdd1243dSDimitry Andric // Verify that the after shuffle the second operand is not 305bdd1243dSDimitry Andric // constant 0. 306bdd1243dSDimitry Andric Value *Operand = Inst.getOperand(0); 307bdd1243dSDimitry Andric if (Constant *C = dyn_cast<Constant>(Operand)) { 308bdd1243dSDimitry Andric if (!C->isZeroValue()) { 309bdd1243dSDimitry Andric ShuffleItems = {0, 1}; 310bdd1243dSDimitry Andric } 311bdd1243dSDimitry Andric } 312bdd1243dSDimitry Andric break; 313bdd1243dSDimitry Andric } 314bdd1243dSDimitry Andric case Instruction::Select: 315bdd1243dSDimitry Andric ShuffleItems = {1, 2}; 316bdd1243dSDimitry Andric break; 317bdd1243dSDimitry Andric case Instruction::Add: 318bdd1243dSDimitry Andric case Instruction::Sub: 319bdd1243dSDimitry Andric case Instruction::Mul: 320bdd1243dSDimitry Andric case Instruction::Shl: 321bdd1243dSDimitry Andric case Instruction::LShr: 322bdd1243dSDimitry Andric case Instruction::AShr: 323bdd1243dSDimitry Andric case Instruction::And: 324bdd1243dSDimitry Andric case Instruction::Or: 325bdd1243dSDimitry Andric case Instruction::Xor: 326bdd1243dSDimitry Andric case Instruction::FAdd: 327bdd1243dSDimitry Andric case Instruction::FSub: 328bdd1243dSDimitry Andric case Instruction::FMul: 329bdd1243dSDimitry Andric case Instruction::ICmp: 330bdd1243dSDimitry Andric case Instruction::FCmp: 331bdd1243dSDimitry Andric case Instruction::ShuffleVector: 332bdd1243dSDimitry Andric ShuffleItems = {0, 1}; 333bdd1243dSDimitry Andric break; 334bdd1243dSDimitry Andric } 335bdd1243dSDimitry Andric if (ShuffleItems != NoneItem) { 336bdd1243dSDimitry Andric Modifications.push_back([&Inst, &ShuffleItems]() { 337bdd1243dSDimitry Andric Value *Op0 = Inst.getOperand(ShuffleItems.first); 338bdd1243dSDimitry Andric Inst.setOperand(ShuffleItems.first, Inst.getOperand(ShuffleItems.second)); 339bdd1243dSDimitry Andric Inst.setOperand(ShuffleItems.second, Op0); 340bdd1243dSDimitry Andric }); 341e8d8bef9SDimitry Andric } 342e8d8bef9SDimitry Andric 343e8d8bef9SDimitry Andric auto RS = makeSampler(IB.Rand, Modifications); 344e8d8bef9SDimitry Andric if (RS) 345e8d8bef9SDimitry Andric RS.getSelection()(); 346e8d8bef9SDimitry Andric } 34781ad6265SDimitry Andric 348bdd1243dSDimitry Andric /// Return a case value that is not already taken to make sure we don't have two 349bdd1243dSDimitry Andric /// cases with same value. 350bdd1243dSDimitry Andric static uint64_t getUniqueCaseValue(SmallSet<uint64_t, 4> &CasesTaken, 351bdd1243dSDimitry Andric uint64_t MaxValue, RandomIRBuilder &IB) { 352bdd1243dSDimitry Andric uint64_t tmp; 353bdd1243dSDimitry Andric do { 354bdd1243dSDimitry Andric tmp = uniform<uint64_t>(IB.Rand, 0, MaxValue); 355bdd1243dSDimitry Andric } while (CasesTaken.count(tmp) != 0); 356bdd1243dSDimitry Andric CasesTaken.insert(tmp); 357bdd1243dSDimitry Andric return tmp; 358bdd1243dSDimitry Andric } 359bdd1243dSDimitry Andric 36006c3fb27SDimitry Andric void InsertFunctionStrategy::mutate(BasicBlock &BB, RandomIRBuilder &IB) { 36106c3fb27SDimitry Andric Module *M = BB.getParent()->getParent(); 36206c3fb27SDimitry Andric // If nullptr is selected, we will create a new function declaration. 36306c3fb27SDimitry Andric SmallVector<Function *, 32> Functions({nullptr}); 36406c3fb27SDimitry Andric for (Function &F : M->functions()) { 36506c3fb27SDimitry Andric Functions.push_back(&F); 36606c3fb27SDimitry Andric } 36706c3fb27SDimitry Andric 36806c3fb27SDimitry Andric auto RS = makeSampler(IB.Rand, Functions); 36906c3fb27SDimitry Andric Function *F = RS.getSelection(); 37006c3fb27SDimitry Andric // Some functions accept metadata type or token type as arguments. 37106c3fb27SDimitry Andric // We don't call those functions for now. 37206c3fb27SDimitry Andric // For example, `@llvm.dbg.declare(metadata, metadata, metadata)` 37306c3fb27SDimitry Andric // https://llvm.org/docs/SourceLevelDebugging.html#llvm-dbg-declare 37406c3fb27SDimitry Andric auto IsUnsupportedTy = [](Type *T) { 37506c3fb27SDimitry Andric return T->isMetadataTy() || T->isTokenTy(); 37606c3fb27SDimitry Andric }; 37706c3fb27SDimitry Andric if (!F || IsUnsupportedTy(F->getReturnType()) || 37806c3fb27SDimitry Andric any_of(F->getFunctionType()->params(), IsUnsupportedTy)) { 37906c3fb27SDimitry Andric F = IB.createFunctionDeclaration(*M); 38006c3fb27SDimitry Andric } 38106c3fb27SDimitry Andric 38206c3fb27SDimitry Andric FunctionType *FTy = F->getFunctionType(); 38306c3fb27SDimitry Andric SmallVector<fuzzerop::SourcePred, 2> SourcePreds; 38406c3fb27SDimitry Andric if (!F->arg_empty()) { 38506c3fb27SDimitry Andric for (Type *ArgTy : FTy->params()) { 38606c3fb27SDimitry Andric SourcePreds.push_back(fuzzerop::onlyType(ArgTy)); 38706c3fb27SDimitry Andric } 38806c3fb27SDimitry Andric } 38906c3fb27SDimitry Andric bool isRetVoid = (F->getReturnType() == Type::getVoidTy(M->getContext())); 39006c3fb27SDimitry Andric auto BuilderFunc = [FTy, F, isRetVoid](ArrayRef<Value *> Srcs, 39106c3fb27SDimitry Andric Instruction *Inst) { 39206c3fb27SDimitry Andric StringRef Name = isRetVoid ? nullptr : "C"; 39306c3fb27SDimitry Andric CallInst *Call = CallInst::Create(FTy, F, Srcs, Name, Inst); 39406c3fb27SDimitry Andric // Don't return this call inst if it return void as it can't be sinked. 39506c3fb27SDimitry Andric return isRetVoid ? nullptr : Call; 39606c3fb27SDimitry Andric }; 39706c3fb27SDimitry Andric 39806c3fb27SDimitry Andric SmallVector<Instruction *, 32> Insts; 39906c3fb27SDimitry Andric for (Instruction &I : getInsertionRange(BB)) 40006c3fb27SDimitry Andric Insts.push_back(&I); 40106c3fb27SDimitry Andric if (Insts.size() < 1) 40206c3fb27SDimitry Andric return; 40306c3fb27SDimitry Andric 40406c3fb27SDimitry Andric // Choose an insertion point for our new call instruction. 40506c3fb27SDimitry Andric uint64_t IP = uniform<uint64_t>(IB.Rand, 0, Insts.size() - 1); 40606c3fb27SDimitry Andric 40706c3fb27SDimitry Andric auto InstsBefore = ArrayRef(Insts).slice(0, IP); 40806c3fb27SDimitry Andric auto InstsAfter = ArrayRef(Insts).slice(IP); 40906c3fb27SDimitry Andric 41006c3fb27SDimitry Andric // Choose a source, which will be used to constrain the operation selection. 41106c3fb27SDimitry Andric SmallVector<Value *, 2> Srcs; 41206c3fb27SDimitry Andric 41306c3fb27SDimitry Andric for (const auto &Pred : ArrayRef(SourcePreds)) { 41406c3fb27SDimitry Andric Srcs.push_back(IB.findOrCreateSource(BB, InstsBefore, Srcs, Pred)); 41506c3fb27SDimitry Andric } 41606c3fb27SDimitry Andric 41706c3fb27SDimitry Andric if (Value *Op = BuilderFunc(Srcs, Insts[IP])) { 41806c3fb27SDimitry Andric // Find a sink and wire up the results of the operation. 41906c3fb27SDimitry Andric IB.connectToSink(BB, InstsAfter, Op); 42006c3fb27SDimitry Andric } 42106c3fb27SDimitry Andric } 42206c3fb27SDimitry Andric 423bdd1243dSDimitry Andric void InsertCFGStrategy::mutate(BasicBlock &BB, RandomIRBuilder &IB) { 424bdd1243dSDimitry Andric SmallVector<Instruction *, 32> Insts; 42506c3fb27SDimitry Andric for (Instruction &I : getInsertionRange(BB)) 42606c3fb27SDimitry Andric Insts.push_back(&I); 427bdd1243dSDimitry Andric if (Insts.size() < 1) 428bdd1243dSDimitry Andric return; 429bdd1243dSDimitry Andric 430bdd1243dSDimitry Andric // Choose a point where we split the block. 431bdd1243dSDimitry Andric uint64_t IP = uniform<uint64_t>(IB.Rand, 0, Insts.size() - 1); 432bdd1243dSDimitry Andric auto InstsBeforeSplit = ArrayRef(Insts).slice(0, IP); 433bdd1243dSDimitry Andric 434bdd1243dSDimitry Andric // `Sink` inherits Blocks' terminator, `Source` will have a BranchInst 435bdd1243dSDimitry Andric // directly jumps to `Sink`. Here, we have to create a new terminator for 436bdd1243dSDimitry Andric // `Source`. 437bdd1243dSDimitry Andric BasicBlock *Block = Insts[IP]->getParent(); 438bdd1243dSDimitry Andric BasicBlock *Source = Block; 439bdd1243dSDimitry Andric BasicBlock *Sink = Block->splitBasicBlock(Insts[IP], "BB"); 440bdd1243dSDimitry Andric 441bdd1243dSDimitry Andric Function *F = BB.getParent(); 442bdd1243dSDimitry Andric LLVMContext &C = F->getParent()->getContext(); 443bdd1243dSDimitry Andric // A coin decides if it is branch or switch 444bdd1243dSDimitry Andric if (uniform<uint64_t>(IB.Rand, 0, 1)) { 445bdd1243dSDimitry Andric // Branch 446bdd1243dSDimitry Andric BasicBlock *IfTrue = BasicBlock::Create(C, "T", F); 447bdd1243dSDimitry Andric BasicBlock *IfFalse = BasicBlock::Create(C, "F", F); 448bdd1243dSDimitry Andric Value *Cond = 449bdd1243dSDimitry Andric IB.findOrCreateSource(*Source, InstsBeforeSplit, {}, 450bdd1243dSDimitry Andric fuzzerop::onlyType(Type::getInt1Ty(C)), false); 451bdd1243dSDimitry Andric BranchInst *Branch = BranchInst::Create(IfTrue, IfFalse, Cond); 452bdd1243dSDimitry Andric // Remove the old terminator. 453bdd1243dSDimitry Andric ReplaceInstWithInst(Source->getTerminator(), Branch); 454bdd1243dSDimitry Andric // Connect these blocks to `Sink` 455bdd1243dSDimitry Andric connectBlocksToSink({IfTrue, IfFalse}, Sink, IB); 456bdd1243dSDimitry Andric } else { 457bdd1243dSDimitry Andric // Switch 458bdd1243dSDimitry Andric // Determine Integer type, it IS possible we use a boolean to switch. 459bdd1243dSDimitry Andric auto RS = 460bdd1243dSDimitry Andric makeSampler(IB.Rand, make_filter_range(IB.KnownTypes, [](Type *Ty) { 461bdd1243dSDimitry Andric return Ty->isIntegerTy(); 462bdd1243dSDimitry Andric })); 463bdd1243dSDimitry Andric assert(RS && "There is no integer type in all allowed types, is the " 464bdd1243dSDimitry Andric "setting correct?"); 465bdd1243dSDimitry Andric Type *Ty = RS.getSelection(); 466bdd1243dSDimitry Andric IntegerType *IntTy = cast<IntegerType>(Ty); 467bdd1243dSDimitry Andric 468bdd1243dSDimitry Andric uint64_t BitSize = IntTy->getBitWidth(); 469bdd1243dSDimitry Andric uint64_t MaxCaseVal = 470bdd1243dSDimitry Andric (BitSize >= 64) ? (uint64_t)-1 : ((uint64_t)1 << BitSize) - 1; 471bdd1243dSDimitry Andric // Create Switch inst in Block 472bdd1243dSDimitry Andric Value *Cond = IB.findOrCreateSource(*Source, InstsBeforeSplit, {}, 473bdd1243dSDimitry Andric fuzzerop::onlyType(IntTy), false); 474bdd1243dSDimitry Andric BasicBlock *DefaultBlock = BasicBlock::Create(C, "SW_D", F); 475bdd1243dSDimitry Andric uint64_t NumCases = uniform<uint64_t>(IB.Rand, 1, MaxNumCases); 476bdd1243dSDimitry Andric NumCases = (NumCases > MaxCaseVal) ? MaxCaseVal + 1 : NumCases; 477bdd1243dSDimitry Andric SwitchInst *Switch = SwitchInst::Create(Cond, DefaultBlock, NumCases); 478bdd1243dSDimitry Andric // Remove the old terminator. 479bdd1243dSDimitry Andric ReplaceInstWithInst(Source->getTerminator(), Switch); 480bdd1243dSDimitry Andric 481bdd1243dSDimitry Andric // Create blocks, for each block assign a case value. 482bdd1243dSDimitry Andric SmallVector<BasicBlock *, 4> Blocks({DefaultBlock}); 483bdd1243dSDimitry Andric SmallSet<uint64_t, 4> CasesTaken; 484bdd1243dSDimitry Andric for (uint64_t i = 0; i < NumCases; i++) { 485bdd1243dSDimitry Andric uint64_t CaseVal = getUniqueCaseValue(CasesTaken, MaxCaseVal, IB); 486bdd1243dSDimitry Andric BasicBlock *CaseBlock = BasicBlock::Create(C, "SW_C", F); 487bdd1243dSDimitry Andric ConstantInt *OnValue = ConstantInt::get(IntTy, CaseVal); 488bdd1243dSDimitry Andric Switch->addCase(OnValue, CaseBlock); 489bdd1243dSDimitry Andric Blocks.push_back(CaseBlock); 490bdd1243dSDimitry Andric } 491bdd1243dSDimitry Andric 492bdd1243dSDimitry Andric // Connect these blocks to `Sink` 493bdd1243dSDimitry Andric connectBlocksToSink(Blocks, Sink, IB); 494bdd1243dSDimitry Andric } 495bdd1243dSDimitry Andric } 496bdd1243dSDimitry Andric 497bdd1243dSDimitry Andric /// The caller has to guarantee that these blocks are "empty", i.e. it doesn't 498bdd1243dSDimitry Andric /// even have terminator. 499bdd1243dSDimitry Andric void InsertCFGStrategy::connectBlocksToSink(ArrayRef<BasicBlock *> Blocks, 500bdd1243dSDimitry Andric BasicBlock *Sink, 501bdd1243dSDimitry Andric RandomIRBuilder &IB) { 502bdd1243dSDimitry Andric uint64_t DirectSinkIdx = uniform<uint64_t>(IB.Rand, 0, Blocks.size() - 1); 503bdd1243dSDimitry Andric for (uint64_t i = 0; i < Blocks.size(); i++) { 504bdd1243dSDimitry Andric // We have at least one block that directly goes to sink. 505bdd1243dSDimitry Andric CFGToSink ToSink = (i == DirectSinkIdx) 506bdd1243dSDimitry Andric ? CFGToSink::DirectSink 507bdd1243dSDimitry Andric : static_cast<CFGToSink>(uniform<uint64_t>( 508bdd1243dSDimitry Andric IB.Rand, 0, CFGToSink::EndOfCFGToLink - 1)); 509bdd1243dSDimitry Andric BasicBlock *BB = Blocks[i]; 510bdd1243dSDimitry Andric Function *F = BB->getParent(); 511bdd1243dSDimitry Andric LLVMContext &C = F->getParent()->getContext(); 512bdd1243dSDimitry Andric switch (ToSink) { 513bdd1243dSDimitry Andric case CFGToSink::Return: { 514bdd1243dSDimitry Andric Type *RetTy = F->getReturnType(); 515bdd1243dSDimitry Andric Value *RetValue = nullptr; 516bdd1243dSDimitry Andric if (!RetTy->isVoidTy()) 517bdd1243dSDimitry Andric RetValue = 518bdd1243dSDimitry Andric IB.findOrCreateSource(*BB, {}, {}, fuzzerop::onlyType(RetTy)); 519bdd1243dSDimitry Andric ReturnInst::Create(C, RetValue, BB); 520bdd1243dSDimitry Andric break; 521bdd1243dSDimitry Andric } 522bdd1243dSDimitry Andric case CFGToSink::DirectSink: { 523bdd1243dSDimitry Andric BranchInst::Create(Sink, BB); 524bdd1243dSDimitry Andric break; 525bdd1243dSDimitry Andric } 526bdd1243dSDimitry Andric case CFGToSink::SinkOrSelfLoop: { 527bdd1243dSDimitry Andric SmallVector<BasicBlock *, 2> Branches({Sink, BB}); 528bdd1243dSDimitry Andric // A coin decides which block is true branch. 529bdd1243dSDimitry Andric uint64_t coin = uniform<uint64_t>(IB.Rand, 0, 1); 530bdd1243dSDimitry Andric Value *Cond = IB.findOrCreateSource( 531bdd1243dSDimitry Andric *BB, {}, {}, fuzzerop::onlyType(Type::getInt1Ty(C)), false); 532bdd1243dSDimitry Andric BranchInst::Create(Branches[coin], Branches[1 - coin], Cond, BB); 533bdd1243dSDimitry Andric break; 534bdd1243dSDimitry Andric } 535bdd1243dSDimitry Andric case CFGToSink::EndOfCFGToLink: 536bdd1243dSDimitry Andric llvm_unreachable("EndOfCFGToLink executed, something's wrong."); 537bdd1243dSDimitry Andric } 538bdd1243dSDimitry Andric } 539bdd1243dSDimitry Andric } 540bdd1243dSDimitry Andric 541bdd1243dSDimitry Andric void InsertPHIStrategy::mutate(BasicBlock &BB, RandomIRBuilder &IB) { 542bdd1243dSDimitry Andric // Can't insert PHI node to entry node. 543bdd1243dSDimitry Andric if (&BB == &BB.getParent()->getEntryBlock()) 544bdd1243dSDimitry Andric return; 545bdd1243dSDimitry Andric Type *Ty = IB.randomType(); 546bdd1243dSDimitry Andric PHINode *PHI = PHINode::Create(Ty, llvm::pred_size(&BB), "", &BB.front()); 547bdd1243dSDimitry Andric 548bdd1243dSDimitry Andric // Use a map to make sure the same incoming basic block has the same value. 549bdd1243dSDimitry Andric DenseMap<BasicBlock *, Value *> IncomingValues; 550bdd1243dSDimitry Andric for (BasicBlock *Pred : predecessors(&BB)) { 551bdd1243dSDimitry Andric Value *Src = IncomingValues[Pred]; 552bdd1243dSDimitry Andric // If `Pred` is not in the map yet, we'll get a nullptr. 553bdd1243dSDimitry Andric if (!Src) { 554bdd1243dSDimitry Andric SmallVector<Instruction *, 32> Insts; 555bdd1243dSDimitry Andric for (auto I = Pred->begin(); I != Pred->end(); ++I) 556bdd1243dSDimitry Andric Insts.push_back(&*I); 557bdd1243dSDimitry Andric // There is no need to inform IB what previously used values are if we are 558bdd1243dSDimitry Andric // using `onlyType` 559bdd1243dSDimitry Andric Src = IB.findOrCreateSource(*Pred, Insts, {}, fuzzerop::onlyType(Ty)); 560bdd1243dSDimitry Andric IncomingValues[Pred] = Src; 561bdd1243dSDimitry Andric } 562bdd1243dSDimitry Andric PHI->addIncoming(Src, Pred); 563bdd1243dSDimitry Andric } 564bdd1243dSDimitry Andric SmallVector<Instruction *, 32> InstsAfter; 56506c3fb27SDimitry Andric for (Instruction &I : getInsertionRange(BB)) 56606c3fb27SDimitry Andric InstsAfter.push_back(&I); 567bdd1243dSDimitry Andric IB.connectToSink(BB, InstsAfter, PHI); 568bdd1243dSDimitry Andric } 569bdd1243dSDimitry Andric 570bdd1243dSDimitry Andric void SinkInstructionStrategy::mutate(Function &F, RandomIRBuilder &IB) { 571bdd1243dSDimitry Andric for (BasicBlock &BB : F) { 572bdd1243dSDimitry Andric this->mutate(BB, IB); 573bdd1243dSDimitry Andric } 574bdd1243dSDimitry Andric } 575bdd1243dSDimitry Andric void SinkInstructionStrategy::mutate(BasicBlock &BB, RandomIRBuilder &IB) { 576bdd1243dSDimitry Andric SmallVector<Instruction *, 32> Insts; 57706c3fb27SDimitry Andric for (Instruction &I : getInsertionRange(BB)) 57806c3fb27SDimitry Andric Insts.push_back(&I); 579bdd1243dSDimitry Andric if (Insts.size() < 1) 580bdd1243dSDimitry Andric return; 581bdd1243dSDimitry Andric // Choose an Instruction to mutate. 582bdd1243dSDimitry Andric uint64_t Idx = uniform<uint64_t>(IB.Rand, 0, Insts.size() - 1); 583bdd1243dSDimitry Andric Instruction *Inst = Insts[Idx]; 584bdd1243dSDimitry Andric // `Idx + 1` so we don't sink to ourselves. 585bdd1243dSDimitry Andric auto InstsAfter = ArrayRef(Insts).slice(Idx + 1); 58606c3fb27SDimitry Andric Type *Ty = Inst->getType(); 58706c3fb27SDimitry Andric // Don't sink terminators, void function calls, token, etc. 58806c3fb27SDimitry Andric if (!Ty->isVoidTy() && !Ty->isTokenTy()) 589bdd1243dSDimitry Andric // Find a new sink and wire up the results of the operation. 590bdd1243dSDimitry Andric IB.connectToSink(BB, InstsAfter, Inst); 591bdd1243dSDimitry Andric } 592bdd1243dSDimitry Andric 593bdd1243dSDimitry Andric void ShuffleBlockStrategy::mutate(BasicBlock &BB, RandomIRBuilder &IB) { 59406c3fb27SDimitry Andric // A deterministic alternative to SmallPtrSet with the same lookup 59506c3fb27SDimitry Andric // performance. 59606c3fb27SDimitry Andric std::map<size_t, Instruction *> AliveInsts; 59706c3fb27SDimitry Andric std::map<Instruction *, size_t> AliveInstsLookup; 59806c3fb27SDimitry Andric size_t InsertIdx = 0; 599bdd1243dSDimitry Andric for (auto &I : make_early_inc_range(make_range( 600bdd1243dSDimitry Andric BB.getFirstInsertionPt(), BB.getTerminator()->getIterator()))) { 601bdd1243dSDimitry Andric // First gather all instructions that can be shuffled. Don't take 602bdd1243dSDimitry Andric // terminator. 60306c3fb27SDimitry Andric AliveInsts.insert({InsertIdx, &I}); 60406c3fb27SDimitry Andric AliveInstsLookup.insert({&I, InsertIdx++}); 605bdd1243dSDimitry Andric // Then remove these instructions from the block 606bdd1243dSDimitry Andric I.removeFromParent(); 607bdd1243dSDimitry Andric } 608bdd1243dSDimitry Andric 609bdd1243dSDimitry Andric // Shuffle these instructions using topological sort. 61006c3fb27SDimitry Andric // Returns false if all current instruction's dependencies in this block have 611bdd1243dSDimitry Andric // been shuffled. If so, this instruction can be shuffled too. 61206c3fb27SDimitry Andric auto hasAliveParent = [&AliveInsts, &AliveInstsLookup](size_t Index) { 61306c3fb27SDimitry Andric for (Value *O : AliveInsts[Index]->operands()) { 614bdd1243dSDimitry Andric Instruction *P = dyn_cast<Instruction>(O); 61506c3fb27SDimitry Andric if (P && AliveInstsLookup.count(P)) 616bdd1243dSDimitry Andric return true; 617bdd1243dSDimitry Andric } 618bdd1243dSDimitry Andric return false; 619bdd1243dSDimitry Andric }; 620bdd1243dSDimitry Andric // Get all alive instructions that depend on the current instruction. 62106c3fb27SDimitry Andric // Takes Instruction* instead of index because the instruction is already 62206c3fb27SDimitry Andric // shuffled. 62306c3fb27SDimitry Andric auto getAliveChildren = [&AliveInstsLookup](Instruction *I) { 62406c3fb27SDimitry Andric SmallSetVector<size_t, 8> Children; 625bdd1243dSDimitry Andric for (Value *U : I->users()) { 626bdd1243dSDimitry Andric Instruction *P = dyn_cast<Instruction>(U); 62706c3fb27SDimitry Andric if (P && AliveInstsLookup.count(P)) 62806c3fb27SDimitry Andric Children.insert(AliveInstsLookup[P]); 629bdd1243dSDimitry Andric } 630bdd1243dSDimitry Andric return Children; 631bdd1243dSDimitry Andric }; 63206c3fb27SDimitry Andric SmallSet<size_t, 8> RootIndices; 633bdd1243dSDimitry Andric SmallVector<Instruction *, 8> Insts; 63406c3fb27SDimitry Andric for (const auto &[Index, Inst] : AliveInsts) { 63506c3fb27SDimitry Andric if (!hasAliveParent(Index)) 63606c3fb27SDimitry Andric RootIndices.insert(Index); 637bdd1243dSDimitry Andric } 638bdd1243dSDimitry Andric // Topological sort by randomly selecting a node without a parent, or root. 63906c3fb27SDimitry Andric while (!RootIndices.empty()) { 64006c3fb27SDimitry Andric auto RS = makeSampler<size_t>(IB.Rand); 64106c3fb27SDimitry Andric for (size_t RootIdx : RootIndices) 64206c3fb27SDimitry Andric RS.sample(RootIdx, 1); 64306c3fb27SDimitry Andric size_t RootIdx = RS.getSelection(); 64406c3fb27SDimitry Andric 64506c3fb27SDimitry Andric RootIndices.erase(RootIdx); 64606c3fb27SDimitry Andric Instruction *Root = AliveInsts[RootIdx]; 64706c3fb27SDimitry Andric AliveInsts.erase(RootIdx); 64806c3fb27SDimitry Andric AliveInstsLookup.erase(Root); 649bdd1243dSDimitry Andric Insts.push_back(Root); 65006c3fb27SDimitry Andric 65106c3fb27SDimitry Andric for (size_t Child : getAliveChildren(Root)) { 652bdd1243dSDimitry Andric if (!hasAliveParent(Child)) { 65306c3fb27SDimitry Andric RootIndices.insert(Child); 654bdd1243dSDimitry Andric } 655bdd1243dSDimitry Andric } 656bdd1243dSDimitry Andric } 657bdd1243dSDimitry Andric 658bdd1243dSDimitry Andric Instruction *Terminator = BB.getTerminator(); 659bdd1243dSDimitry Andric // Then put instructions back. 660bdd1243dSDimitry Andric for (Instruction *I : Insts) { 661bdd1243dSDimitry Andric I->insertBefore(Terminator); 662bdd1243dSDimitry Andric } 663bdd1243dSDimitry Andric } 664bdd1243dSDimitry Andric 66581ad6265SDimitry Andric std::unique_ptr<Module> llvm::parseModule(const uint8_t *Data, size_t Size, 66681ad6265SDimitry Andric LLVMContext &Context) { 66781ad6265SDimitry Andric 66881ad6265SDimitry Andric if (Size <= 1) 66981ad6265SDimitry Andric // We get bogus data given an empty corpus - just create a new module. 67081ad6265SDimitry Andric return std::make_unique<Module>("M", Context); 67181ad6265SDimitry Andric 67281ad6265SDimitry Andric auto Buffer = MemoryBuffer::getMemBuffer( 67381ad6265SDimitry Andric StringRef(reinterpret_cast<const char *>(Data), Size), "Fuzzer input", 67481ad6265SDimitry Andric /*RequiresNullTerminator=*/false); 67581ad6265SDimitry Andric 67681ad6265SDimitry Andric SMDiagnostic Err; 67781ad6265SDimitry Andric auto M = parseBitcodeFile(Buffer->getMemBufferRef(), Context); 67881ad6265SDimitry Andric if (Error E = M.takeError()) { 67981ad6265SDimitry Andric errs() << toString(std::move(E)) << "\n"; 68081ad6265SDimitry Andric return nullptr; 68181ad6265SDimitry Andric } 68281ad6265SDimitry Andric return std::move(M.get()); 68381ad6265SDimitry Andric } 68481ad6265SDimitry Andric 68581ad6265SDimitry Andric size_t llvm::writeModule(const Module &M, uint8_t *Dest, size_t MaxSize) { 68681ad6265SDimitry Andric std::string Buf; 68781ad6265SDimitry Andric { 68881ad6265SDimitry Andric raw_string_ostream OS(Buf); 68981ad6265SDimitry Andric WriteBitcodeToFile(M, OS); 69081ad6265SDimitry Andric } 69181ad6265SDimitry Andric if (Buf.size() > MaxSize) 69281ad6265SDimitry Andric return 0; 69381ad6265SDimitry Andric memcpy(Dest, Buf.data(), Buf.size()); 69481ad6265SDimitry Andric return Buf.size(); 69581ad6265SDimitry Andric } 69681ad6265SDimitry Andric 69781ad6265SDimitry Andric std::unique_ptr<Module> llvm::parseAndVerify(const uint8_t *Data, size_t Size, 69881ad6265SDimitry Andric LLVMContext &Context) { 69981ad6265SDimitry Andric auto M = parseModule(Data, Size, Context); 70081ad6265SDimitry Andric if (!M || verifyModule(*M, &errs())) 70181ad6265SDimitry Andric return nullptr; 70281ad6265SDimitry Andric 70381ad6265SDimitry Andric return M; 70481ad6265SDimitry Andric } 705