Mercurial > hg > CbC > CbC_llvm
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; |