23using namespace fuzzerop;
28 std::vector<BasicBlock *> ret;
37 ret.push_back(
Node->getBlock());
48 std::vector<BasicBlock *> ret;
55 ret.push_back(Child->getBlock());
57 while (
Idx < ret.size()) {
61 ret.push_back(Child->getBlock());
78std::pair<GlobalVariable *, bool>
86 bool DidCreate =
false;
92 RS.sample(
nullptr, 1);
97 auto TRS = makeSampler<Constant *>(
Rand);
104 M->getDataLayout().getDefaultGlobalsAddressSpace());
106 return {GV, DidCreate};
118 bool allowConstant) {
119 auto MatchesPred = [&Srcs, &Pred](
Value *V) {
return Pred.
matches(Srcs, V); };
129 return RS.getSelection();
136 for (
uint64_t i = 0; i <
F->arg_size(); i++) {
137 Args.push_back(
F->getArg(i));
141 return RS.getSelection();
147 std::shuffle(Dominators.begin(), Dominators.end(),
Rand);
151 Instructions.push_back(&
I);
157 return RS.getSelection();
165 Type *Ty = GV->getValueType();
170 LoadGV =
new LoadInst(Ty, GV,
"LGV", &BB);
175 if (Pred.
matches(Srcs, LoadGV)) {
180 if (GV->use_empty()) {
181 GV->eraseFromParent();
187 return newSource(BB, Insts, Srcs, Pred, allowConstant);
200 bool allowConstant) {
202 auto RS = makeSampler<Value *>(
Rand);
210 if (
auto *
I = dyn_cast<Instruction>(
Ptr)) {
211 IP = ++
I->getIterator();
212 assert(IP != BB.
end() &&
"guaranteed by the findPointer");
215 Type *AccessTy = RS.getSelection()->getType();
216 auto *NewLoad =
new LoadInst(AccessTy,
Ptr,
"L", &*IP);
219 if (Pred.
matches(Srcs, NewLoad))
220 RS.sample(NewLoad, RS.totalWeight());
222 NewLoad->eraseFromParent();
225 Value *newSrc = RS.getSelection();
229 if (!allowConstant && isa<Constant>(newSrc)) {
236 newSrc =
new LoadInst(Ty, Alloca,
"L", &BB);
243 const Value *Replacement) {
247 switch (
I->getOpcode()) {
248 case Instruction::GetElementPtr:
249 case Instruction::ExtractElement:
250 case Instruction::ExtractValue:
256 case Instruction::InsertValue:
257 case Instruction::InsertElement:
258 case Instruction::ShuffleVector:
265 case Instruction::Switch:
266 case Instruction::Br:
270 case Instruction::Call:
271 case Instruction::Invoke:
272 case Instruction::CallBr: {
273 const Function *Callee = cast<CallBase>(
I)->getCalledFunction();
280 if (!Callee->getIntrinsicID() && OperandNo == 0)
282 return !Callee->hasParamAttribute(OperandNo, Attribute::ImmArg);
297 auto findSinkAndConnect =
299 auto RS = makeSampler<Use *>(
Rand);
300 for (
auto &
I : Instructions) {
301 for (
Use &U :
I->operands())
306 Use *Sink = RS.getSelection();
307 User *U = Sink->getUser();
308 unsigned OpNo = Sink->getOperandNo();
309 U->setOperand(OpNo, V);
310 return cast<Instruction>(U);
318 Sink = findSinkAndConnect(Insts);
324 std::shuffle(Dominators.begin(), Dominators.end(),
Rand);
327 if (isa<PointerType>(
I.getType()))
335 std::shuffle(Dominatees.begin(), Dominatees.end(),
Rand);
337 std::vector<Instruction *> Instructions;
339 Instructions.push_back(&
I);
340 Sink = findSinkAndConnect(Instructions);
352 auto [GV, DidCreate] =
369 Type *Ty = V->getType();
384 if (Inst->isTerminator())
390 return RS.getSelection();
404 for (
uint64_t i = 0; i < ArgNum; i++) {
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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
Module.h This file contains the declarations for the Module class.
static bool isCompatibleReplacement(const Instruction *I, const Use &Operand, const Value *Replacement)
static std::vector< BasicBlock * > getDominators(BasicBlock *BB)
Return a vector of Blocks that dominates this block, excluding current block.
static std::vector< BasicBlock * > getDominatees(BasicBlock *BB)
Return a vector of Blocks that is dominated by this block, excluding current block.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
an instruction to allocate memory on the stack
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & back() const
back - Get the last element.
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...
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...
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
iterator_range< iterator > children()
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Module * getParent()
Get the module that this global value is contained inside of...
LinkageTypes
An enumeration for the kinds of linkage for global values.
@ ExternalLinkage
Externally visible function.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
A Module instance is used to store all the information related to an LLVM module.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isPointerTy() const
True if this is an instance of PointerType.
static Type * getVoidTy(LLVMContext &C)
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
unsigned getOperandNo() const
Return the operand # of this use in its User.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
A matcher/generator for finding suitable values for the next source in an operation's partially compl...
bool matches(ArrayRef< Value * > Cur, const Value *New)
Returns true if New is compatible for the argument after Cur.
std::vector< Constant * > generate(ArrayRef< Value * > Cur, ArrayRef< Type * > BaseTypes)
Generates a list of potential values for the argument after Cur.
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static SourcePred onlyType(Type *Only)
static SourcePred anyType()
This is an optimization pass for GlobalISel generic memory operations.
ReservoirSampler< ElT, GenT > makeSampler(GenT &RandGen, RangeT &&Items)
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...
T uniform(GenT &Gen, T Min, T Max)
Return a uniformly distributed random value between Min and Max.
Function * createFunctionDeclaration(Module &M, uint64_t ArgNum)
SmallVector< Type *, 16 > KnownTypes
std::pair< GlobalVariable *, bool > findOrCreateGlobalVariable(Module *M, ArrayRef< Value * > Srcs, fuzzerop::SourcePred Pred)
Find or create a global variable.
Value * findOrCreateSource(BasicBlock &BB, ArrayRef< Instruction * > Insts)
Find a "source" for some operation, which will be used in one of the operation's operands.
AllocaInst * createStackMemory(Function *F, Type *Ty, Value *Init=nullptr)
Create a stack memory at the head of the function, store Init to the memory if provided.
Instruction * newSink(BasicBlock &BB, ArrayRef< Instruction * > Insts, Value *V)
Create a user for V in BB.
Function * createFunctionDefinition(Module &M, uint64_t ArgNum)
Value * newSource(BasicBlock &BB, ArrayRef< Instruction * > Insts, ArrayRef< Value * > Srcs, fuzzerop::SourcePred Pred, bool allowConstant=true)
Create some Value suitable as a source for some operation.
Instruction * connectToSink(BasicBlock &BB, ArrayRef< Instruction * > Insts, Value *V)
Find a viable user for V in Insts, which should all be contained in BB.
@ SinkToInstInCurBlock
TODO: Also consider pointers in function argument.
Value * findPointer(BasicBlock &BB, ArrayRef< Instruction * > Insts)
Type * randomType()
Return a uniformly choosen type from AllowedTypes.