LLVM 17.0.0git
IRMutator.cpp
Go to the documentation of this file.
1//===-- IRMutator.cpp -----------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "llvm/ADT/STLExtras.h"
11#include "llvm/ADT/SmallSet.h"
18#include "llvm/IR/BasicBlock.h"
19#include "llvm/IR/FMF.h"
20#include "llvm/IR/Function.h"
23#include "llvm/IR/Module.h"
24#include "llvm/IR/Operator.h"
25#include "llvm/IR/Verifier.h"
30#include <optional>
31
32using namespace llvm;
33
34static void createEmptyFunction(Module &M) {
35 // TODO: Some arguments and a return value would probably be more interesting.
36 LLVMContext &Context = M.getContext();
37 Function *F = Function::Create(FunctionType::get(Type::getVoidTy(Context), {},
38 /*isVarArg=*/false),
42}
43
45 auto RS = makeSampler<Function *>(IB.Rand);
46 for (Function &F : M)
47 if (!F.isDeclaration())
48 RS.sample(&F, /*Weight=*/1);
49
50 if (RS.isEmpty())
52 else
53 mutate(*RS.getSelection(), IB);
54}
55
57 mutate(*makeSampler(IB.Rand, make_pointer_range(F)).getSelection(), IB);
58}
59
61 mutate(*makeSampler(IB.Rand, make_pointer_range(BB)).getSelection(), IB);
62}
63
64void IRMutator::mutateModule(Module &M, int Seed, size_t CurSize,
65 size_t MaxSize) {
66 std::vector<Type *> Types;
67 for (const auto &Getter : AllowedTypes)
68 Types.push_back(Getter(M.getContext()));
69 RandomIRBuilder IB(Seed, Types);
70
71 auto RS = makeSampler<IRMutationStrategy *>(IB.Rand);
72 for (const auto &Strategy : Strategies)
73 RS.sample(Strategy.get(),
74 Strategy->getWeight(CurSize, MaxSize, RS.totalWeight()));
75 auto Strategy = RS.getSelection();
76
77 Strategy->mutate(M, IB);
78}
79
82 FPM.addPass(DCEPass());
84 FAM.registerPass([&] { return TargetLibraryAnalysis(); });
86 FPM.run(F, FAM);
87}
88
92}
93
94std::vector<fuzzerop::OpDescriptor> InjectorIRStrategy::getDefaultOps() {
95 std::vector<fuzzerop::OpDescriptor> Ops;
102 return Ops;
103}
104
105std::optional<fuzzerop::OpDescriptor>
106InjectorIRStrategy::chooseOperation(Value *Src, RandomIRBuilder &IB) {
107 auto OpMatchesPred = [&Src](fuzzerop::OpDescriptor &Op) {
108 return Op.SourcePreds[0].matches({}, Src);
109 };
110 auto RS = makeSampler(IB.Rand, make_filter_range(Operations, OpMatchesPred));
111 if (RS.isEmpty())
112 return std::nullopt;
113 return *RS;
114}
115
118 for (auto I = BB.getFirstInsertionPt(), E = BB.end(); I != E; ++I)
119 Insts.push_back(&*I);
120 if (Insts.size() < 1)
121 return;
122
123 // Choose an insertion point for our new instruction.
124 size_t IP = uniform<size_t>(IB.Rand, 0, Insts.size() - 1);
125
126 auto InstsBefore = ArrayRef(Insts).slice(0, IP);
127 auto InstsAfter = ArrayRef(Insts).slice(IP);
128
129 // Choose a source, which will be used to constrain the operation selection.
131 Srcs.push_back(IB.findOrCreateSource(BB, InstsBefore));
132
133 // Choose an operation that's constrained to be valid for the type of the
134 // source, collect any other sources it needs, and then build it.
135 auto OpDesc = chooseOperation(Srcs[0], IB);
136 // Bail if no operation was found
137 if (!OpDesc)
138 return;
139
140 for (const auto &Pred : ArrayRef(OpDesc->SourcePreds).slice(1))
141 Srcs.push_back(IB.findOrCreateSource(BB, InstsBefore, Srcs, Pred));
142
143 if (Value *Op = OpDesc->BuilderFunc(Srcs, Insts[IP])) {
144 // Find a sink and wire up the results of the operation.
145 IB.connectToSink(BB, InstsAfter, Op);
146 }
147}
148
149uint64_t InstDeleterIRStrategy::getWeight(size_t CurrentSize, size_t MaxSize,
150 uint64_t CurrentWeight) {
151 // If we have less than 200 bytes, panic and try to always delete.
152 if (CurrentSize > MaxSize - 200)
153 return CurrentWeight ? CurrentWeight * 100 : 1;
154 // Draw a line starting from when we only have 1k left and increasing linearly
155 // to double the current weight.
156 int64_t Line = (-2 * static_cast<int64_t>(CurrentWeight)) *
157 (static_cast<int64_t>(MaxSize) -
158 static_cast<int64_t>(CurrentSize) - 1000) /
159 1000;
160 // Clamp negative weights to zero.
161 if (Line < 0)
162 return 0;
163 return Line;
164}
165
167 auto RS = makeSampler<Instruction *>(IB.Rand);
168 for (Instruction &Inst : instructions(F)) {
169 // TODO: We can't handle these instructions.
170 if (Inst.isTerminator() || Inst.isEHPad() || Inst.isSwiftError() ||
171 isa<PHINode>(Inst))
172 continue;
173
174 RS.sample(&Inst, /*Weight=*/1);
175 }
176 if (RS.isEmpty())
177 return;
178
179 // Delete the instruction.
180 mutate(*RS.getSelection(), IB);
181 // Clean up any dead code that's left over after removing the instruction.
183}
184
186 assert(!Inst.isTerminator() && "Deleting terminators invalidates CFG");
187
188 if (Inst.getType()->isVoidTy()) {
189 // Instructions with void type (ie, store) have no uses to worry about. Just
190 // erase it and move on.
191 Inst.eraseFromParent();
192 return;
193 }
194
195 // Otherwise we need to find some other value with the right type to keep the
196 // users happy.
197 auto Pred = fuzzerop::onlyType(Inst.getType());
198 auto RS = makeSampler<Value *>(IB.Rand);
200 BasicBlock *BB = Inst.getParent();
201 for (auto I = BB->getFirstInsertionPt(), E = Inst.getIterator(); I != E;
202 ++I) {
203 if (Pred.matches({}, &*I))
204 RS.sample(&*I, /*Weight=*/1);
205 InstsBefore.push_back(&*I);
206 }
207 if (!RS)
208 RS.sample(IB.newSource(*BB, InstsBefore, {}, Pred), /*Weight=*/1);
209
210 Inst.replaceAllUsesWith(RS.getSelection());
211 Inst.eraseFromParent();
212}
213
215 RandomIRBuilder &IB) {
216 SmallVector<std::function<void()>, 8> Modifications;
217 CmpInst *CI = nullptr;
218 GetElementPtrInst *GEP = nullptr;
219 switch (Inst.getOpcode()) {
220 default:
221 break;
222 // Add nsw, nuw flag
223 case Instruction::Add:
224 case Instruction::Mul:
225 case Instruction::Sub:
226 case Instruction::Shl:
227 Modifications.push_back(
228 [&Inst]() { Inst.setHasNoSignedWrap(!Inst.hasNoSignedWrap()); });
229 Modifications.push_back(
230 [&Inst]() { Inst.setHasNoUnsignedWrap(!Inst.hasNoUnsignedWrap()); });
231 break;
232 case Instruction::ICmp:
233 CI = cast<ICmpInst>(&Inst);
234 for (unsigned p = CmpInst::FIRST_ICMP_PREDICATE;
236 Modifications.push_back(
237 [CI, p]() { CI->setPredicate(static_cast<CmpInst::Predicate>(p)); });
238 }
239 break;
240 // Add inbound flag.
241 case Instruction::GetElementPtr:
242 GEP = cast<GetElementPtrInst>(&Inst);
243 Modifications.push_back(
244 [GEP]() { GEP->setIsInBounds(!GEP->isInBounds()); });
245 break;
246 // Add exact flag.
247 case Instruction::UDiv:
248 case Instruction::SDiv:
249 case Instruction::LShr:
250 case Instruction::AShr:
251 Modifications.push_back([&Inst] { Inst.setIsExact(!Inst.isExact()); });
252 break;
253
254 case Instruction::FCmp:
255 CI = cast<ICmpInst>(&Inst);
256 for (unsigned p = CmpInst::FIRST_FCMP_PREDICATE;
258 Modifications.push_back(
259 [CI, p]() { CI->setPredicate(static_cast<CmpInst::Predicate>(p)); });
260 }
261 break;
262 }
263
264 // Add fast math flag if possible.
265 if (isa<FPMathOperator>(&Inst)) {
266 // Try setting everything unless they are already on.
267 Modifications.push_back(
268 [&Inst] { Inst.setFast(!Inst.getFastMathFlags().all()); });
269 // Try unsetting everything unless they are already off.
270 Modifications.push_back(
271 [&Inst] { Inst.setFast(!Inst.getFastMathFlags().none()); });
272 // Individual setting by flipping the bit
273 Modifications.push_back(
274 [&Inst] { Inst.setHasAllowReassoc(!Inst.hasAllowReassoc()); });
275 Modifications.push_back([&Inst] { Inst.setHasNoNaNs(!Inst.hasNoNaNs()); });
276 Modifications.push_back([&Inst] { Inst.setHasNoInfs(!Inst.hasNoInfs()); });
277 Modifications.push_back(
278 [&Inst] { Inst.setHasNoSignedZeros(!Inst.hasNoSignedZeros()); });
279 Modifications.push_back(
280 [&Inst] { Inst.setHasAllowReciprocal(!Inst.hasAllowReciprocal()); });
281 Modifications.push_back(
282 [&Inst] { Inst.setHasAllowContract(!Inst.hasAllowContract()); });
283 Modifications.push_back(
284 [&Inst] { Inst.setHasApproxFunc(!Inst.hasApproxFunc()); });
285 }
286
287 // Randomly switch operands of instructions
288 std::pair<int, int> NoneItem({-1, -1}), ShuffleItems(NoneItem);
289 switch (Inst.getOpcode()) {
290 case Instruction::SDiv:
291 case Instruction::UDiv:
292 case Instruction::SRem:
293 case Instruction::URem:
294 case Instruction::FDiv:
295 case Instruction::FRem: {
296 // Verify that the after shuffle the second operand is not
297 // constant 0.
298 Value *Operand = Inst.getOperand(0);
299 if (Constant *C = dyn_cast<Constant>(Operand)) {
300 if (!C->isZeroValue()) {
301 ShuffleItems = {0, 1};
302 }
303 }
304 break;
305 }
306 case Instruction::Select:
307 ShuffleItems = {1, 2};
308 break;
309 case Instruction::Add:
310 case Instruction::Sub:
311 case Instruction::Mul:
312 case Instruction::Shl:
313 case Instruction::LShr:
314 case Instruction::AShr:
315 case Instruction::And:
316 case Instruction::Or:
317 case Instruction::Xor:
318 case Instruction::FAdd:
319 case Instruction::FSub:
320 case Instruction::FMul:
321 case Instruction::ICmp:
322 case Instruction::FCmp:
323 case Instruction::ShuffleVector:
324 ShuffleItems = {0, 1};
325 break;
326 }
327 if (ShuffleItems != NoneItem) {
328 Modifications.push_back([&Inst, &ShuffleItems]() {
329 Value *Op0 = Inst.getOperand(ShuffleItems.first);
330 Inst.setOperand(ShuffleItems.first, Inst.getOperand(ShuffleItems.second));
331 Inst.setOperand(ShuffleItems.second, Op0);
332 });
333 }
334
335 auto RS = makeSampler(IB.Rand, Modifications);
336 if (RS)
337 RS.getSelection()();
338}
339
340/// Return a case value that is not already taken to make sure we don't have two
341/// cases with same value.
343 uint64_t MaxValue, RandomIRBuilder &IB) {
344 uint64_t tmp;
345 do {
346 tmp = uniform<uint64_t>(IB.Rand, 0, MaxValue);
347 } while (CasesTaken.count(tmp) != 0);
348 CasesTaken.insert(tmp);
349 return tmp;
350}
351
354 for (auto I = BB.getFirstInsertionPt(), E = BB.end(); I != E; ++I)
355 Insts.push_back(&*I);
356 if (Insts.size() < 1)
357 return;
358
359 // Choose a point where we split the block.
360 uint64_t IP = uniform<uint64_t>(IB.Rand, 0, Insts.size() - 1);
361 auto InstsBeforeSplit = ArrayRef(Insts).slice(0, IP);
362
363 // `Sink` inherits Blocks' terminator, `Source` will have a BranchInst
364 // directly jumps to `Sink`. Here, we have to create a new terminator for
365 // `Source`.
366 BasicBlock *Block = Insts[IP]->getParent();
367 BasicBlock *Source = Block;
368 BasicBlock *Sink = Block->splitBasicBlock(Insts[IP], "BB");
369
370 Function *F = BB.getParent();
371 LLVMContext &C = F->getParent()->getContext();
372 // A coin decides if it is branch or switch
373 if (uniform<uint64_t>(IB.Rand, 0, 1)) {
374 // Branch
375 BasicBlock *IfTrue = BasicBlock::Create(C, "T", F);
376 BasicBlock *IfFalse = BasicBlock::Create(C, "F", F);
377 Value *Cond =
378 IB.findOrCreateSource(*Source, InstsBeforeSplit, {},
380 BranchInst *Branch = BranchInst::Create(IfTrue, IfFalse, Cond);
381 // Remove the old terminator.
382 ReplaceInstWithInst(Source->getTerminator(), Branch);
383 // Connect these blocks to `Sink`
384 connectBlocksToSink({IfTrue, IfFalse}, Sink, IB);
385 } else {
386 // Switch
387 // Determine Integer type, it IS possible we use a boolean to switch.
388 auto RS =
389 makeSampler(IB.Rand, make_filter_range(IB.KnownTypes, [](Type *Ty) {
390 return Ty->isIntegerTy();
391 }));
392 assert(RS && "There is no integer type in all allowed types, is the "
393 "setting correct?");
394 Type *Ty = RS.getSelection();
395 IntegerType *IntTy = cast<IntegerType>(Ty);
396
397 uint64_t BitSize = IntTy->getBitWidth();
398 uint64_t MaxCaseVal =
399 (BitSize >= 64) ? (uint64_t)-1 : ((uint64_t)1 << BitSize) - 1;
400 // Create Switch inst in Block
401 Value *Cond = IB.findOrCreateSource(*Source, InstsBeforeSplit, {},
402 fuzzerop::onlyType(IntTy), false);
403 BasicBlock *DefaultBlock = BasicBlock::Create(C, "SW_D", F);
404 uint64_t NumCases = uniform<uint64_t>(IB.Rand, 1, MaxNumCases);
405 NumCases = (NumCases > MaxCaseVal) ? MaxCaseVal + 1 : NumCases;
406 SwitchInst *Switch = SwitchInst::Create(Cond, DefaultBlock, NumCases);
407 // Remove the old terminator.
408 ReplaceInstWithInst(Source->getTerminator(), Switch);
409
410 // Create blocks, for each block assign a case value.
411 SmallVector<BasicBlock *, 4> Blocks({DefaultBlock});
412 SmallSet<uint64_t, 4> CasesTaken;
413 for (uint64_t i = 0; i < NumCases; i++) {
414 uint64_t CaseVal = getUniqueCaseValue(CasesTaken, MaxCaseVal, IB);
415 BasicBlock *CaseBlock = BasicBlock::Create(C, "SW_C", F);
416 ConstantInt *OnValue = ConstantInt::get(IntTy, CaseVal);
417 Switch->addCase(OnValue, CaseBlock);
418 Blocks.push_back(CaseBlock);
419 }
420
421 // Connect these blocks to `Sink`
422 connectBlocksToSink(Blocks, Sink, IB);
423 }
424}
425
426/// The caller has to guarantee that these blocks are "empty", i.e. it doesn't
427/// even have terminator.
428void InsertCFGStrategy::connectBlocksToSink(ArrayRef<BasicBlock *> Blocks,
429 BasicBlock *Sink,
430 RandomIRBuilder &IB) {
431 uint64_t DirectSinkIdx = uniform<uint64_t>(IB.Rand, 0, Blocks.size() - 1);
432 for (uint64_t i = 0; i < Blocks.size(); i++) {
433 // We have at least one block that directly goes to sink.
434 CFGToSink ToSink = (i == DirectSinkIdx)
435 ? CFGToSink::DirectSink
436 : static_cast<CFGToSink>(uniform<uint64_t>(
437 IB.Rand, 0, CFGToSink::EndOfCFGToLink - 1));
438 BasicBlock *BB = Blocks[i];
439 Function *F = BB->getParent();
440 LLVMContext &C = F->getParent()->getContext();
441 switch (ToSink) {
442 case CFGToSink::Return: {
443 Type *RetTy = F->getReturnType();
444 Value *RetValue = nullptr;
445 if (!RetTy->isVoidTy())
446 RetValue =
447 IB.findOrCreateSource(*BB, {}, {}, fuzzerop::onlyType(RetTy));
448 ReturnInst::Create(C, RetValue, BB);
449 break;
450 }
451 case CFGToSink::DirectSink: {
452 BranchInst::Create(Sink, BB);
453 break;
454 }
455 case CFGToSink::SinkOrSelfLoop: {
456 SmallVector<BasicBlock *, 2> Branches({Sink, BB});
457 // A coin decides which block is true branch.
458 uint64_t coin = uniform<uint64_t>(IB.Rand, 0, 1);
459 Value *Cond = IB.findOrCreateSource(
460 *BB, {}, {}, fuzzerop::onlyType(Type::getInt1Ty(C)), false);
461 BranchInst::Create(Branches[coin], Branches[1 - coin], Cond, BB);
462 break;
463 }
464 case CFGToSink::EndOfCFGToLink:
465 llvm_unreachable("EndOfCFGToLink executed, something's wrong.");
466 }
467 }
468}
469
471 // Can't insert PHI node to entry node.
472 if (&BB == &BB.getParent()->getEntryBlock())
473 return;
474 Type *Ty = IB.randomType();
475 PHINode *PHI = PHINode::Create(Ty, llvm::pred_size(&BB), "", &BB.front());
476
477 // Use a map to make sure the same incoming basic block has the same value.
478 DenseMap<BasicBlock *, Value *> IncomingValues;
479 for (BasicBlock *Pred : predecessors(&BB)) {
480 Value *Src = IncomingValues[Pred];
481 // If `Pred` is not in the map yet, we'll get a nullptr.
482 if (!Src) {
484 for (auto I = Pred->begin(); I != Pred->end(); ++I)
485 Insts.push_back(&*I);
486 // There is no need to inform IB what previously used values are if we are
487 // using `onlyType`
488 Src = IB.findOrCreateSource(*Pred, Insts, {}, fuzzerop::onlyType(Ty));
489 IncomingValues[Pred] = Src;
490 }
491 PHI->addIncoming(Src, Pred);
492 }
494 for (auto I = BB.getFirstInsertionPt(), E = BB.end(); I != E; ++I)
495 InstsAfter.push_back(&*I);
496 IB.connectToSink(BB, InstsAfter, PHI);
497}
498
500 for (BasicBlock &BB : F) {
501 this->mutate(BB, IB);
502 }
503}
506 for (auto I = BB.getFirstInsertionPt(), E = BB.end(); I != E; ++I)
507 Insts.push_back(&*I);
508 if (Insts.size() < 1)
509 return;
510 // Choose an Instruction to mutate.
511 uint64_t Idx = uniform<uint64_t>(IB.Rand, 0, Insts.size() - 1);
512 Instruction *Inst = Insts[Idx];
513 // `Idx + 1` so we don't sink to ourselves.
514 auto InstsAfter = ArrayRef(Insts).slice(Idx + 1);
516 // Don't sink terminators, void function calls, etc.
517 if (Inst->getType() != Type::getVoidTy(C))
518 // Find a new sink and wire up the results of the operation.
519 IB.connectToSink(BB, InstsAfter, Inst);
520}
521
523
525 for (auto &I : make_early_inc_range(make_range(
527 // First gather all instructions that can be shuffled. Don't take
528 // terminator.
529 AliveInsts.insert(&I);
530 // Then remove these instructions from the block
531 I.removeFromParent();
532 }
533
534 // Shuffle these instructions using topological sort.
535 // Returns true if all current instruction's dependencies in this block have
536 // been shuffled. If so, this instruction can be shuffled too.
537 auto hasAliveParent = [&AliveInsts](Instruction *I) {
538 for (Value *O : I->operands()) {
539 Instruction *P = dyn_cast<Instruction>(O);
540 if (P && AliveInsts.count(P))
541 return true;
542 }
543 return false;
544 };
545 // Get all alive instructions that depend on the current instruction.
546 auto getAliveChildren = [&AliveInsts](Instruction *I) {
548 for (Value *U : I->users()) {
549 Instruction *P = dyn_cast<Instruction>(U);
550 if (P && AliveInsts.count(P))
551 Children.insert(P);
552 }
553 return Children;
554 };
557 for (Instruction *I : AliveInsts) {
558 if (!hasAliveParent(I))
559 Roots.insert(I);
560 }
561 // Topological sort by randomly selecting a node without a parent, or root.
562 while (!Roots.empty()) {
563 auto RS = makeSampler<Instruction *>(IB.Rand);
564 for (Instruction *Root : Roots)
565 RS.sample(Root, 1);
566 Instruction *Root = RS.getSelection();
567 Roots.erase(Root);
568 AliveInsts.erase(Root);
569 Insts.push_back(Root);
570 for (Instruction *Child : getAliveChildren(Root)) {
571 if (!hasAliveParent(Child)) {
572 Roots.insert(Child);
573 }
574 }
575 }
576
577 Instruction *Terminator = BB.getTerminator();
578 // Then put instructions back.
579 for (Instruction *I : Insts) {
580 I->insertBefore(Terminator);
581 }
582}
583
584std::unique_ptr<Module> llvm::parseModule(const uint8_t *Data, size_t Size,
585 LLVMContext &Context) {
586
587 if (Size <= 1)
588 // We get bogus data given an empty corpus - just create a new module.
589 return std::make_unique<Module>("M", Context);
590
591 auto Buffer = MemoryBuffer::getMemBuffer(
592 StringRef(reinterpret_cast<const char *>(Data), Size), "Fuzzer input",
593 /*RequiresNullTerminator=*/false);
594
595 SMDiagnostic Err;
596 auto M = parseBitcodeFile(Buffer->getMemBufferRef(), Context);
597 if (Error E = M.takeError()) {
598 errs() << toString(std::move(E)) << "\n";
599 return nullptr;
600 }
601 return std::move(M.get());
602}
603
604size_t llvm::writeModule(const Module &M, uint8_t *Dest, size_t MaxSize) {
605 std::string Buf;
606 {
609 }
610 if (Buf.size() > MaxSize)
611 return 0;
612 memcpy(Dest, Buf.data(), Buf.size());
613 return Buf.size();
614}
615
616std::unique_ptr<Module> llvm::parseAndVerify(const uint8_t *Data, size_t Size,
617 LLVMContext &Context) {
618 auto M = parseModule(Data, Size, Context);
619 if (!M || verifyModule(*M, &errs()))
620 return nullptr;
621
622 return M;
623}
Rewrite undef for PHI
SmallVector< MachineOperand, 4 > Cond
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
return RetTy
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
uint64_t Size
Hexagon Common GEP
static void createEmptyFunction(Module &M)
Definition: IRMutator.cpp:34
static void eliminateDeadCode(Function &F)
Definition: IRMutator.cpp:80
static uint64_t getUniqueCaseValue(SmallSet< uint64_t, 4 > &CasesTaken, uint64_t MaxValue, RandomIRBuilder &IB)
Return a case value that is not already taken to make sure we don't have two cases with same value.
Definition: IRMutator.cpp:342
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
Module.h This file contains the declarations for the Module class.
print must be executed print the must be executed context for all instructions
LLVMContext & Context
#define P(N)
FunctionAnalysisManager FAM
static ManagedStatic< cl::opt< uint64_t >, CreateSeed > Seed
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
raw_pwrite_stream & OS
This file defines the SmallSet class.
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:620
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
Definition: PassManager.h:836
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Definition: ArrayRef.h:193
LLVM Basic Block Representation.
Definition: BasicBlock.h:56
iterator end()
Definition: BasicBlock.h:316
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
Definition: BasicBlock.cpp:245
const Instruction & front() const
Definition: BasicBlock.h:326
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:105
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:112
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.h:127
Conditional or Unconditional Branch instruction.
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
This class is the base class for the comparison instructions.
Definition: InstrTypes.h:708
void setPredicate(Predicate P)
Set the predicate for this instruction to the specified value.
Definition: InstrTypes.h:811
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:718
@ FIRST_ICMP_PREDICATE
Definition: InstrTypes.h:749
@ FIRST_FCMP_PREDICATE
Definition: InstrTypes.h:736
This is the shared class of boolean and integer constants.
Definition: Constants.h:78
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:888
This is an important base class in LLVM.
Definition: Constant.h:41
Basic Dead Code Elimination pass.
Definition: DCE.h:23
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
bool none() const
Definition: FMF.h:59
bool all() const
Definition: FMF.h:60
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:136
const BasicBlock & getEntryBlock() const
Definition: Function.h:740
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Definition: Instructions.h:940
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:652
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:48
virtual void mutate(Module &M, RandomIRBuilder &IB)
Definition: IRMutator.cpp:44
void mutateModule(Module &M, int Seed, size_t CurSize, size_t MaxSize)
Definition: IRMutator.cpp:64
static std::vector< fuzzerop::OpDescriptor > getDefaultOps()
Definition: IRMutator.cpp:94
void mutate(Function &F, RandomIRBuilder &IB) override
Definition: IRMutator.cpp:89
void mutate(BasicBlock &BB, RandomIRBuilder &IB) override
Definition: IRMutator.cpp:352
void mutate(BasicBlock &BB, RandomIRBuilder &IB) override
Definition: IRMutator.cpp:470
uint64_t getWeight(size_t CurrentSize, size_t MaxSize, uint64_t CurrentWeight) override
Provide a weight to bias towards choosing this strategy for a mutation.
Definition: IRMutator.cpp:149
void mutate(Function &F, RandomIRBuilder &IB) override
Definition: IRMutator.cpp:166
void mutate(Instruction &Inst, RandomIRBuilder &IB) override
Definition: IRMutator.cpp:214
void setHasNoUnsignedWrap(bool b=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.
bool hasNoNaNs() const LLVM_READONLY
Determine whether the no-NaNs flag is set.
bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
bool hasNoInfs() const LLVM_READONLY
Determine whether the no-infs flag is set.
void setHasNoSignedZeros(bool B)
Set or clear the no-signed-zeros flag on this instruction, which must be an operator which supports t...
bool hasNoSignedZeros() const LLVM_READONLY
Determine whether the no-signed-zeros flag is set.
bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
void setHasAllowContract(bool B)
Set or clear the allow-contract flag on this instruction, which must be an operator which supports th...
void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
void setHasNoNaNs(bool B)
Set or clear the no-nans flag on this instruction, which must be an operator which supports this flag...
void setHasApproxFunc(bool B)
Set or clear the approximate-math-functions flag on this instruction, which must be an operator which...
void setHasAllowReassoc(bool B)
Set or clear the reassociation flag on this instruction, which must be an operator which supports thi...
const BasicBlock * getParent() const
Definition: Instruction.h:90
bool isExact() const LLVM_READONLY
Determine whether the exact flag is set.
bool isTerminator() const
Definition: Instruction.h:171
bool hasAllowReciprocal() const LLVM_READONLY
Determine whether the allow-reciprocal flag is set.
void setHasNoInfs(bool B)
Set or clear the no-infs flag on this instruction, which must be an operator which supports this flag...
FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
bool hasApproxFunc() const LLVM_READONLY
Determine whether the approximate-math-functions flag is set.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Definition: Instruction.h:168
void setIsExact(bool b=true)
Set or clear the exact flag on this instruction, which must be an operator which supports this flag.
void setHasAllowReciprocal(bool B)
Set or clear the allow-reciprocal flag on this instruction, which must be an operator which supports ...
bool hasAllowContract() const LLVM_READONLY
Determine whether the allow-contract flag is set.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:82
void setFast(bool B)
Set or clear all fast-math-flags on this instruction, which must be an operator which supports this f...
bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
Class to represent integer types.
Definition: DerivedTypes.h:40
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
Definition: DerivedTypes.h:72
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
LLVMContext & getContext() const
Get the global data context.
Definition: Module.h:262
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
Pseudo-analysis pass that exposes the PassInstrumentation to pass managers.
Definition: PassManager.h:595
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same< PassT, PassManager >::value > addPass(PassT &&Pass)
Definition: PassManager.h:544
PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs)
Run all of the passes in this manager over the given unit of IR.
Definition: PassManager.h:498
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition: SourceMgr.h:281
void mutate(BasicBlock &BB, RandomIRBuilder &IB) override
Definition: IRMutator.cpp:522
void mutate(Function &F, RandomIRBuilder &IB) override
Definition: IRMutator.cpp:499
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false.
Definition: SmallPtrSet.h:379
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition: SmallPtrSet.h:383
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:365
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:450
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:135
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition: SmallSet.h:164
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:177
size_t size() const
Definition: SmallVector.h:91
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Multiway switch.
static SwitchInst * Create(Value *Value, BasicBlock *Default, unsigned NumCases, Instruction *InsertBefore=nullptr)
Analysis pass providing the TargetLibraryInfo.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static IntegerType * getInt1Ty(LLVMContext &C)
static Type * getVoidTy(LLVMContext &C)
bool isVoidTy() const
Return true if this is 'void'.
Definition: Type.h:140
void setOperand(unsigned i, Value *Val)
Definition: User.h:174
Value * getOperand(unsigned i) const
Definition: User.h:169
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:532
self_iterator getIterator()
Definition: ilist_node.h:82
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:642
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
static SourcePred onlyType(Type *Only)
Definition: OpDescriptor.h:94
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void ReplaceInstWithInst(BasicBlock *BB, BasicBlock::iterator &BI, Instruction *I)
Replace the instruction specified by BI with the instruction specified by I.
void describeFuzzerIntOps(std::vector< fuzzerop::OpDescriptor > &Ops)
Getters for the default sets of operations, per general category.
Definition: Operations.cpp:18
Expected< std::unique_ptr< Module > > parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context, ParserCallbacks Callbacks={})
Read the specified bitcode file, returning the module.
void WriteBitcodeToFile(const Module &M, raw_ostream &Out, bool ShouldPreserveUseListOrder=false, const ModuleSummaryIndex *Index=nullptr, bool GenerateHash=false, ModuleHash *ModHash=nullptr)
Write the specified module to the specified raw output stream.
std::unique_ptr< Module > parseAndVerify(const uint8_t *Data, size_t Size, LLVMContext &Context)
Try to parse module and verify it.
Definition: IRMutator.cpp:616
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
std::unique_ptr< Module > parseModule(const uint8_t *Data, size_t Size, LLVMContext &Context)
Fuzzer friendly interface for the llvm bitcode parser.
Definition: IRMutator.cpp:584
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:748
void describeFuzzerAggregateOps(std::vector< fuzzerop::OpDescriptor > &Ops)
Definition: Operations.cpp:79
size_t writeModule(const Module &M, uint8_t *Dest, size_t MaxSize)
Fuzzer friendly interface for the llvm bitcode printer.
Definition: IRMutator.cpp:604
ReservoirSampler< ElT, GenT > makeSampler(GenT &RandGen, RangeT &&Items)
Definition: Random.h:75
void describeFuzzerVectorOps(std::vector< fuzzerop::OpDescriptor > &Ops)
Definition: Operations.cpp:85
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
Definition: STLExtras.h:664
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void describeFuzzerFloatOps(std::vector< fuzzerop::OpDescriptor > &Ops)
Definition: Operations.cpp:45
void describeFuzzerControlFlowOps(std::vector< fuzzerop::OpDescriptor > &Ops)
Definition: Operations.cpp:70
auto predecessors(const MachineBasicBlock *BB)
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition: iterator.h:363
void describeFuzzerPointerOps(std::vector< fuzzerop::OpDescriptor > &Ops)
Definition: Operations.cpp:75
unsigned pred_size(const MachineBasicBlock *BB)
bool verifyModule(const Module &M, raw_ostream *OS=nullptr, bool *BrokenDebugInfo=nullptr)
Check a module for errors.
Definition: Verifier.cpp:6476
A description of some operation we can build while fuzzing IR.
Definition: OpDescriptor.h:88