Go to the documentation of this file.
19 using namespace fuzzerop;
23 return findOrCreateSource(
BB, Insts, {},
anyType());
30 auto MatchesPred = [&Srcs, &Pred](
Instruction *Inst) {
31 return Pred.
matches(Srcs, Inst);
35 RS.sample(
nullptr, 1);
38 return newSource(
BB, Insts, Srcs, Pred);
44 auto RS = makeSampler<Value *>(Rand);
45 RS.sample(Pred.
generate(Srcs, KnownTypes));
48 Value *Ptr = findPointer(
BB, Insts, Srcs, Pred);
51 auto IP =
BB.getFirstInsertionPt();
52 if (
auto *
I = dyn_cast<Instruction>(Ptr)) {
53 IP = ++
I->getIterator();
54 assert(
IP !=
BB.end() &&
"guaranteed by the findPointer");
58 ? RS.getSelection()->getType()
60 auto *NewLoad =
new LoadInst(AccessTy, Ptr,
"L", &*
IP);
63 if (Pred.
matches(Srcs, NewLoad))
64 RS.sample(NewLoad, RS.totalWeight());
66 NewLoad->eraseFromParent();
69 assert(!RS.isEmpty() &&
"Failed to generate sources");
70 return RS.getSelection();
74 const Value *Replacement) {
77 switch (
I->getOpcode()) {
78 case Instruction::GetElementPtr:
79 case Instruction::ExtractElement:
80 case Instruction::ExtractValue:
86 case Instruction::InsertValue:
87 case Instruction::InsertElement:
88 case Instruction::ShuffleVector:
100 auto RS = makeSampler<Use *>(Rand);
101 for (
auto &
I : Insts) {
102 if (isa<IntrinsicInst>(
I))
107 for (
Use &U :
I->operands())
112 RS.sample(
nullptr, 1);
114 if (
Use *
Sink = RS.getSelection()) {
116 unsigned OpNo =
Sink->getOperandNo();
120 newSink(
BB, Insts, V);
139 auto IsMatchingPtr = [&Srcs, &Pred](
Instruction *Inst) {
142 if (Inst->isTerminator())
145 if (
auto *PtrTy = dyn_cast<PointerType>(Inst->getType())) {
146 if (PtrTy->isOpaque())
160 return RS.getSelection();
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Value * findOrCreateSource(BasicBlock &BB, ArrayRef< Instruction * > Insts)
Find a "source" for some operation, which will be used in one of the operation's operands.
This is an optimization pass for GlobalISel generic memory operations.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
Value * findPointer(BasicBlock &BB, ArrayRef< Instruction * > Insts, ArrayRef< Value * > Srcs, fuzzerop::SourcePred Pred)
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getOperandNo() const
Return the operand # of this use in its User.
Type * getNonOpaquePointerElementType() const
Only use this method in code that is not reachable with opaque pointers, or part of deprecated method...
static SourcePred matchFirstType()
Match values that have the same type as the first source.
LLVM Basic Block Representation.
const T & back() const
back - Get the last element.
static SourcePred anyType()
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
An instruction for storing to memory.
T uniform(GenT &Gen, T Min, T Max)
Return a uniformly distributed random value between Min and Max.
void connectToSink(BasicBlock &BB, ArrayRef< Instruction * > Insts, Value *V)
Find a viable user for V in Insts, which should all be contained in BB.
void newSink(BasicBlock &BB, ArrayRef< Instruction * > Insts, Value *V)
Create a user for V in BB.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void setOperand(unsigned i, Value *Val)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Type * getType() const
All values are typed, get the type of this value.
bool matches(ArrayRef< Value * > Cur, const Value *New)
Returns true if New is compatible for the argument after Cur.
An instruction for reading from memory.
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...
ReservoirSampler< ElT, GenT > makeSampler(GenT &RandGen, RangeT &&Items)
A matcher/generator for finding suitable values for the next source in an operation's partially compl...
Value * newSource(BasicBlock &BB, ArrayRef< Instruction * > Insts, ArrayRef< Value * > Srcs, fuzzerop::SourcePred Pred)
Create some Value suitable as a source for some operation.
bool isOpaquePointerTy() const
True if this is an instance of an opaque PointerType.
std::vector< Constant * > generate(ArrayRef< Value * > Cur, ArrayRef< Type * > BaseTypes)
Generates a list of potential values for the argument after Cur.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
an instruction to allocate memory on the stack
static bool isCompatibleReplacement(const Instruction *I, const Use &Operand, const Value *Replacement)
LLVM Value Representation.
bool isFirstClassType() const
Return true if the type is "first class", meaning it is a valid type for a Value.
A Use represents the edge between a Value definition and its users.