1 //===-- llvm-stress.cpp - Generate random LL files to stress-test LLVM ----===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This program is a utility that generates random .ll files to stress-test 11 // different components in LLVM. 12 // 13 //===----------------------------------------------------------------------===// 14 #include "llvm/LLVMContext.h" 15 #include "llvm/Module.h" 16 #include "llvm/PassManager.h" 17 #include "llvm/Constants.h" 18 #include "llvm/Instruction.h" 19 #include "llvm/CallGraphSCCPass.h" 20 #include "llvm/Assembly/PrintModulePass.h" 21 #include "llvm/Analysis/Verifier.h" 22 #include "llvm/Support/PassNameParser.h" 23 #include "llvm/Support/Debug.h" 24 #include "llvm/Support/ManagedStatic.h" 25 #include "llvm/Support/PluginLoader.h" 26 #include "llvm/Support/PrettyStackTrace.h" 27 #include "llvm/Support/ToolOutputFile.h" 28 #include <memory> 29 #include <sstream> 30 #include <set> 31 #include <vector> 32 #include <algorithm> 33 using namespace llvm; 34 35 static cl::opt<unsigned> SeedCL("seed", 36 cl::desc("Seed used for randomness"), cl::init(0)); 37 static cl::opt<unsigned> SizeCL("size", 38 cl::desc("The estimated size of the generated function (# of instrs)"), 39 cl::init(100)); 40 static cl::opt<std::string> 41 OutputFilename("o", cl::desc("Override output filename"), 42 cl::value_desc("filename")); 43 44 static cl::opt<bool> GenHalfFloat("generate-half-float", 45 cl::desc("Generate half-length floating-point values"), cl::init(false)); 46 static cl::opt<bool> GenX86FP80("generate-x86-fp80", 47 cl::desc("Generate 80-bit X86 floating-point values"), cl::init(false)); 48 static cl::opt<bool> GenFP128("generate-fp128", 49 cl::desc("Generate 128-bit floating-point values"), cl::init(false)); 50 static cl::opt<bool> GenPPCFP128("generate-ppc-fp128", 51 cl::desc("Generate 128-bit PPC floating-point values"), cl::init(false)); 52 static cl::opt<bool> GenX86MMX("generate-x86-mmx", 53 cl::desc("Generate X86 MMX floating-point values"), cl::init(false)); 54 55 /// A utility class to provide a pseudo-random number generator which is 56 /// the same across all platforms. This is somewhat close to the libc 57 /// implementation. Note: This is not a cryptographically secure pseudorandom 58 /// number generator. 59 class Random { 60 public: 61 /// C'tor 62 Random(unsigned _seed):Seed(_seed) {} 63 64 /// Return a random integer, up to a 65 /// maximum of 2**19 - 1. 66 uint32_t Rand() { 67 uint32_t Val = Seed + 0x000b07a1; 68 Seed = (Val * 0x3c7c0ac1); 69 // Only lowest 19 bits are random-ish. 70 return Seed & 0x7ffff; 71 } 72 73 /// Return a random 32 bit integer. 74 uint32_t Rand32() { 75 uint32_t Val = Rand(); 76 Val &= 0xffff; 77 return Val | (Rand() << 16); 78 } 79 80 /// Return a random 64 bit integer. 81 uint64_t Rand64() { 82 uint64_t Val = Rand32(); 83 return Val | (uint64_t(Rand32()) << 32); 84 } 85 private: 86 unsigned Seed; 87 }; 88 89 /// Generate an empty function with a default argument list. 90 Function *GenEmptyFunction(Module *M) { 91 // Type Definitions 92 std::vector<Type*> ArgsTy; 93 // Define a few arguments 94 LLVMContext &Context = M->getContext(); 95 ArgsTy.push_back(PointerType::get(IntegerType::getInt8Ty(Context), 0)); 96 ArgsTy.push_back(PointerType::get(IntegerType::getInt32Ty(Context), 0)); 97 ArgsTy.push_back(PointerType::get(IntegerType::getInt64Ty(Context), 0)); 98 ArgsTy.push_back(IntegerType::getInt32Ty(Context)); 99 ArgsTy.push_back(IntegerType::getInt64Ty(Context)); 100 ArgsTy.push_back(IntegerType::getInt8Ty(Context)); 101 102 FunctionType *FuncTy = FunctionType::get(Type::getVoidTy(Context), ArgsTy, 0); 103 // Pick a unique name to describe the input parameters 104 std::stringstream ss; 105 ss<<"autogen_SD"<<SeedCL; 106 Function *Func = Function::Create(FuncTy, GlobalValue::ExternalLinkage, 107 ss.str(), M); 108 109 Func->setCallingConv(CallingConv::C); 110 return Func; 111 } 112 113 /// A base class, implementing utilities needed for 114 /// modifying and adding new random instructions. 115 struct Modifier { 116 /// Used to store the randomly generated values. 117 typedef std::vector<Value*> PieceTable; 118 119 public: 120 /// C'tor 121 Modifier(BasicBlock *Block, PieceTable *PT, Random *R): 122 BB(Block),PT(PT),Ran(R),Context(BB->getContext()) {} 123 /// Add a new instruction. 124 virtual void Act() = 0; 125 /// Add N new instructions, 126 virtual void ActN(unsigned n) { 127 for (unsigned i=0; i<n; ++i) 128 Act(); 129 } 130 131 protected: 132 /// Return a random value from the list of known values. 133 Value *getRandomVal() { 134 assert(PT->size()); 135 return PT->at(Ran->Rand() % PT->size()); 136 } 137 138 Constant *getRandomConstant(Type *Tp) { 139 if (Tp->isIntegerTy()) { 140 if (Ran->Rand() & 1) 141 return ConstantInt::getAllOnesValue(Tp); 142 return ConstantInt::getNullValue(Tp); 143 } else if (Tp->isFloatingPointTy()) { 144 if (Ran->Rand() & 1) 145 return ConstantFP::getAllOnesValue(Tp); 146 return ConstantFP::getNullValue(Tp); 147 } 148 return UndefValue::get(Tp); 149 } 150 151 /// Return a random value with a known type. 152 Value *getRandomValue(Type *Tp) { 153 unsigned index = Ran->Rand(); 154 for (unsigned i=0; i<PT->size(); ++i) { 155 Value *V = PT->at((index + i) % PT->size()); 156 if (V->getType() == Tp) 157 return V; 158 } 159 160 // If the requested type was not found, generate a constant value. 161 if (Tp->isIntegerTy()) { 162 if (Ran->Rand() & 1) 163 return ConstantInt::getAllOnesValue(Tp); 164 return ConstantInt::getNullValue(Tp); 165 } else if (Tp->isFloatingPointTy()) { 166 if (Ran->Rand() & 1) 167 return ConstantFP::getAllOnesValue(Tp); 168 return ConstantFP::getNullValue(Tp); 169 } else if (Tp->isVectorTy()) { 170 VectorType *VTp = cast<VectorType>(Tp); 171 172 std::vector<Constant*> TempValues; 173 TempValues.reserve(VTp->getNumElements()); 174 for (unsigned i = 0; i < VTp->getNumElements(); ++i) 175 TempValues.push_back(getRandomConstant(VTp->getScalarType())); 176 177 ArrayRef<Constant*> VectorValue(TempValues); 178 return ConstantVector::get(VectorValue); 179 } 180 181 return UndefValue::get(Tp); 182 } 183 184 /// Return a random value of any pointer type. 185 Value *getRandomPointerValue() { 186 unsigned index = Ran->Rand(); 187 for (unsigned i=0; i<PT->size(); ++i) { 188 Value *V = PT->at((index + i) % PT->size()); 189 if (V->getType()->isPointerTy()) 190 return V; 191 } 192 return UndefValue::get(pickPointerType()); 193 } 194 195 /// Return a random value of any vector type. 196 Value *getRandomVectorValue() { 197 unsigned index = Ran->Rand(); 198 for (unsigned i=0; i<PT->size(); ++i) { 199 Value *V = PT->at((index + i) % PT->size()); 200 if (V->getType()->isVectorTy()) 201 return V; 202 } 203 return UndefValue::get(pickVectorType()); 204 } 205 206 /// Pick a random type. 207 Type *pickType() { 208 return (Ran->Rand() & 1 ? pickVectorType() : pickScalarType()); 209 } 210 211 /// Pick a random pointer type. 212 Type *pickPointerType() { 213 Type *Ty = pickType(); 214 return PointerType::get(Ty, 0); 215 } 216 217 /// Pick a random vector type. 218 Type *pickVectorType(unsigned len = (unsigned)-1) { 219 // Pick a random vector width in the range 2**0 to 2**4. 220 // by adding two randoms we are generating a normal-like distribution 221 // around 2**3. 222 unsigned width = 1<<((Ran->Rand() % 3) + (Ran->Rand() % 3)); 223 Type *Ty; 224 225 // Vectors of x86mmx are illegal; keep trying till we get something else. 226 do { 227 Ty = pickScalarType(); 228 } while (Ty->isX86_MMXTy()); 229 230 if (len != (unsigned)-1) 231 width = len; 232 return VectorType::get(Ty, width); 233 } 234 235 /// Pick a random scalar type. 236 Type *pickScalarType() { 237 Type *t = 0; 238 do { 239 switch (Ran->Rand() % 30) { 240 case 0: t = Type::getInt1Ty(Context); break; 241 case 1: t = Type::getInt8Ty(Context); break; 242 case 2: t = Type::getInt16Ty(Context); break; 243 case 3: case 4: 244 case 5: t = Type::getFloatTy(Context); break; 245 case 6: case 7: 246 case 8: t = Type::getDoubleTy(Context); break; 247 case 9: case 10: 248 case 11: t = Type::getInt32Ty(Context); break; 249 case 12: case 13: 250 case 14: t = Type::getInt64Ty(Context); break; 251 case 15: case 16: 252 case 17: if (GenHalfFloat) t = Type::getHalfTy(Context); break; 253 case 18: case 19: 254 case 20: if (GenX86FP80) t = Type::getX86_FP80Ty(Context); break; 255 case 21: case 22: 256 case 23: if (GenFP128) t = Type::getFP128Ty(Context); break; 257 case 24: case 25: 258 case 26: if (GenPPCFP128) t = Type::getPPC_FP128Ty(Context); break; 259 case 27: case 28: 260 case 29: if (GenX86MMX) t = Type::getX86_MMXTy(Context); break; 261 default: llvm_unreachable("Invalid scalar value"); 262 } 263 } while (t == 0); 264 265 return t; 266 } 267 268 /// Basic block to populate 269 BasicBlock *BB; 270 /// Value table 271 PieceTable *PT; 272 /// Random number generator 273 Random *Ran; 274 /// Context 275 LLVMContext &Context; 276 }; 277 278 struct LoadModifier: public Modifier { 279 LoadModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 280 virtual void Act() { 281 // Try to use predefined pointers. If non exist, use undef pointer value; 282 Value *Ptr = getRandomPointerValue(); 283 Value *V = new LoadInst(Ptr, "L", BB->getTerminator()); 284 PT->push_back(V); 285 } 286 }; 287 288 struct StoreModifier: public Modifier { 289 StoreModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 290 virtual void Act() { 291 // Try to use predefined pointers. If non exist, use undef pointer value; 292 Value *Ptr = getRandomPointerValue(); 293 Type *Tp = Ptr->getType(); 294 Value *Val = getRandomValue(Tp->getContainedType(0)); 295 Type *ValTy = Val->getType(); 296 297 // Do not store vectors of i1s because they are unsupported 298 // by the codegen. 299 if (ValTy->isVectorTy() && ValTy->getScalarSizeInBits() == 1) 300 return; 301 302 new StoreInst(Val, Ptr, BB->getTerminator()); 303 } 304 }; 305 306 struct BinModifier: public Modifier { 307 BinModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 308 309 virtual void Act() { 310 Value *Val0 = getRandomVal(); 311 Value *Val1 = getRandomValue(Val0->getType()); 312 313 // Don't handle pointer types. 314 if (Val0->getType()->isPointerTy() || 315 Val1->getType()->isPointerTy()) 316 return; 317 318 // Don't handle i1 types. 319 if (Val0->getType()->getScalarSizeInBits() == 1) 320 return; 321 322 323 bool isFloat = Val0->getType()->getScalarType()->isFloatingPointTy(); 324 Instruction* Term = BB->getTerminator(); 325 unsigned R = Ran->Rand() % (isFloat ? 7 : 13); 326 Instruction::BinaryOps Op; 327 328 switch (R) { 329 default: llvm_unreachable("Invalid BinOp"); 330 case 0:{Op = (isFloat?Instruction::FAdd : Instruction::Add); break; } 331 case 1:{Op = (isFloat?Instruction::FSub : Instruction::Sub); break; } 332 case 2:{Op = (isFloat?Instruction::FMul : Instruction::Mul); break; } 333 case 3:{Op = (isFloat?Instruction::FDiv : Instruction::SDiv); break; } 334 case 4:{Op = (isFloat?Instruction::FDiv : Instruction::UDiv); break; } 335 case 5:{Op = (isFloat?Instruction::FRem : Instruction::SRem); break; } 336 case 6:{Op = (isFloat?Instruction::FRem : Instruction::URem); break; } 337 case 7: {Op = Instruction::Shl; break; } 338 case 8: {Op = Instruction::LShr; break; } 339 case 9: {Op = Instruction::AShr; break; } 340 case 10:{Op = Instruction::And; break; } 341 case 11:{Op = Instruction::Or; break; } 342 case 12:{Op = Instruction::Xor; break; } 343 } 344 345 PT->push_back(BinaryOperator::Create(Op, Val0, Val1, "B", Term)); 346 } 347 }; 348 349 /// Generate constant values. 350 struct ConstModifier: public Modifier { 351 ConstModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 352 virtual void Act() { 353 Type *Ty = pickType(); 354 355 if (Ty->isVectorTy()) { 356 switch (Ran->Rand() % 2) { 357 case 0: if (Ty->getScalarType()->isIntegerTy()) 358 return PT->push_back(ConstantVector::getAllOnesValue(Ty)); 359 case 1: if (Ty->getScalarType()->isIntegerTy()) 360 return PT->push_back(ConstantVector::getNullValue(Ty)); 361 } 362 } 363 364 if (Ty->isFloatingPointTy()) { 365 // Generate 128 random bits, the size of the (currently) 366 // largest floating-point types. 367 uint64_t RandomBits[2]; 368 for (unsigned i = 0; i < 2; ++i) 369 RandomBits[i] = Ran->Rand64(); 370 371 APInt RandomInt(Ty->getPrimitiveSizeInBits(), makeArrayRef(RandomBits)); 372 373 bool isIEEE = !Ty->isX86_FP80Ty() && !Ty->isPPC_FP128Ty(); 374 APFloat RandomFloat(RandomInt, isIEEE); 375 376 if (Ran->Rand() & 1) 377 return PT->push_back(ConstantFP::getNullValue(Ty)); 378 return PT->push_back(ConstantFP::get(Ty->getContext(), RandomFloat)); 379 } 380 381 if (Ty->isIntegerTy()) { 382 switch (Ran->Rand() % 7) { 383 case 0: if (Ty->isIntegerTy()) 384 return PT->push_back(ConstantInt::get(Ty, 385 APInt::getAllOnesValue(Ty->getPrimitiveSizeInBits()))); 386 case 1: if (Ty->isIntegerTy()) 387 return PT->push_back(ConstantInt::get(Ty, 388 APInt::getNullValue(Ty->getPrimitiveSizeInBits()))); 389 case 2: case 3: case 4: case 5: 390 case 6: if (Ty->isIntegerTy()) 391 PT->push_back(ConstantInt::get(Ty, Ran->Rand())); 392 } 393 } 394 395 } 396 }; 397 398 struct AllocaModifier: public Modifier { 399 AllocaModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R){} 400 401 virtual void Act() { 402 Type *Tp = pickType(); 403 PT->push_back(new AllocaInst(Tp, "A", BB->getFirstNonPHI())); 404 } 405 }; 406 407 struct ExtractElementModifier: public Modifier { 408 ExtractElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): 409 Modifier(BB, PT, R) {} 410 411 virtual void Act() { 412 Value *Val0 = getRandomVectorValue(); 413 Value *V = ExtractElementInst::Create(Val0, 414 ConstantInt::get(Type::getInt32Ty(BB->getContext()), 415 Ran->Rand() % cast<VectorType>(Val0->getType())->getNumElements()), 416 "E", BB->getTerminator()); 417 return PT->push_back(V); 418 } 419 }; 420 421 struct ShuffModifier: public Modifier { 422 ShuffModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 423 virtual void Act() { 424 425 Value *Val0 = getRandomVectorValue(); 426 Value *Val1 = getRandomValue(Val0->getType()); 427 428 unsigned Width = cast<VectorType>(Val0->getType())->getNumElements(); 429 std::vector<Constant*> Idxs; 430 431 Type *I32 = Type::getInt32Ty(BB->getContext()); 432 for (unsigned i=0; i<Width; ++i) { 433 Constant *CI = ConstantInt::get(I32, Ran->Rand() % (Width*2)); 434 // Pick some undef values. 435 if (!(Ran->Rand() % 5)) 436 CI = UndefValue::get(I32); 437 Idxs.push_back(CI); 438 } 439 440 Constant *Mask = ConstantVector::get(Idxs); 441 442 Value *V = new ShuffleVectorInst(Val0, Val1, Mask, "Shuff", 443 BB->getTerminator()); 444 PT->push_back(V); 445 } 446 }; 447 448 struct InsertElementModifier: public Modifier { 449 InsertElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): 450 Modifier(BB, PT, R) {} 451 452 virtual void Act() { 453 Value *Val0 = getRandomVectorValue(); 454 Value *Val1 = getRandomValue(Val0->getType()->getScalarType()); 455 456 Value *V = InsertElementInst::Create(Val0, Val1, 457 ConstantInt::get(Type::getInt32Ty(BB->getContext()), 458 Ran->Rand() % cast<VectorType>(Val0->getType())->getNumElements()), 459 "I", BB->getTerminator()); 460 return PT->push_back(V); 461 } 462 463 }; 464 465 struct CastModifier: public Modifier { 466 CastModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 467 virtual void Act() { 468 469 Value *V = getRandomVal(); 470 Type *VTy = V->getType(); 471 Type *DestTy = pickScalarType(); 472 473 // Handle vector casts vectors. 474 if (VTy->isVectorTy()) { 475 VectorType *VecTy = cast<VectorType>(VTy); 476 DestTy = pickVectorType(VecTy->getNumElements()); 477 } 478 479 // no need to cast. 480 if (VTy == DestTy) return; 481 482 // Pointers: 483 if (VTy->isPointerTy()) { 484 if (!DestTy->isPointerTy()) 485 DestTy = PointerType::get(DestTy, 0); 486 return PT->push_back( 487 new BitCastInst(V, DestTy, "PC", BB->getTerminator())); 488 } 489 490 unsigned VSize = VTy->getScalarType()->getPrimitiveSizeInBits(); 491 unsigned DestSize = DestTy->getScalarType()->getPrimitiveSizeInBits(); 492 493 // Generate lots of bitcasts. 494 if ((Ran->Rand() & 1) && VSize == DestSize) { 495 return PT->push_back( 496 new BitCastInst(V, DestTy, "BC", BB->getTerminator())); 497 } 498 499 // Both types are integers: 500 if (VTy->getScalarType()->isIntegerTy() && 501 DestTy->getScalarType()->isIntegerTy()) { 502 if (VSize > DestSize) { 503 return PT->push_back( 504 new TruncInst(V, DestTy, "Tr", BB->getTerminator())); 505 } else { 506 assert(VSize < DestSize && "Different int types with the same size?"); 507 if (Ran->Rand() & 1) 508 return PT->push_back( 509 new ZExtInst(V, DestTy, "ZE", BB->getTerminator())); 510 return PT->push_back(new SExtInst(V, DestTy, "Se", BB->getTerminator())); 511 } 512 } 513 514 // Fp to int. 515 if (VTy->getScalarType()->isFloatingPointTy() && 516 DestTy->getScalarType()->isIntegerTy()) { 517 if (Ran->Rand() & 1) 518 return PT->push_back( 519 new FPToSIInst(V, DestTy, "FC", BB->getTerminator())); 520 return PT->push_back(new FPToUIInst(V, DestTy, "FC", BB->getTerminator())); 521 } 522 523 // Int to fp. 524 if (VTy->getScalarType()->isIntegerTy() && 525 DestTy->getScalarType()->isFloatingPointTy()) { 526 if (Ran->Rand() & 1) 527 return PT->push_back( 528 new SIToFPInst(V, DestTy, "FC", BB->getTerminator())); 529 return PT->push_back(new UIToFPInst(V, DestTy, "FC", BB->getTerminator())); 530 531 } 532 533 // Both floats. 534 if (VTy->getScalarType()->isFloatingPointTy() && 535 DestTy->getScalarType()->isFloatingPointTy()) { 536 if (VSize > DestSize) { 537 return PT->push_back( 538 new FPTruncInst(V, DestTy, "Tr", BB->getTerminator())); 539 } else if (VSize < DestSize) { 540 return PT->push_back( 541 new FPExtInst(V, DestTy, "ZE", BB->getTerminator())); 542 } 543 // If VSize == DestSize, then the two types must be fp128 and ppc_fp128, 544 // for which there is no defined conversion. So do nothing. 545 } 546 } 547 548 }; 549 550 struct SelectModifier: public Modifier { 551 SelectModifier(BasicBlock *BB, PieceTable *PT, Random *R): 552 Modifier(BB, PT, R) {} 553 554 virtual void Act() { 555 // Try a bunch of different select configuration until a valid one is found. 556 Value *Val0 = getRandomVal(); 557 Value *Val1 = getRandomValue(Val0->getType()); 558 559 Type *CondTy = Type::getInt1Ty(Context); 560 561 // If the value type is a vector, and we allow vector select, then in 50% 562 // of the cases generate a vector select. 563 if (Val0->getType()->isVectorTy() && (Ran->Rand() % 1)) { 564 unsigned NumElem = cast<VectorType>(Val0->getType())->getNumElements(); 565 CondTy = VectorType::get(CondTy, NumElem); 566 } 567 568 Value *Cond = getRandomValue(CondTy); 569 Value *V = SelectInst::Create(Cond, Val0, Val1, "Sl", BB->getTerminator()); 570 return PT->push_back(V); 571 } 572 }; 573 574 575 struct CmpModifier: public Modifier { 576 CmpModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 577 virtual void Act() { 578 579 Value *Val0 = getRandomVal(); 580 Value *Val1 = getRandomValue(Val0->getType()); 581 582 if (Val0->getType()->isPointerTy()) return; 583 bool fp = Val0->getType()->getScalarType()->isFloatingPointTy(); 584 585 int op; 586 if (fp) { 587 op = Ran->Rand() % 588 (CmpInst::LAST_FCMP_PREDICATE - CmpInst::FIRST_FCMP_PREDICATE) + 589 CmpInst::FIRST_FCMP_PREDICATE; 590 } else { 591 op = Ran->Rand() % 592 (CmpInst::LAST_ICMP_PREDICATE - CmpInst::FIRST_ICMP_PREDICATE) + 593 CmpInst::FIRST_ICMP_PREDICATE; 594 } 595 596 Value *V = CmpInst::Create(fp ? Instruction::FCmp : Instruction::ICmp, 597 op, Val0, Val1, "Cmp", BB->getTerminator()); 598 return PT->push_back(V); 599 } 600 }; 601 602 void FillFunction(Function *F) { 603 // Create a legal entry block. 604 BasicBlock *BB = BasicBlock::Create(F->getContext(), "BB", F); 605 ReturnInst::Create(F->getContext(), BB); 606 607 // Create the value table. 608 Modifier::PieceTable PT; 609 // Pick an initial seed value 610 Random R(SeedCL); 611 612 // Consider arguments as legal values. 613 for (Function::arg_iterator it = F->arg_begin(), e = F->arg_end(); 614 it != e; ++it) 615 PT.push_back(it); 616 617 // List of modifiers which add new random instructions. 618 std::vector<Modifier*> Modifiers; 619 std::auto_ptr<Modifier> LM(new LoadModifier(BB, &PT, &R)); 620 std::auto_ptr<Modifier> SM(new StoreModifier(BB, &PT, &R)); 621 std::auto_ptr<Modifier> EE(new ExtractElementModifier(BB, &PT, &R)); 622 std::auto_ptr<Modifier> SHM(new ShuffModifier(BB, &PT, &R)); 623 std::auto_ptr<Modifier> IE(new InsertElementModifier(BB, &PT, &R)); 624 std::auto_ptr<Modifier> BM(new BinModifier(BB, &PT, &R)); 625 std::auto_ptr<Modifier> CM(new CastModifier(BB, &PT, &R)); 626 std::auto_ptr<Modifier> SLM(new SelectModifier(BB, &PT, &R)); 627 std::auto_ptr<Modifier> PM(new CmpModifier(BB, &PT, &R)); 628 Modifiers.push_back(LM.get()); 629 Modifiers.push_back(SM.get()); 630 Modifiers.push_back(EE.get()); 631 Modifiers.push_back(SHM.get()); 632 Modifiers.push_back(IE.get()); 633 Modifiers.push_back(BM.get()); 634 Modifiers.push_back(CM.get()); 635 Modifiers.push_back(SLM.get()); 636 Modifiers.push_back(PM.get()); 637 638 // Generate the random instructions 639 AllocaModifier AM(BB, &PT, &R); AM.ActN(5); // Throw in a few allocas 640 ConstModifier COM(BB, &PT, &R); COM.ActN(40); // Throw in a few constants 641 642 for (unsigned i=0; i< SizeCL / Modifiers.size(); ++i) 643 for (std::vector<Modifier*>::iterator it = Modifiers.begin(), 644 e = Modifiers.end(); it != e; ++it) { 645 (*it)->Act(); 646 } 647 648 SM->ActN(5); // Throw in a few stores. 649 } 650 651 void IntroduceControlFlow(Function *F) { 652 std::set<Instruction*> BoolInst; 653 for (BasicBlock::iterator it = F->begin()->begin(), 654 e = F->begin()->end(); it != e; ++it) { 655 if (it->getType() == IntegerType::getInt1Ty(F->getContext())) 656 BoolInst.insert(it); 657 } 658 659 for (std::set<Instruction*>::iterator it = BoolInst.begin(), 660 e = BoolInst.end(); it != e; ++it) { 661 Instruction *Instr = *it; 662 BasicBlock *Curr = Instr->getParent(); 663 BasicBlock::iterator Loc= Instr; 664 BasicBlock *Next = Curr->splitBasicBlock(Loc, "CF"); 665 Instr->moveBefore(Curr->getTerminator()); 666 if (Curr != &F->getEntryBlock()) { 667 BranchInst::Create(Curr, Next, Instr, Curr->getTerminator()); 668 Curr->getTerminator()->eraseFromParent(); 669 } 670 } 671 } 672 673 int main(int argc, char **argv) { 674 // Init LLVM, call llvm_shutdown() on exit, parse args, etc. 675 llvm::PrettyStackTraceProgram X(argc, argv); 676 cl::ParseCommandLineOptions(argc, argv, "llvm codegen stress-tester\n"); 677 llvm_shutdown_obj Y; 678 679 std::auto_ptr<Module> M(new Module("/tmp/autogen.bc", getGlobalContext())); 680 Function *F = GenEmptyFunction(M.get()); 681 FillFunction(F); 682 IntroduceControlFlow(F); 683 684 // Figure out what stream we are supposed to write to... 685 OwningPtr<tool_output_file> Out; 686 // Default to standard output. 687 if (OutputFilename.empty()) 688 OutputFilename = "-"; 689 690 std::string ErrorInfo; 691 Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, 692 raw_fd_ostream::F_Binary)); 693 if (!ErrorInfo.empty()) { 694 errs() << ErrorInfo << '\n'; 695 return 1; 696 } 697 698 PassManager Passes; 699 Passes.add(createVerifierPass()); 700 Passes.add(createPrintModulePass(&Out->os())); 701 Passes.run(*M.get()); 702 Out->keep(); 703 704 return 0; 705 } 706