xref: /freebsd/contrib/llvm-project/llvm/lib/FuzzMutate/IRMutator.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
mutate(Module & M,RandomIRBuilder & IB)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 
mutate(Function & F,RandomIRBuilder & IB)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 
mutate(BasicBlock & BB,RandomIRBuilder & IB)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 
getModuleSize(const Module & M)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 
mutateModule(Module & M,int Seed,size_t MaxSize)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 
eliminateDeadCode(Function & F)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 
mutate(Function & F,RandomIRBuilder & IB)910b57cec5SDimitry Andric void InjectorIRStrategy::mutate(Function &F, RandomIRBuilder &IB) {
920b57cec5SDimitry Andric   IRMutationStrategy::mutate(F, IB);
930b57cec5SDimitry Andric   eliminateDeadCode(F);
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric 
getDefaultOps()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>
chooseOperation(Value * Src,RandomIRBuilder & IB)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>
getInsertionRange(BasicBlock & BB)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 
mutate(BasicBlock & BB,RandomIRBuilder & IB)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 
getWeight(size_t CurrentSize,size_t MaxSize,uint64_t CurrentWeight)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 
mutate(Function & F,RandomIRBuilder & IB)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 
mutate(Instruction & Inst,RandomIRBuilder & IB)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 
mutate(Instruction & Inst,RandomIRBuilder & IB)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.
getUniqueCaseValue(SmallSet<uint64_t,4> & CasesTaken,uint64_t MaxValue,RandomIRBuilder & IB)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 
mutate(BasicBlock & BB,RandomIRBuilder & IB)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 
mutate(BasicBlock & BB,RandomIRBuilder & IB)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.
connectBlocksToSink(ArrayRef<BasicBlock * > Blocks,BasicBlock * Sink,RandomIRBuilder & IB)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 
mutate(BasicBlock & BB,RandomIRBuilder & IB)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 
mutate(Function & F,RandomIRBuilder & IB)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 }
mutate(BasicBlock & BB,RandomIRBuilder & IB)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 
mutate(BasicBlock & BB,RandomIRBuilder & IB)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 
parseModule(const uint8_t * Data,size_t Size,LLVMContext & Context)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 
writeModule(const Module & M,uint8_t * Dest,size_t MaxSize)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 
parseAndVerify(const uint8_t * Data,size_t Size,LLVMContext & Context)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