~ubuntu-branches/ubuntu/quantal/llvm-3.1/quantal

« back to all changes in this revision

Viewing changes to tools/llvm-stress/llvm-stress.cpp

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2012-03-29 19:09:51 UTC
  • Revision ID: package-import@ubuntu.com-20120329190951-aq83ivog4cg8bxun
Tags: upstream-3.1~svn153643
ImportĀ upstreamĀ versionĀ 3.1~svn153643

Show diffs side-by-side

added added

removed removed

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