45 auto RS = makeSampler<Function *>(IB.Rand);
47 if (!
F.isDeclaration())
66 std::vector<Type *> Types;
67 for (
const auto &Getter : AllowedTypes)
68 Types.push_back(Getter(M.getContext()));
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();
77 Strategy->mutate(M, IB);
95 std::vector<fuzzerop::OpDescriptor> Ops;
105std::optional<fuzzerop::OpDescriptor>
108 return Op.SourcePreds[0].matches({}, Src);
120 if (Insts.
size() < 1)
124 size_t IP = uniform<size_t>(IB.Rand, 0, Insts.
size() - 1);
131 Srcs.
push_back(IB.findOrCreateSource(BB, InstsBefore));
135 auto OpDesc = chooseOperation(Srcs[0], IB);
140 for (
const auto &Pred :
ArrayRef(OpDesc->SourcePreds).
slice(1))
141 Srcs.
push_back(IB.findOrCreateSource(BB, InstsBefore, Srcs, Pred));
143 if (
Value *Op = OpDesc->BuilderFunc(Srcs, Insts[IP])) {
145 IB.connectToSink(BB, InstsAfter, Op);
152 if (CurrentSize > MaxSize - 200)
153 return CurrentWeight ? CurrentWeight * 100 : 1;
156 int64_t Line = (-2 *
static_cast<int64_t
>(CurrentWeight)) *
157 (
static_cast<int64_t
>(MaxSize) -
158 static_cast<int64_t
>(CurrentSize) - 1000) /
167 auto RS = makeSampler<Instruction *>(IB.Rand);
170 if (Inst.isTerminator() || Inst.isEHPad() || Inst.isSwiftError() ||
180 mutate(*RS.getSelection(), IB);
198 auto RS = makeSampler<Value *>(IB.Rand);
203 if (Pred.matches({}, &*
I))
208 RS.sample(IB.newSource(*BB, InstsBefore, {}, Pred), 1);
216 SmallVector<std::function<void()>, 8> Modifications;
223 case Instruction::Add:
224 case Instruction::Mul:
225 case Instruction::Sub:
226 case Instruction::Shl:
227 Modifications.push_back(
229 Modifications.push_back(
232 case Instruction::ICmp:
233 CI = cast<ICmpInst>(&Inst);
236 Modifications.push_back(
241 case Instruction::GetElementPtr:
242 GEP = cast<GetElementPtrInst>(&Inst);
243 Modifications.push_back(
244 [
GEP]() {
GEP->setIsInBounds(!
GEP->isInBounds()); });
247 case Instruction::UDiv:
248 case Instruction::SDiv:
249 case Instruction::LShr:
250 case Instruction::AShr:
254 case Instruction::FCmp:
255 CI = cast<ICmpInst>(&Inst);
258 Modifications.push_back(
265 if (isa<FPMathOperator>(&Inst)) {
267 Modifications.push_back(
270 Modifications.push_back(
273 Modifications.push_back(
277 Modifications.push_back(
279 Modifications.push_back(
281 Modifications.push_back(
283 Modifications.push_back(
288 std::pair<int, int> NoneItem({-1, -1}), ShuffleItems(NoneItem);
290 case Instruction::SDiv:
291 case Instruction::UDiv:
292 case Instruction::SRem:
293 case Instruction::URem:
294 case Instruction::FDiv:
295 case Instruction::FRem: {
299 if (
Constant *
C = dyn_cast<Constant>(Operand)) {
300 if (!
C->isZeroValue()) {
301 ShuffleItems = {0, 1};
306 case Instruction::Select:
307 ShuffleItems = {1, 2};
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};
327 if (ShuffleItems != NoneItem) {
328 Modifications.push_back([&Inst, &ShuffleItems]() {
346 tmp = uniform<uint64_t>(IB.Rand, 0, MaxValue);
347 }
while (CasesTaken.
count(tmp) != 0);
356 if (Insts.
size() < 1)
360 uint64_t IP = uniform<uint64_t>(IB.Rand, 0, Insts.
size() - 1);
373 if (uniform<uint64_t>(IB.Rand, 0, 1)) {
378 IB.findOrCreateSource(*Source, InstsBeforeSplit, {},
384 connectBlocksToSink({IfTrue, IfFalse}, Sink, IB);
390 return Ty->isIntegerTy();
392 assert(RS &&
"There is no integer type in all allowed types, is the "
394 Type *Ty = RS.getSelection();
401 Value *
Cond = IB.findOrCreateSource(*Source, InstsBeforeSplit, {},
404 uint64_t NumCases = uniform<uint64_t>(IB.Rand, 1, MaxNumCases);
405 NumCases = (NumCases > MaxCaseVal) ? MaxCaseVal + 1 : NumCases;
413 for (
uint64_t i = 0; i < NumCases; i++) {
417 Switch->addCase(OnValue, CaseBlock);
418 Blocks.push_back(CaseBlock);
422 connectBlocksToSink(Blocks, Sink, IB);
431 uint64_t DirectSinkIdx = uniform<uint64_t>(IB.Rand, 0, Blocks.
size() - 1);
434 CFGToSink ToSink = (i == DirectSinkIdx)
435 ? CFGToSink::DirectSink
436 :
static_cast<CFGToSink
>(uniform<uint64_t>(
437 IB.Rand, 0, CFGToSink::EndOfCFGToLink - 1));
442 case CFGToSink::Return: {
444 Value *RetValue =
nullptr;
445 if (!
RetTy->isVoidTy())
451 case CFGToSink::DirectSink: {
455 case CFGToSink::SinkOrSelfLoop: {
458 uint64_t coin = uniform<uint64_t>(
IB.Rand, 0, 1);
464 case CFGToSink::EndOfCFGToLink:
474 Type *Ty = IB.randomType();
480 Value *Src = IncomingValues[Pred];
484 for (
auto I = Pred->begin();
I != Pred->end(); ++
I)
489 IncomingValues[Pred] = Src;
491 PHI->addIncoming(Src, Pred);
496 IB.connectToSink(BB, InstsAfter,
PHI);
508 if (Insts.
size() < 1)
519 IB.connectToSink(BB, InstsAfter, Inst);
531 I.removeFromParent();
538 for (
Value *O :
I->operands()) {
548 for (
Value *U :
I->users()) {
558 if (!hasAliveParent(
I))
562 while (!Roots.
empty()) {
563 auto RS = makeSampler<Instruction *>(IB.Rand);
568 AliveInsts.
erase(Root);
570 for (
Instruction *Child : getAliveChildren(Root)) {
571 if (!hasAliveParent(Child)) {
580 I->insertBefore(Terminator);
589 return std::make_unique<Module>(
"M",
Context);
597 if (
Error E = M.takeError()) {
601 return std::move(M.get());
610 if (Buf.size() > MaxSize)
612 memcpy(Dest, Buf.data(), Buf.size());
SmallVector< MachineOperand, 4 > Cond
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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
static void createEmptyFunction(Module &M)
static void eliminateDeadCode(Function &F)
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.
print must be executed print the must be executed context for all instructions
FunctionAnalysisManager FAM
static ManagedStatic< cl::opt< uint64_t >, CreateSeed > Seed
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet class.
A container for analyses that lazily runs them and caches their results.
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
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.
LLVM Basic Block Representation.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Instruction & front() const
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const Function * getParent() const
Return the enclosing method, or null if none.
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...
Conditional or Unconditional Branch instruction.
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
This class is the base class for the comparison instructions.
void setPredicate(Predicate P)
Set the predicate for this instruction to the specified value.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
This is the shared class of boolean and integer constants.
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.
This is an important base class in LLVM.
Basic Dead Code Elimination pass.
Lightweight error class with error context and mandatory checking.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
const BasicBlock & getEntryBlock() const
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...
@ ExternalLinkage
Externally visible function.
virtual void mutate(Module &M, RandomIRBuilder &IB)
void mutateModule(Module &M, int Seed, size_t CurSize, size_t MaxSize)
static std::vector< fuzzerop::OpDescriptor > getDefaultOps()
void mutate(Function &F, 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
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
bool isExact() const LLVM_READONLY
Determine whether the exact flag is set.
bool isTerminator() const
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.
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.
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.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
This is an important class for using LLVM in a threaded context.
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.
LLVMContext & getContext() const
Get the global data context.
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.
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same< PassT, PassManager >::value > 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, Instruction *InsertBefore=nullptr)
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
void mutate(BasicBlock &BB, RandomIRBuilder &IB) override
void mutate(Function &F, RandomIRBuilder &IB) override
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
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.
static IntegerType * getInt1Ty(LLVMContext &C)
static Type * getVoidTy(LLVMContext &C)
bool isVoidTy() const
Return true if this is 'void'.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
self_iterator getIterator()
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
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)
This is an optimization pass for GlobalISel generic memory operations.
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.
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.
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.
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...
void describeFuzzerAggregateOps(std::vector< fuzzerop::OpDescriptor > &Ops)
size_t writeModule(const Module &M, uint8_t *Dest, size_t MaxSize)
Fuzzer friendly interface for the llvm bitcode printer.
ReservoirSampler< ElT, GenT > makeSampler(GenT &RandGen, RangeT &&Items)
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...
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void describeFuzzerFloatOps(std::vector< fuzzerop::OpDescriptor > &Ops)
void describeFuzzerControlFlowOps(std::vector< fuzzerop::OpDescriptor > &Ops)
auto predecessors(const MachineBasicBlock *BB)
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
void describeFuzzerPointerOps(std::vector< fuzzerop::OpDescriptor > &Ops)
unsigned pred_size(const MachineBasicBlock *BB)
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.