LLVM 24.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"
24#include "llvm/IR/IntrinsicsAMDGPU.h"
25#include "llvm/IR/Module.h"
26#include "llvm/IR/Operator.h"
28#include "llvm/IR/Verifier.h"
32#include <map>
33#include <optional>
34
35using namespace llvm;
36
38 auto RS = makeSampler<Function *>(IB.Rand);
39 for (Function &F : M)
40 if (!F.isDeclaration())
41 RS.sample(&F, /*Weight=*/1);
42
43 while (RS.totalWeight() < IB.MinFunctionNum) {
44 Function *F = IB.createFunctionDefinition(M);
45 RS.sample(F, /*Weight=*/1);
46 }
47 mutate(*RS.getSelection(), IB);
48}
49
52 [](BasicBlock *BB) { return !BB->isEHPad(); });
54 mutate(*makeSampler(IB.Rand, Range).getSelection(), IB);
55}
56
58 mutate(*makeSampler(IB.Rand, make_pointer_range(BB)).getSelection(), IB);
59}
60
62 return M.getInstructionCount() + M.size() + M.global_size() + M.alias_size();
63}
64
65void IRMutator::mutateModule(Module &M, int Seed, 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 size_t CurSize = IRMutator::getModuleSize(M);
72 auto RS = makeSampler<IRMutationStrategy *>(IB.Rand);
73 for (const auto &Strategy : Strategies)
74 RS.sample(Strategy.get(),
75 Strategy->getWeight(CurSize, MaxSize, RS.totalWeight()));
76 if (RS.totalWeight() == 0)
77 return;
78 auto Strategy = RS.getSelection();
79
80 Strategy->mutate(M, IB);
81}
82
85 FPM.addPass(DCEPass());
87 FAM.registerPass([&] { return TargetLibraryAnalysis(); });
88 FAM.registerPass([&] { return PassInstrumentationAnalysis(); });
89 FPM.run(F, FAM);
90}
91
96
97std::vector<fuzzerop::OpDescriptor> InjectorIRStrategy::getDefaultOps() {
98 std::vector<fuzzerop::OpDescriptor> Ops;
105 return Ops;
106}
107
108std::optional<fuzzerop::OpDescriptor>
109InjectorIRStrategy::chooseOperation(Value *Src, RandomIRBuilder &IB) {
110 auto OpMatchesPred = [&Src](fuzzerop::OpDescriptor &Op) {
111 return Op.SourcePreds[0].matches({}, Src);
112 };
113 auto RS = makeSampler(IB.Rand, make_filter_range(Operations, OpMatchesPred));
114 if (RS.isEmpty())
115 return std::nullopt;
116 return *RS;
117}
118
121 return I;
122 } else {
123 // Certain intrinsics, such as @llvm.amdgcn.cs.chain, must be immediately
124 // followed by an unreachable instruction..
126 if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(UI->getPrevNode())) {
127 return II;
128 }
129 }
130 }
131
132 return BB.getTerminator();
133}
134
136 auto End = BB.end();
137
138 if (BB.empty()) {
139 return End;
140 }
141
142 Instruction *EffectiveTerminator = getEffectiveTerminator(BB);
143 if (EffectiveTerminator != BB.getTerminator()) {
144 // Adjust range for special cases such as tail call.
145 End = std::prev(BB.end());
146 }
147
148 return End;
149}
150
153 auto End = getEndIterator(BB);
154 return make_range(BB.getFirstInsertionPt(), End);
155}
156
160 if (Insts.size() < 1)
161 return;
162
163 // Choose an insertion point for our new instruction.
164 size_t IP = uniform<size_t>(IB.Rand, 0, Insts.size() - 1);
165
166 auto InstsBefore = ArrayRef(Insts).slice(0, IP);
167 auto InstsAfter = ArrayRef(Insts).slice(IP);
168
169 // Choose a source, which will be used to constrain the operation selection.
171 Srcs.push_back(IB.findOrCreateSource(BB, InstsBefore));
172
173 // Choose an operation that's constrained to be valid for the type of the
174 // source, collect any other sources it needs, and then build it.
175 auto OpDesc = chooseOperation(Srcs[0], IB);
176 // Bail if no operation was found
177 if (!OpDesc)
178 return;
179
180 for (const auto &Pred : ArrayRef(OpDesc->SourcePreds).slice(1))
181 Srcs.push_back(IB.findOrCreateSource(BB, InstsBefore, Srcs, Pred));
182
183 if (Value *Op = OpDesc->BuilderFunc(Srcs, Insts[IP]->getIterator())) {
184 // Find a sink and wire up the results of the operation.
185 IB.connectToSink(BB, InstsAfter, Op);
186 }
187}
188
189uint64_t InstDeleterIRStrategy::getWeight(size_t CurrentSize, size_t MaxSize,
190 uint64_t CurrentWeight) {
191 // If we have less than 200 bytes, panic and try to always delete.
192 if (CurrentSize > MaxSize - 200)
193 return CurrentWeight ? CurrentWeight * 100 : 1;
194 // Draw a line starting from when we only have 1k left and increasing linearly
195 // to double the current weight.
196 int64_t Line = (-2 * static_cast<int64_t>(CurrentWeight)) *
197 (static_cast<int64_t>(MaxSize) -
198 static_cast<int64_t>(CurrentSize) - 1000) /
199 1000;
200 // Clamp negative weights to zero.
201 if (Line < 0)
202 return 0;
203 return Line;
204}
205
207 auto RS = makeSampler<Instruction *>(IB.Rand);
208 for (Instruction &Inst : instructions(F)) {
209 // TODO: We can't handle these instructions.
210 if (Inst.isTerminator() || Inst.isEHPad() || Inst.isSwiftError() ||
211 isa<PHINode>(Inst))
212 continue;
213
214 RS.sample(&Inst, /*Weight=*/1);
215 }
216 if (RS.isEmpty())
217 return;
218
219 // Delete the instruction.
220 mutate(*RS.getSelection(), IB);
221 // Clean up any dead code that's left over after removing the instruction.
223}
224
226 assert(!Inst.isTerminator() && "Deleting terminators invalidates CFG");
227
228 if (Inst.getType()->isVoidTy()) {
229 // Instructions with void type (ie, store) have no uses to worry about. Just
230 // erase it and move on.
231 Inst.eraseFromParent();
232 return;
233 }
234
235 // Otherwise we need to find some other value with the right type to keep the
236 // users happy.
237 auto Pred = fuzzerop::onlyType(Inst.getType());
238 auto RS = makeSampler<Value *>(IB.Rand);
240 BasicBlock *BB = Inst.getParent();
241 for (auto I = BB->getFirstInsertionPt(), E = Inst.getIterator(); I != E;
242 ++I) {
243 if (Pred.matches({}, &*I))
244 RS.sample(&*I, /*Weight=*/1);
245 InstsBefore.push_back(&*I);
246 }
247 if (!RS)
248 RS.sample(IB.newSource(*BB, InstsBefore, {}, Pred), /*Weight=*/1);
249
250 Inst.replaceAllUsesWith(RS.getSelection());
251 Inst.eraseFromParent();
252}
253
255 RandomIRBuilder &IB) {
256 SmallVector<std::function<void()>, 8> Modifications;
257 CmpInst *CI = nullptr;
258 GetElementPtrInst *GEP = nullptr;
259 switch (Inst.getOpcode()) {
260 default:
261 break;
262 // Add nsw, nuw flag
263 case Instruction::Add:
264 case Instruction::Mul:
265 case Instruction::Sub:
266 case Instruction::Shl:
267 Modifications.push_back(
268 [&Inst]() { Inst.setHasNoSignedWrap(!Inst.hasNoSignedWrap()); });
269 Modifications.push_back(
270 [&Inst]() { Inst.setHasNoUnsignedWrap(!Inst.hasNoUnsignedWrap()); });
271 break;
272 case Instruction::ICmp:
273 CI = cast<ICmpInst>(&Inst);
274 for (unsigned p = CmpInst::FIRST_ICMP_PREDICATE;
276 Modifications.push_back(
277 [CI, p]() { CI->setPredicate(static_cast<CmpInst::Predicate>(p)); });
278 }
279 break;
280 // Add inbound flag.
281 case Instruction::GetElementPtr:
283 Modifications.push_back(
284 [GEP]() { GEP->setIsInBounds(!GEP->isInBounds()); });
285 break;
286 // Add exact flag.
287 case Instruction::UDiv:
288 case Instruction::SDiv:
289 case Instruction::LShr:
290 case Instruction::AShr:
291 Modifications.push_back([&Inst] { Inst.setIsExact(!Inst.isExact()); });
292 break;
293
294 case Instruction::FCmp:
295 CI = cast<FCmpInst>(&Inst);
296 for (unsigned p = CmpInst::FIRST_FCMP_PREDICATE;
298 Modifications.push_back(
299 [CI, p]() { CI->setPredicate(static_cast<CmpInst::Predicate>(p)); });
300 }
301 break;
302 }
303
304 // Add fast math flag if possible.
305 if (isa<FPMathOperator>(&Inst)) {
306 // Try setting everything unless they are already on.
307 Modifications.push_back(
308 [&Inst] { Inst.setFast(!Inst.getFastMathFlags().all()); });
309 // Try unsetting everything unless they are already off.
310 Modifications.push_back(
311 [&Inst] { Inst.setFast(!Inst.getFastMathFlags().none()); });
312 // Individual setting by flipping the bit
313 Modifications.push_back(
314 [&Inst] { Inst.setHasAllowReassoc(!Inst.hasAllowReassoc()); });
315 Modifications.push_back([&Inst] { Inst.setHasNoNaNs(!Inst.hasNoNaNs()); });
316 Modifications.push_back([&Inst] { Inst.setHasNoInfs(!Inst.hasNoInfs()); });
317 Modifications.push_back(
318 [&Inst] { Inst.setHasNoSignedZeros(!Inst.hasNoSignedZeros()); });
319 Modifications.push_back(
320 [&Inst] { Inst.setHasAllowReciprocal(!Inst.hasAllowReciprocal()); });
321 Modifications.push_back(
322 [&Inst] { Inst.setHasAllowContract(!Inst.hasAllowContract()); });
323 Modifications.push_back(
324 [&Inst] { Inst.setHasApproxFunc(!Inst.hasApproxFunc()); });
325 }
326
327 // Randomly switch operands of instructions
328 std::pair<int, int> NoneItem({-1, -1}), ShuffleItems(NoneItem);
329 switch (Inst.getOpcode()) {
330 case Instruction::SDiv:
331 case Instruction::UDiv:
332 case Instruction::SRem:
333 case Instruction::URem:
334 case Instruction::FDiv:
335 case Instruction::FRem: {
336 // Verify that the after shuffle the second operand is not
337 // constant 0.
338 Value *Operand = Inst.getOperand(0);
339 if (Constant *C = dyn_cast<Constant>(Operand)) {
340 if (!C->isNullValue()) {
341 ShuffleItems = {0, 1};
342 }
343 }
344 break;
345 }
346 case Instruction::Select:
347 ShuffleItems = {1, 2};
348 break;
349 case Instruction::Add:
350 case Instruction::Sub:
351 case Instruction::Mul:
352 case Instruction::Shl:
353 case Instruction::LShr:
354 case Instruction::AShr:
355 case Instruction::And:
356 case Instruction::Or:
357 case Instruction::Xor:
358 case Instruction::FAdd:
359 case Instruction::FSub:
360 case Instruction::FMul:
361 case Instruction::ICmp:
362 case Instruction::FCmp:
363 case Instruction::ShuffleVector:
364 ShuffleItems = {0, 1};
365 break;
366 }
367 if (ShuffleItems != NoneItem) {
368 Modifications.push_back([&Inst, &ShuffleItems]() {
369 Value *Op0 = Inst.getOperand(ShuffleItems.first);
370 Inst.setOperand(ShuffleItems.first, Inst.getOperand(ShuffleItems.second));
371 Inst.setOperand(ShuffleItems.second, Op0);
372 });
373 }
374
375 auto RS = makeSampler(IB.Rand, Modifications);
376 if (RS)
377 RS.getSelection()();
378}
379
380/// Return a case value that is not already taken to make sure we don't have two
381/// cases with same value.
383 uint64_t MaxValue, RandomIRBuilder &IB) {
384 uint64_t tmp;
385 do {
386 tmp = uniform<uint64_t>(IB.Rand, 0, MaxValue);
387 } while (CasesTaken.count(tmp) != 0);
388 CasesTaken.insert(tmp);
389 return tmp;
390}
391
392/// Determines whether a function is unsupported by the current mutator's
393/// implementation. The function returns true if any of the following criteria
394/// are met:
395/// * The function accepts metadata or token types as arguments.
396/// * The function has ABI attributes that could cause UB.
397/// * The function uses a non-callable CC that may result in UB.
399 // Some functions accept metadata type or token type as arguments.
400 // We don't call those functions for now.
401 // For example, `@llvm.dbg.declare(metadata, metadata, metadata)`
402 // https://llvm.org/docs/SourceLevelDebugging.html#llvm-dbg-declare
403 auto IsUnsupportedTy = [](Type *T) {
404 return T->isMetadataTy() || T->isTokenTy();
405 };
406
407 if (IsUnsupportedTy(F->getReturnType()) ||
408 any_of(F->getFunctionType()->params(), IsUnsupportedTy)) {
409 return true;
410 }
411
412 // ABI attributes must be specified both at the function
413 // declaration/definition and call-site, otherwise the
414 // behavior may be undefined.
415 // We don't call those functions for now to prevent UB from happening.
416 auto IsABIAttribute = [](AttributeSet A) {
417 static const Attribute::AttrKind ABIAttrs[] = {
418 Attribute::StructRet, Attribute::ByVal,
419 Attribute::InAlloca, Attribute::InReg,
420 Attribute::StackAlignment, Attribute::SwiftSelf,
421 Attribute::SwiftAsync, Attribute::SwiftError,
422 Attribute::Preallocated, Attribute::ByRef,
423 Attribute::ZExt, Attribute::SExt};
424
425 return llvm::any_of(ABIAttrs, [&](Attribute::AttrKind kind) {
426 return A.hasAttribute(kind);
427 });
428 };
429
430 auto FuncAttrs = F->getAttributes();
431 if (IsABIAttribute(FuncAttrs.getRetAttrs())) {
432 return true;
433 }
434 for (size_t i = 0; i < F->arg_size(); i++) {
435 if (IsABIAttribute(FuncAttrs.getParamAttrs(i))) {
436 return true;
437 }
438 }
439
440 // If it is not satisfied, the IR will be invalid.
441 if (!isCallableCC(F->getCallingConv())) {
442 return true;
443 }
444
445 // This intrinsic has specific requirements for its parameters and the caller
446 // must adhere to certain calling conventions.
447 if (F->isIntrinsic() && F->getIntrinsicID() == Intrinsic::amdgcn_cs_chain) {
448 return true;
449 }
450
451 return false;
452}
453
455 Module *M = BB.getParent()->getParent();
456 // If nullptr is selected, we will create a new function declaration.
457 SmallVector<Function *, 32> Functions({nullptr});
458 for (Function &F : M->functions()) {
459 Functions.push_back(&F);
460 }
461
462 auto RS = makeSampler(IB.Rand, Functions);
463 Function *F = RS.getSelection();
464
465 if (!F || isUnsupportedFunction(F)) {
466 F = IB.createFunctionDeclaration(*M);
467 }
468
469 FunctionType *FTy = F->getFunctionType();
471 if (!F->arg_empty()) {
472 for (Type *ArgTy : FTy->params()) {
473 SourcePreds.push_back(fuzzerop::onlyType(ArgTy));
474 }
475 }
476 bool isRetVoid = (F->getReturnType() == Type::getVoidTy(M->getContext()));
477 auto BuilderFunc = [FTy, F, isRetVoid](ArrayRef<Value *> Srcs,
478 BasicBlock::iterator InsertPt) {
479 StringRef Name = isRetVoid ? nullptr : "C";
480 CallInst *Call = CallInst::Create(FTy, F, Srcs, Name, InsertPt);
481 Call->setCallingConv(F->getCallingConv());
482 // Don't return this call inst if it return void as it can't be sinked.
483 return isRetVoid ? nullptr : Call;
484 };
485
488 if (Insts.size() < 1)
489 return;
490
491 // Choose an insertion point for our new call instruction.
492 uint64_t IP = uniform<uint64_t>(IB.Rand, 0, Insts.size() - 1);
493
494 auto InstsBefore = ArrayRef(Insts).slice(0, IP);
495 auto InstsAfter = ArrayRef(Insts).slice(IP);
496
497 // Choose a source, which will be used to constrain the operation selection.
499
500 for (const auto &Pred : ArrayRef(SourcePreds)) {
501 Srcs.push_back(IB.findOrCreateSource(BB, InstsBefore, Srcs, Pred));
502 }
503
504 if (Value *Op = BuilderFunc(Srcs, Insts[IP]->getIterator())) {
505 // Find a sink and wire up the results of the operation.
506 IB.connectToSink(BB, InstsAfter, Op);
507 }
508}
509
513 if (Insts.size() < 1)
514 return;
515
516 // Choose a point where we split the block.
517 uint64_t IP = uniform<uint64_t>(IB.Rand, 0, Insts.size() - 1);
518 auto InstsBeforeSplit = ArrayRef(Insts).slice(0, IP);
519
520 // `Sink` inherits Blocks' terminator, `Source` will have a UncondBrInst
521 // directly jumps to `Sink`. Here, we have to create a new terminator for
522 // `Source`.
523 BasicBlock *Block = Insts[IP]->getParent();
524 BasicBlock *Source = Block;
525 BasicBlock *Sink = Block->splitBasicBlock(Insts[IP], "BB");
526
527 Function *F = BB.getParent();
528 LLVMContext &C = F->getParent()->getContext();
529 // A coin decides if it is branch or switch
530 if (uniform<uint64_t>(IB.Rand, 0, 1)) {
531 // Branch
532 BasicBlock *IfTrue = BasicBlock::Create(C, "T", F);
533 BasicBlock *IfFalse = BasicBlock::Create(C, "F", F);
534 Value *Cond =
535 IB.findOrCreateSource(*Source, InstsBeforeSplit, {},
537 CondBrInst *Branch = CondBrInst::Create(Cond, IfTrue, IfFalse);
538 // Remove the old terminator.
539 ReplaceInstWithInst(Source->getTerminator(), Branch);
540 // Connect these blocks to `Sink`
541 connectBlocksToSink({IfTrue, IfFalse}, Sink, IB);
542 } else {
543 // Switch
544 // Determine Integer type, it IS possible we use a boolean to switch.
545 auto RS =
546 makeSampler(IB.Rand, make_filter_range(IB.KnownTypes, [](Type *Ty) {
547 return Ty->isIntegerTy();
548 }));
549 assert(RS && "There is no integer type in all allowed types, is the "
550 "setting correct?");
551 Type *Ty = RS.getSelection();
552 IntegerType *IntTy = cast<IntegerType>(Ty);
553
554 uint64_t BitSize = IntTy->getBitWidth();
555 uint64_t MaxCaseVal =
556 (BitSize >= 64) ? (uint64_t)-1 : ((uint64_t)1 << BitSize) - 1;
557 // Create Switch inst in Block
558 Value *Cond = IB.findOrCreateSource(*Source, InstsBeforeSplit, {},
559 fuzzerop::onlyType(IntTy), false);
560 BasicBlock *DefaultBlock = BasicBlock::Create(C, "SW_D", F);
561 uint64_t NumCases = uniform<uint64_t>(IB.Rand, 1, MaxNumCases);
562 NumCases = (NumCases > MaxCaseVal) ? MaxCaseVal + 1 : NumCases;
563 SwitchInst *Switch = SwitchInst::Create(Cond, DefaultBlock, NumCases);
564 // Remove the old terminator.
565 ReplaceInstWithInst(Source->getTerminator(), Switch);
566
567 // Create blocks, for each block assign a case value.
568 SmallVector<BasicBlock *, 4> Blocks({DefaultBlock});
569 SmallSet<uint64_t, 4> CasesTaken;
570 for (uint64_t i = 0; i < NumCases; i++) {
571 uint64_t CaseVal = getUniqueCaseValue(CasesTaken, MaxCaseVal, IB);
572 BasicBlock *CaseBlock = BasicBlock::Create(C, "SW_C", F);
573 ConstantInt *OnValue = ConstantInt::get(IntTy, CaseVal);
574 Switch->addCase(OnValue, CaseBlock);
575 Blocks.push_back(CaseBlock);
576 }
577
578 // Connect these blocks to `Sink`
579 connectBlocksToSink(Blocks, Sink, IB);
580 }
581}
582
583/// The caller has to guarantee that these blocks are "empty", i.e. it doesn't
584/// even have terminator.
585void InsertCFGStrategy::connectBlocksToSink(ArrayRef<BasicBlock *> Blocks,
586 BasicBlock *Sink,
587 RandomIRBuilder &IB) {
588 uint64_t DirectSinkIdx = uniform<uint64_t>(IB.Rand, 0, Blocks.size() - 1);
589 for (uint64_t i = 0; i < Blocks.size(); i++) {
590 // We have at least one block that directly goes to sink.
591 CFGToSink ToSink = (i == DirectSinkIdx)
592 ? CFGToSink::DirectSink
593 : static_cast<CFGToSink>(uniform<uint64_t>(
594 IB.Rand, 0, CFGToSink::EndOfCFGToLink - 1));
595 BasicBlock *BB = Blocks[i];
596 Function *F = BB->getParent();
597 LLVMContext &C = F->getParent()->getContext();
598 switch (ToSink) {
599 case CFGToSink::Return: {
600 Type *RetTy = F->getReturnType();
601 Value *RetValue = nullptr;
602 if (!RetTy->isVoidTy())
603 RetValue =
604 IB.findOrCreateSource(*BB, {}, {}, fuzzerop::onlyType(RetTy));
605 ReturnInst::Create(C, RetValue, BB);
606 break;
607 }
608 case CFGToSink::DirectSink: {
609 UncondBrInst::Create(Sink, BB);
610 break;
611 }
612 case CFGToSink::SinkOrSelfLoop: {
613 SmallVector<BasicBlock *, 2> Branches({Sink, BB});
614 // A coin decides which block is true branch.
615 uint64_t coin = uniform<uint64_t>(IB.Rand, 0, 1);
616 Value *Cond = IB.findOrCreateSource(
617 *BB, {}, {}, fuzzerop::onlyType(Type::getInt1Ty(C)), false);
618 CondBrInst::Create(Cond, Branches[coin], Branches[1 - coin], BB);
619 break;
620 }
621 case CFGToSink::EndOfCFGToLink:
622 llvm_unreachable("EndOfCFGToLink executed, something's wrong.");
623 }
624 }
625}
626
628 // Can't insert PHI node to entry node.
629 if (&BB == &BB.getParent()->getEntryBlock())
630 return;
631 Type *Ty = IB.randomType();
632 PHINode *PHI = PHINode::Create(Ty, llvm::pred_size(&BB), "", BB.begin());
633
634 // Use a map to make sure the same incoming basic block has the same value.
635 DenseMap<BasicBlock *, Value *> IncomingValues;
636 for (BasicBlock *Pred : predecessors(&BB)) {
637 Value *Src = IncomingValues[Pred];
638 // If `Pred` is not in the map yet, we'll get a nullptr.
639 if (!Src) {
641 for (auto I = Pred->begin(); I != Pred->end(); ++I)
642 Insts.push_back(&*I);
643 // There is no need to inform IB what previously used values are if we are
644 // using `onlyType`
645 Src = IB.findOrCreateSource(*Pred, Insts, {}, fuzzerop::onlyType(Ty));
646 IncomingValues[Pred] = Src;
647 }
648 PHI->addIncoming(Src, Pred);
649 }
652 IB.connectToSink(BB, InstsAfter, PHI);
653}
654
656 for (BasicBlock &BB : F) {
657 this->mutate(BB, IB);
658 }
659}
663 if (Insts.size() < 1)
664 return;
665 // Choose an Instruction to mutate.
666 uint64_t Idx = uniform<uint64_t>(IB.Rand, 0, Insts.size() - 1);
667 Instruction *Inst = Insts[Idx];
668 // `Idx + 1` so we don't sink to ourselves.
669 auto InstsAfter = ArrayRef(Insts).slice(Idx + 1);
670 Type *Ty = Inst->getType();
671 // Don't sink terminators, void function calls, token, etc.
672 if (!Ty->isVoidTy() && !Ty->isTokenTy())
673 // Find a new sink and wire up the results of the operation.
674 IB.connectToSink(BB, InstsAfter, Inst);
675}
676
678 // A deterministic alternative to SmallPtrSet with the same lookup
679 // performance.
680 std::map<size_t, Instruction *> AliveInsts;
681 std::map<Instruction *, size_t> AliveInstsLookup;
682 size_t InsertIdx = 0;
683 for (auto &I : make_early_inc_range(
685 getEffectiveTerminator(BB)->getIterator()))) {
686 // First gather all instructions that can be shuffled. Don't take
687 // terminator.
688 AliveInsts.insert({InsertIdx, &I});
689 AliveInstsLookup.insert({&I, InsertIdx++});
690 // Then remove these instructions from the block
691 I.removeFromParent();
692 }
693
694 // Shuffle these instructions using topological sort.
695 // Returns false if all current instruction's dependencies in this block have
696 // been shuffled. If so, this instruction can be shuffled too.
697 auto hasAliveParent = [&AliveInsts, &AliveInstsLookup](size_t Index) {
698 for (Value *O : AliveInsts[Index]->operands()) {
700 if (P && AliveInstsLookup.count(P))
701 return true;
702 }
703 return false;
704 };
705 // Get all alive instructions that depend on the current instruction.
706 // Takes Instruction* instead of index because the instruction is already
707 // shuffled.
708 auto getAliveChildren = [&AliveInstsLookup](Instruction *I) {
710 for (Value *U : I->users()) {
712 auto It = AliveInstsLookup.find(P);
713 if (It != AliveInstsLookup.end())
714 Children.insert(It->second);
715 }
716 }
717 return Children;
718 };
719 SmallSet<size_t, 8> RootIndices;
721 for (const auto &[Index, Inst] : AliveInsts) {
722 if (!hasAliveParent(Index))
723 RootIndices.insert(Index);
724 }
725 // Topological sort by randomly selecting a node without a parent, or root.
726 while (!RootIndices.empty()) {
727 auto RS = makeSampler<size_t>(IB.Rand);
728 for (size_t RootIdx : RootIndices)
729 RS.sample(RootIdx, 1);
730 size_t RootIdx = RS.getSelection();
731
732 RootIndices.erase(RootIdx);
733 Instruction *Root = AliveInsts[RootIdx];
734 AliveInsts.erase(RootIdx);
735 AliveInstsLookup.erase(Root);
736 Insts.push_back(Root);
737
738 for (size_t Child : getAliveChildren(Root)) {
739 if (!hasAliveParent(Child)) {
740 RootIndices.insert(Child);
741 }
742 }
743 }
744
745 Instruction *Terminator = getEffectiveTerminator(BB);
746 // Then put instructions back.
747 for (Instruction *I : Insts) {
748 I->insertBefore(Terminator->getIterator());
749 }
750}
751
752std::unique_ptr<Module> llvm::parseModule(const uint8_t *Data, size_t Size,
753 LLVMContext &Context) {
754
755 if (Size <= 1)
756 // We get bogus data given an empty corpus - just create a new module.
757 return std::make_unique<Module>("M", Context);
758
759 auto Buffer = MemoryBuffer::getMemBuffer(
760 StringRef(reinterpret_cast<const char *>(Data), Size), "Fuzzer input",
761 /*RequiresNullTerminator=*/false);
762
763 auto M = parseBitcodeFile(Buffer->getMemBufferRef(), Context);
764 if (Error E = M.takeError()) {
765 errs() << toString(std::move(E)) << "\n";
766 return nullptr;
767 }
768 return std::move(M.get());
769}
770
771size_t llvm::writeModule(const Module &M, uint8_t *Dest, size_t MaxSize) {
772 std::string Buf;
773 {
774 raw_string_ostream OS(Buf);
775 WriteBitcodeToFile(M, OS);
776 }
777 if (Buf.size() > MaxSize)
778 return 0;
779 memcpy(Dest, Buf.data(), Buf.size());
780 return Buf.size();
781}
782
783std::unique_ptr<Module> llvm::parseAndVerify(const uint8_t *Data, size_t Size,
784 LLVMContext &Context) {
785 auto M = parseModule(Data, Size, Context);
786 if (!M || verifyModule(*M, &errs()))
787 return nullptr;
788
789 return M;
790}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
Rewrite undef for PHI
Expand Atomic instructions
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Hexagon Common GEP
static Instruction * getEffectiveTerminator(BasicBlock &BB)
static bool isUnsupportedFunction(Function *F)
Determines whether a function is unsupported by the current mutator's implementation.
static void eliminateDeadCode(Function &F)
Definition IRMutator.cpp:83
static iterator_range< BasicBlock::iterator > getInsertionRange(BasicBlock &BB)
static BasicBlock::iterator getEndIterator(BasicBlock &BB)
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.
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
#define P(N)
FunctionAnalysisManager FAM
This file defines the Pass Instrumentation classes that provide instrumentation points into the pass ...
SmallVector< MachineOperand, 4 > Cond
static ManagedStatic< cl::opt< uint64_t >, CreateSeed > Seed
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallSet class.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
This class holds the attributes for a particular argument, parameter, function, or return value.
Definition Attributes.h:406
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition Attributes.h:125
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator end()
Definition BasicBlock.h:453
iterator begin()
Instruction iterator methods.
Definition BasicBlock.h:440
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
bool empty() const
Definition BasicBlock.h:462
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
bool isEHPad() const
Return true if this basic block is an exception handling block.
Definition BasicBlock.h:683
LLVM_ABI const CallInst * getTerminatingMustTailCall() const
Returns the call instruction marked 'musttail' prior to the terminating return instruction of this ba...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
This class is the base class for the comparison instructions.
Definition InstrTypes.h:728
void setPredicate(Predicate P)
Set the predicate for this instruction to the specified value.
Definition InstrTypes.h:831
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
Conditional Branch instruction.
static CondBrInst * Create(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse, InsertPosition InsertBefore=nullptr)
This is the shared class of boolean and integer constants.
Definition Constants.h:87
This is an important base class in LLVM.
Definition Constant.h:44
Basic Dead Code Elimination pass.
Definition DCE.h:23
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
bool none() const
Definition FMF.h:57
bool all() const
Definition FMF.h:58
Class to represent function types.
ArrayRef< Type * > params() const
const BasicBlock & getEntryBlock() const
Definition Function.h:794
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Module * getParent()
Get the module that this global value is contained inside of...
virtual void mutate(Module &M, RandomIRBuilder &IB)
Definition IRMutator.cpp:37
LLVM_ABI void mutateModule(Module &M, int Seed, size_t MaxSize)
Mutate given module.
Definition IRMutator.cpp:65
static LLVM_ABI size_t getModuleSize(const Module &M)
Calculate the size of module as the number of objects in it, i.e.
Definition IRMutator.cpp:61
static std::vector< fuzzerop::OpDescriptor > getDefaultOps()
Definition IRMutator.cpp:97
void mutate(Function &F, RandomIRBuilder &IB) override
Definition IRMutator.cpp:92
void mutate(BasicBlock &BB, RandomIRBuilder &IB) override
void mutate(BasicBlock &BB, RandomIRBuilder &IB) override
void mutate(BasicBlock &BB, RandomIRBuilder &IB) override
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.
void mutate(Function &F, RandomIRBuilder &IB) override
void mutate(Instruction &Inst, RandomIRBuilder &IB) override
LLVM_ABI void setHasNoUnsignedWrap(bool b=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.
LLVM_ABI bool hasNoNaNs() const LLVM_READONLY
Determine whether the no-NaNs flag is set.
LLVM_ABI bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
LLVM_ABI bool hasNoInfs() const LLVM_READONLY
Determine whether the no-infs flag is set.
LLVM_ABI void setHasNoSignedZeros(bool B)
Set or clear the no-signed-zeros flag on this instruction, which must be an operator which supports t...
LLVM_ABI bool hasNoSignedZeros() const LLVM_READONLY
Determine whether the no-signed-zeros flag is set.
LLVM_ABI bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
LLVM_ABI void setHasAllowContract(bool B)
Set or clear the allow-contract flag on this instruction, which must be an operator which supports th...
LLVM_ABI void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
LLVM_ABI void setHasNoNaNs(bool B)
Set or clear the no-nans flag on this instruction, which must be an operator which supports this flag...
LLVM_ABI void setHasApproxFunc(bool B)
Set or clear the approximate-math-functions flag on this instruction, which must be an operator which...
LLVM_ABI void setHasAllowReassoc(bool B)
Set or clear the reassociation flag on this instruction, which must be an operator which supports thi...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI bool isExact() const LLVM_READONLY
Determine whether the exact flag is set.
bool isTerminator() const
LLVM_ABI bool hasAllowReciprocal() const LLVM_READONLY
Determine whether the allow-reciprocal flag is set.
LLVM_ABI void setHasNoInfs(bool B)
Set or clear the no-infs flag on this instruction, which must be an operator which supports this flag...
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
LLVM_ABI 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.
LLVM_ABI void setIsExact(bool b=true)
Set or clear the exact flag on this instruction, which must be an operator which supports this flag.
LLVM_ABI void setHasAllowReciprocal(bool B)
Set or clear the allow-reciprocal flag on this instruction, which must be an operator which supports ...
LLVM_ABI bool hasAllowContract() const LLVM_READONLY
Determine whether the allow-contract flag is set.
LLVM_ABI void setFast(bool B)
Set or clear all fast-math-flags on this instruction, which must be an operator which supports this f...
LLVM_ABI bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
Class to represent integer types.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
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:68
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition 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.
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs)
Run all of the passes in this manager over the given unit of IR.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition InsertBefore=nullptr)
void mutate(BasicBlock &BB, RandomIRBuilder &IB) override
void mutate(Function &F, RandomIRBuilder &IB) override
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:345
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition SmallSet.h:134
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition SmallSet.h:176
bool empty() const
Definition SmallSet.h:169
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:184
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Multiway switch.
static SwitchInst * Create(Value *Value, BasicBlock *Default, unsigned NumCases, InsertPosition 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:46
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:272
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:296
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
This function has undefined behavior.
void setOperand(unsigned i, Value *Val)
Definition User.h:212
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:549
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
A range adaptor for a pair of iterators.
A raw_ostream that writes to an std::string.
CallInst * Call
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static SourcePred onlyType(Type *Only)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void ReplaceInstWithInst(BasicBlock *BB, BasicBlock::iterator &BI, Instruction *I)
Replace the instruction specified by BI with the instruction specified by I.
LLVM_ABI void describeFuzzerIntOps(std::vector< fuzzerop::OpDescriptor > &Ops)
Getters for the default sets of operations, per general category.
LLVM_ABI Expected< std::unique_ptr< Module > > parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context, ParserCallbacks Callbacks={})
Read the specified bitcode file, returning the module.
LLVM_ABI 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.
LLVM_ABI std::unique_ptr< Module > parseAndVerify(const uint8_t *Data, size_t Size, LLVMContext &Context)
Try to parse module and verify it.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI std::unique_ptr< Module > parseModule(const uint8_t *Data, size_t Size, LLVMContext &Context)
Fuzzer friendly interface for the llvm bitcode parser.
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:649
auto pred_size(const MachineBasicBlock *BB)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI void describeFuzzerAggregateOps(std::vector< fuzzerop::OpDescriptor > &Ops)
LLVM_ABI size_t writeModule(const Module &M, uint8_t *Dest, size_t MaxSize)
Fuzzer friendly interface for the llvm bitcode printer.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
ReservoirSampler< ElT, GenT > makeSampler(GenT &RandGen, RangeT &&Items)
Definition Random.h:75
LLVM_ABI void describeFuzzerVectorOps(std::vector< fuzzerop::OpDescriptor > &Ops)
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:552
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFExpression::Operation Op
LLVM_ABI void describeFuzzerFloatOps(std::vector< fuzzerop::OpDescriptor > &Ops)
PassManager< Function > FunctionPassManager
Convenience typedef for a pass manager over functions.
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI void describeFuzzerControlFlowOps(std::vector< fuzzerop::OpDescriptor > &Ops)
auto predecessors(const MachineBasicBlock *BB)
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
LLVM_ABI void describeFuzzerPointerOps(std::vector< fuzzerop::OpDescriptor > &Ops)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
T uniform(GenT &Gen, T Min, T Max)
Return a uniformly distributed random value between Min and Max.
Definition Random.h:21
constexpr bool isCallableCC(CallingConv::ID CC)
LLVM_ABI bool verifyModule(const Module &M, raw_ostream *OS=nullptr, bool *BrokenDebugInfo=nullptr)
Check a module for errors.
A description of some operation we can build while fuzzing IR.