LLVM: lib/FuzzMutate/RandomIRBuilder.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
20
21using namespace llvm;
23
24
25
27 std::vector<BasicBlock *> ret;
30
31
33 return ret;
35 while (Node && Node->getBlock()) {
36 ret.push_back(Node->getBlock());
37
39 }
40 return ret;
41}
42
43
44
47 std::vector<BasicBlock *> ret;
49
50
51 if (!Parent)
52 return ret;
54 ret.push_back(Child->getBlock());
56 while (Idx < ret.size()) {
58 Idx++;
60 ret.push_back(Child->getBlock());
61 }
62 return ret;
63}
64
67
68 BasicBlock *EntryBB = &F->getEntryBlock();
74 return Alloca;
75}
76
77std::pair<GlobalVariable *, bool>
80 auto MatchesPred = [&Srcs, &Pred](GlobalVariable *GV) {
81
82
83 return Pred.matches(Srcs, PoisonValue::get(GV->getValueType()));
84 };
85 bool DidCreate = false;
89 RS.sample(nullptr, 1);
91 if (!GV) {
92 DidCreate = true;
95 TRS.sample(Pred.generate(Srcs, KnownTypes));
98 GV = new GlobalVariable(*M, Ty, false, LinkageTypes::ExternalLinkage, Init,
99 "G", nullptr,
101 M->getDataLayout().getDefaultGlobalsAddressSpace());
102 }
103 return {GV, DidCreate};
104}
105
110
111
113 const Twine &Name,
115 if (M && M->getTargetTriple().isAMDGCN()) {
116
118 if (pointerType && pointerType->getAddressSpace() == 8) {
119
121 Ptr, PointerType::get(M->getContext(), 7), Name + ".ASC", IP);
122 if (NewInsts)
124 return NewPtr;
125 }
126 }
127
128 return Ptr;
129}
130
131
138
139
140static std::pair<Instruction *, SmallVector<Instruction *>>
142 const Twine &LoadName) {
144
146
149
150 return std::make_pair(Load, NewInsts);
151}
152
154
155 for (auto it = NewInsts.rbegin(); it != NewInsts.rend(); ++it) {
156 (*it)->eraseFromParent();
157 }
158}
159
164 bool allowConstant) {
165 auto MatchesPred = [&Srcs, &Pred](Value *V) { return Pred.matches(Srcs, V); };
169 std::shuffle(SrcTys.begin(), SrcTys.end(), Rand);
170 for (uint64_t SrcTy : SrcTys) {
171 switch (SrcTy) {
174 if (!RS.isEmpty()) {
175 return RS.getSelection();
176 }
177 break;
178 }
182 for (uint64_t i = 0; i < F->arg_size(); i++) {
183 Args.push_back(F->getArg(i));
184 }
186 if (!RS.isEmpty()) {
187 return RS.getSelection();
188 }
189 break;
190 }
193 std::shuffle(Dominators.begin(), Dominators.end(), Rand);
197 auto RS =
199
200 if (!RS.isEmpty()) {
201 return RS.getSelection();
202 }
203 }
204 break;
205 }
209 Type *Ty = GV->getValueType();
213
214
216
217
218 if (DidCreate) {
219 if (Pred.matches(Srcs, LoadGV)) {
220 return LoadGV;
221 }
222
224
225 if (GV->use_empty()) {
226 GV->eraseFromParent();
227 }
228 }
229 break;
230 }
232 return newSource(BB, Insts, Srcs, Pred, allowConstant);
233 }
234 default:
237 }
238 }
239 }
241}
242
245 bool allowConstant) {
246
248 RS.sample(Pred.generate(Srcs, KnownTypes));
249
250
252 if (Ptr) {
253
256 IP = ++I->getIterator();
257 assert(IP != BB.end() && "guaranteed by the findPointer");
258 }
259
260 Type *AccessTy = RS.getSelection()->getType();
261
262
263 auto [NewLoad, NewInsts] =
265
266
267 if (Pred.matches(Srcs, NewLoad))
268 RS.sample(NewLoad, RS.totalWeight());
269 else {
270
272 }
273 }
274
275 Value *newSrc = RS.getSelection();
276
277
278
284 newSrc = new LoadInst(Ty, Alloca, "L",
286 } else {
287 newSrc = new LoadInst(Ty, Alloca, "L", &BB);
288 }
289 }
290 return newSrc;
291}
292
294 const Value *Replacement) {
295 unsigned int OperandNo = Operand.getOperandNo();
297 return false;
298 switch (I->getOpcode()) {
299 case Instruction::GetElementPtr:
300 case Instruction::ExtractElement:
301 case Instruction::ExtractValue:
302
303
304 if (OperandNo >= 1)
305 return false;
306 break;
307 case Instruction::InsertValue:
308 case Instruction::InsertElement:
309 case Instruction::ShuffleVector:
310 if (OperandNo >= 2)
311 return false;
312 break;
313
314
315
316 case Instruction::Switch:
317 case Instruction::Br:
318 if (OperandNo >= 1)
319 return false;
320 break;
321 case Instruction::Call:
322 case Instruction::Invoke:
323 case Instruction::CallBr: {
325
326 if (!Callee)
327 return false;
328
329
330
331 if (!Callee->getIntrinsicID() && OperandNo == 0)
332 return false;
333 return !Callee->hasParamAttribute(OperandNo, Attribute::ImmArg);
334 }
335 default:
336 break;
337 }
338 return true;
339}
340
347 std::shuffle(SinkTys.begin(), SinkTys.end(), Rand);
348 auto findSinkAndConnect =
351 for (auto &I : Instructions) {
352 for (Use &U : I->operands())
354 RS.sample(&U, 1);
355 }
356 if (!RS.isEmpty()) {
357 Use *Sink = RS.getSelection();
358 User *U = Sink->getUser();
359 unsigned OpNo = Sink->getOperandNo();
360 U->setOperand(OpNo, V);
362 }
363 return nullptr;
364 };
366 for (uint64_t SinkTy : SinkTys) {
367 switch (SinkTy) {
369 Sink = findSinkAndConnect(Insts);
370 if (Sink)
371 return Sink;
372 break;
375 std::shuffle(Dominators.begin(), Dominators.end(), Rand);
380 I.getModule());
381 }
382 }
383 }
384 break;
385 }
388 std::shuffle(Dominatees.begin(), Dominatees.end(), Rand);
389 for (BasicBlock *Dominee : Dominatees) {
390 std::vector<Instruction *> Instructions;
392 Instructions.push_back(&I);
393 Sink = findSinkAndConnect(Instructions);
394 if (Sink) {
395 return Sink;
396 }
397 }
398 break;
399 }
401
402 return newSink(BB, Insts, V);
405 auto [GV, DidCreate] =
408 }
410 default:
412 }
413 }
415}
416
420 if (!Ptr) {
422 Type *Ty = V->getType();
424 } else {
426 }
427 }
428
431}
432
435 auto IsMatchingPtr = [](Instruction *Inst) {
436
437
438 if (Inst->isTerminator())
439 return false;
440
441 return Inst->getType()->isPointerTy();
442 };
444 return RS.getSelection();
445 return nullptr;
446}
447
452
456
458 for (uint64_t i = 0; i < ArgNum; i++) {
460 }
461
463 false),
465 return F;
466}
471
475
476
477
481 Type *RetTy = F->getReturnType();
484 new AllocaInst(RetTy, DL.getAllocaAddrSpace(), "RP", BB);
487 } else {
489 }
490
491 return F;
492}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
static bool isCompatibleReplacement(const Instruction *I, const Use &Operand, const Value *Replacement)
Definition RandomIRBuilder.cpp:293
static Value * buildTargetLegalPtr(Module *M, Value *Ptr, InsertPosition IP, const Twine &Name, SmallVector< Instruction * > *NewInsts)
Definition RandomIRBuilder.cpp:112
static void eraseNewInstructions(SmallVector< Instruction * > &NewInsts)
Definition RandomIRBuilder.cpp:153
static std::pair< Instruction *, SmallVector< Instruction * > > buildTargetLegalLoad(Type *AccessTy, Value *Ptr, InsertPosition IP, Module *M, const Twine &LoadName)
Definition RandomIRBuilder.cpp:141
static Instruction * buildTargetLegalStore(Value *Val, Value *Ptr, InsertPosition IP, Module *M)
Definition RandomIRBuilder.cpp:132
static std::vector< BasicBlock * > getDominators(BasicBlock *BB)
Return a vector of Blocks that dominates this block, excluding current block.
Definition RandomIRBuilder.cpp:26
static std::vector< BasicBlock * > getDominatees(BasicBlock *BB)
Return a vector of Blocks that is dominated by this block, excluding current block.
Definition RandomIRBuilder.cpp:45
This class represents a conversion between pointers from one address space to another.
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.
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.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
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...
LLVM_ABI const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
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 LLVM_ABI 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.
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 LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
static LLVM_ABI 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)
reverse_iterator rbegin()
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
LLVM_ABI 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...
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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
DomTreeNodeBase< BasicBlock > DomTreeNode
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...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
T uniform(GenT &Gen, T Min, T Max)
Return a uniformly distributed random value between Min and Max.
LLVM_ABI Function * createFunctionDeclaration(Module &M, uint64_t ArgNum)
Definition RandomIRBuilder.cpp:453
SmallVector< Type *, 16 > KnownTypes
LLVM_ABI std::pair< GlobalVariable *, bool > findOrCreateGlobalVariable(Module *M, ArrayRef< Value * > Srcs, fuzzerop::SourcePred Pred)
Find or create a global variable.
Definition RandomIRBuilder.cpp:78
LLVM_ABI Value * findOrCreateSource(BasicBlock &BB, ArrayRef< Instruction * > Insts)
Find a "source" for some operation, which will be used in one of the operation's operands.
Definition RandomIRBuilder.cpp:106
LLVM_ABI 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.
Definition RandomIRBuilder.cpp:65
LLVM_ABI Instruction * newSink(BasicBlock &BB, ArrayRef< Instruction * > Insts, Value *V)
Create a user for V in BB.
Definition RandomIRBuilder.cpp:417
LLVM_ABI Function * createFunctionDefinition(Module &M, uint64_t ArgNum)
Definition RandomIRBuilder.cpp:472
LLVM_ABI 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.
Definition RandomIRBuilder.cpp:243
LLVM_ABI Instruction * connectToSink(BasicBlock &BB, ArrayRef< Instruction * > Insts, Value *V)
Find a viable user for V in Insts, which should all be contained in BB.
Definition RandomIRBuilder.cpp:341
@ SinkToInstInCurBlock
TODO: Also consider pointers in function argument.
LLVM_ABI Value * findPointer(BasicBlock &BB, ArrayRef< Instruction * > Insts)
Definition RandomIRBuilder.cpp:433
LLVM_ABI Type * randomType()
Return a uniformly choosen type from AllowedTypes.
Definition RandomIRBuilder.cpp:448