comparison lib/FuzzMutate/RandomIRBuilder.cpp @ 134:3a76565eade5 LLVM5.0.1

update 5.0.1
author mir3636
date Sat, 17 Feb 2018 09:57:20 +0900
parents 803732b1fca8
children c2174574ed3a
comparison
equal deleted inserted replaced
133:c60214abe0e8 134:3a76565eade5
13 #include "llvm/IR/BasicBlock.h" 13 #include "llvm/IR/BasicBlock.h"
14 #include "llvm/IR/Constants.h" 14 #include "llvm/IR/Constants.h"
15 #include "llvm/IR/Function.h" 15 #include "llvm/IR/Function.h"
16 #include "llvm/IR/Instructions.h" 16 #include "llvm/IR/Instructions.h"
17 #include "llvm/IR/IntrinsicInst.h" 17 #include "llvm/IR/IntrinsicInst.h"
18 #include "llvm/IR/Module.h"
19 18
20 using namespace llvm; 19 using namespace llvm;
21 using namespace fuzzerop; 20 using namespace fuzzerop;
22 21
23 Value *RandomIRBuilder::findOrCreateSource(BasicBlock &BB, 22 Value *RandomIRBuilder::findOrCreateSource(BasicBlock &BB,
43 Value *RandomIRBuilder::newSource(BasicBlock &BB, ArrayRef<Instruction *> Insts, 42 Value *RandomIRBuilder::newSource(BasicBlock &BB, ArrayRef<Instruction *> Insts,
44 ArrayRef<Value *> Srcs, SourcePred Pred) { 43 ArrayRef<Value *> Srcs, SourcePred Pred) {
45 // Generate some constants to choose from. 44 // Generate some constants to choose from.
46 auto RS = makeSampler<Value *>(Rand); 45 auto RS = makeSampler<Value *>(Rand);
47 RS.sample(Pred.generate(Srcs, KnownTypes)); 46 RS.sample(Pred.generate(Srcs, KnownTypes));
48 assert(!RS.isEmpty() && "Failed to generate sources");
49 47
50 // If we can find a pointer to load from, use it half the time. 48 // If we can find a pointer to load from, use it half the time.
51 Value *Ptr = findPointer(BB, Insts, Srcs, Pred); 49 Value *Ptr = findPointer(BB, Insts, Srcs, Pred);
52 if (Ptr) 50 if (Ptr) {
53 RS.sample(Ptr, RS.totalWeight()); 51 // Create load from the chosen pointer
52 auto IP = BB.getFirstInsertionPt();
53 if (auto *I = dyn_cast<Instruction>(Ptr)) {
54 IP = ++I->getIterator();
55 assert(IP != BB.end() && "guaranteed by the findPointer");
56 }
57 auto *NewLoad = new LoadInst(Ptr, "L", &*IP);
54 58
55 Value *Result = RS.getSelection(); 59 // Only sample this load if it really matches the descriptor
56 if (Result != Ptr) 60 if (Pred.matches(Srcs, NewLoad))
57 return Result; 61 RS.sample(NewLoad, RS.totalWeight());
62 else
63 NewLoad->eraseFromParent();
64 }
58 65
59 // If we choose the pointer, we need to create a load. 66 assert(!RS.isEmpty() && "Failed to generate sources");
60 auto IP = BB.getFirstInsertionPt(); 67 return RS.getSelection();
61 if (auto *I = dyn_cast<Instruction>(Ptr))
62 IP = ++I->getIterator();
63 return new LoadInst(Ptr, "L", &*IP);
64 } 68 }
65 69
66 static bool isCompatibleReplacement(const Instruction *I, const Use &Operand, 70 static bool isCompatibleReplacement(const Instruction *I, const Use &Operand,
67 const Value *Replacement) { 71 const Value *Replacement) {
68 if (Operand->getType() != Replacement->getType()) 72 if (Operand->getType() != Replacement->getType())
71 case Instruction::GetElementPtr: 75 case Instruction::GetElementPtr:
72 case Instruction::ExtractElement: 76 case Instruction::ExtractElement:
73 case Instruction::ExtractValue: 77 case Instruction::ExtractValue:
74 // TODO: We could potentially validate these, but for now just leave indices 78 // TODO: We could potentially validate these, but for now just leave indices
75 // alone. 79 // alone.
76 if (Operand.getOperandNo() > 1) 80 if (Operand.getOperandNo() >= 1)
77 return false; 81 return false;
78 break; 82 break;
79 case Instruction::InsertValue: 83 case Instruction::InsertValue:
80 case Instruction::InsertElement: 84 case Instruction::InsertElement:
81 if (Operand.getOperandNo() > 2) 85 case Instruction::ShuffleVector:
86 if (Operand.getOperandNo() >= 2)
82 return false; 87 return false;
83 break; 88 break;
84 default: 89 default:
85 break; 90 break;
86 } 91 }
127 132
128 Value *RandomIRBuilder::findPointer(BasicBlock &BB, 133 Value *RandomIRBuilder::findPointer(BasicBlock &BB,
129 ArrayRef<Instruction *> Insts, 134 ArrayRef<Instruction *> Insts,
130 ArrayRef<Value *> Srcs, SourcePred Pred) { 135 ArrayRef<Value *> Srcs, SourcePred Pred) {
131 auto IsMatchingPtr = [&Srcs, &Pred](Instruction *Inst) { 136 auto IsMatchingPtr = [&Srcs, &Pred](Instruction *Inst) {
132 if (auto PtrTy = dyn_cast<PointerType>(Inst->getType())) 137 // Invoke instructions sometimes produce valid pointers but currently
138 // we can't insert loads or stores from them
139 if (isa<TerminatorInst>(Inst))
140 return false;
141
142 if (auto PtrTy = dyn_cast<PointerType>(Inst->getType())) {
143 // We can never generate loads from non first class or non sized types
144 if (!PtrTy->getElementType()->isSized() ||
145 !PtrTy->getElementType()->isFirstClassType())
146 return false;
147
133 // TODO: Check if this is horribly expensive. 148 // TODO: Check if this is horribly expensive.
134 return Pred.matches(Srcs, UndefValue::get(PtrTy->getElementType())); 149 return Pred.matches(Srcs, UndefValue::get(PtrTy->getElementType()));
150 }
135 return false; 151 return false;
136 }; 152 };
137 if (auto RS = makeSampler(Rand, make_filter_range(Insts, IsMatchingPtr))) 153 if (auto RS = makeSampler(Rand, make_filter_range(Insts, IsMatchingPtr)))
138 return RS.getSelection(); 154 return RS.getSelection();
139 return nullptr; 155 return nullptr;