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