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)) {
234 newSrc =
new LoadInst(Ty, Alloca,
"L",
237 newSrc =
new LoadInst(Ty, Alloca,
"L", &BB);
244 const Value *Replacement) {
248 switch (
I->getOpcode()) {
249 case Instruction::GetElementPtr:
250 case Instruction::ExtractElement:
251 case Instruction::ExtractValue:
257 case Instruction::InsertValue:
258 case Instruction::InsertElement:
259 case Instruction::ShuffleVector:
266 case Instruction::Switch:
267 case Instruction::Br:
271 case Instruction::Call:
272 case Instruction::Invoke:
273 case Instruction::CallBr: {
274 const Function *Callee = cast<CallBase>(
I)->getCalledFunction();
281 if (!Callee->getIntrinsicID() && OperandNo == 0)
283 return !Callee->hasParamAttribute(OperandNo, Attribute::ImmArg);
298 auto findSinkAndConnect =
300 auto RS = makeSampler<Use *>(
Rand);
301 for (
auto &
I : Instructions) {
302 for (
Use &U :
I->operands())
307 Use *Sink = RS.getSelection();
308 User *U = Sink->getUser();
309 unsigned OpNo = Sink->getOperandNo();
310 U->setOperand(OpNo, V);
311 return cast<Instruction>(U);
319 Sink = findSinkAndConnect(Insts);
325 std::shuffle(Dominators.begin(), Dominators.end(),
Rand);
328 if (isa<PointerType>(
I.getType()))
336 std::shuffle(Dominatees.begin(), Dominatees.end(),
Rand);
338 std::vector<Instruction *> Instructions;
340 Instructions.push_back(&
I);
341 Sink = findSinkAndConnect(Instructions);
353 auto [GV, DidCreate] =
370 Type *Ty = V->getType();
385 if (Inst->isTerminator())
391 return RS.getSelection();
405 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.
InstListType::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 PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition 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)
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.
self_iterator getIterator()
#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.