LLVM  7.0.0svn
Operations.cpp
Go to the documentation of this file.
1 //===-- Operations.cpp ----------------------------------------------------===//
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 
11 #include "llvm/IR/BasicBlock.h"
12 #include "llvm/IR/Constants.h"
13 #include "llvm/IR/Function.h"
14 #include "llvm/IR/Instructions.h"
15 
16 using namespace llvm;
17 using namespace fuzzerop;
18 
19 void llvm::describeFuzzerIntOps(std::vector<fuzzerop::OpDescriptor> &Ops) {
20  Ops.push_back(binOpDescriptor(1, Instruction::Add));
21  Ops.push_back(binOpDescriptor(1, Instruction::Sub));
22  Ops.push_back(binOpDescriptor(1, Instruction::Mul));
23  Ops.push_back(binOpDescriptor(1, Instruction::SDiv));
24  Ops.push_back(binOpDescriptor(1, Instruction::UDiv));
25  Ops.push_back(binOpDescriptor(1, Instruction::SRem));
26  Ops.push_back(binOpDescriptor(1, Instruction::URem));
27  Ops.push_back(binOpDescriptor(1, Instruction::Shl));
28  Ops.push_back(binOpDescriptor(1, Instruction::LShr));
29  Ops.push_back(binOpDescriptor(1, Instruction::AShr));
30  Ops.push_back(binOpDescriptor(1, Instruction::And));
31  Ops.push_back(binOpDescriptor(1, Instruction::Or));
32  Ops.push_back(binOpDescriptor(1, Instruction::Xor));
33 
34  Ops.push_back(cmpOpDescriptor(1, Instruction::ICmp, CmpInst::ICMP_EQ));
35  Ops.push_back(cmpOpDescriptor(1, Instruction::ICmp, CmpInst::ICMP_NE));
36  Ops.push_back(cmpOpDescriptor(1, Instruction::ICmp, CmpInst::ICMP_UGT));
37  Ops.push_back(cmpOpDescriptor(1, Instruction::ICmp, CmpInst::ICMP_UGE));
38  Ops.push_back(cmpOpDescriptor(1, Instruction::ICmp, CmpInst::ICMP_ULT));
39  Ops.push_back(cmpOpDescriptor(1, Instruction::ICmp, CmpInst::ICMP_ULE));
40  Ops.push_back(cmpOpDescriptor(1, Instruction::ICmp, CmpInst::ICMP_SGT));
41  Ops.push_back(cmpOpDescriptor(1, Instruction::ICmp, CmpInst::ICMP_SGE));
42  Ops.push_back(cmpOpDescriptor(1, Instruction::ICmp, CmpInst::ICMP_SLT));
43  Ops.push_back(cmpOpDescriptor(1, Instruction::ICmp, CmpInst::ICMP_SLE));
44 }
45 
46 void llvm::describeFuzzerFloatOps(std::vector<fuzzerop::OpDescriptor> &Ops) {
47  Ops.push_back(binOpDescriptor(1, Instruction::FAdd));
48  Ops.push_back(binOpDescriptor(1, Instruction::FSub));
49  Ops.push_back(binOpDescriptor(1, Instruction::FMul));
50  Ops.push_back(binOpDescriptor(1, Instruction::FDiv));
51  Ops.push_back(binOpDescriptor(1, Instruction::FRem));
52 
53  Ops.push_back(cmpOpDescriptor(1, Instruction::FCmp, CmpInst::FCMP_FALSE));
54  Ops.push_back(cmpOpDescriptor(1, Instruction::FCmp, CmpInst::FCMP_OEQ));
55  Ops.push_back(cmpOpDescriptor(1, Instruction::FCmp, CmpInst::FCMP_OGT));
56  Ops.push_back(cmpOpDescriptor(1, Instruction::FCmp, CmpInst::FCMP_OGE));
57  Ops.push_back(cmpOpDescriptor(1, Instruction::FCmp, CmpInst::FCMP_OLT));
58  Ops.push_back(cmpOpDescriptor(1, Instruction::FCmp, CmpInst::FCMP_OLE));
59  Ops.push_back(cmpOpDescriptor(1, Instruction::FCmp, CmpInst::FCMP_ONE));
60  Ops.push_back(cmpOpDescriptor(1, Instruction::FCmp, CmpInst::FCMP_ORD));
61  Ops.push_back(cmpOpDescriptor(1, Instruction::FCmp, CmpInst::FCMP_UNO));
62  Ops.push_back(cmpOpDescriptor(1, Instruction::FCmp, CmpInst::FCMP_UEQ));
63  Ops.push_back(cmpOpDescriptor(1, Instruction::FCmp, CmpInst::FCMP_UGT));
64  Ops.push_back(cmpOpDescriptor(1, Instruction::FCmp, CmpInst::FCMP_UGE));
65  Ops.push_back(cmpOpDescriptor(1, Instruction::FCmp, CmpInst::FCMP_ULT));
66  Ops.push_back(cmpOpDescriptor(1, Instruction::FCmp, CmpInst::FCMP_ULE));
67  Ops.push_back(cmpOpDescriptor(1, Instruction::FCmp, CmpInst::FCMP_UNE));
68  Ops.push_back(cmpOpDescriptor(1, Instruction::FCmp, CmpInst::FCMP_TRUE));
69 }
70 
72  std::vector<fuzzerop::OpDescriptor> &Ops) {
73  Ops.push_back(splitBlockDescriptor(1));
74 }
75 
76 void llvm::describeFuzzerPointerOps(std::vector<fuzzerop::OpDescriptor> &Ops) {
77  Ops.push_back(gepDescriptor(1));
78 }
79 
81  std::vector<fuzzerop::OpDescriptor> &Ops) {
82  Ops.push_back(extractValueDescriptor(1));
83  Ops.push_back(insertValueDescriptor(1));
84 }
85 
86 void llvm::describeFuzzerVectorOps(std::vector<fuzzerop::OpDescriptor> &Ops) {
87  Ops.push_back(extractElementDescriptor(1));
88  Ops.push_back(insertElementDescriptor(1));
89  Ops.push_back(shuffleVectorDescriptor(1));
90 }
91 
94  auto buildOp = [Op](ArrayRef<Value *> Srcs, Instruction *Inst) {
95  return BinaryOperator::Create(Op, Srcs[0], Srcs[1], "B", Inst);
96  };
97  switch (Op) {
98  case Instruction::Add:
99  case Instruction::Sub:
100  case Instruction::Mul:
101  case Instruction::SDiv:
102  case Instruction::UDiv:
103  case Instruction::SRem:
104  case Instruction::URem:
105  case Instruction::Shl:
106  case Instruction::LShr:
107  case Instruction::AShr:
108  case Instruction::And:
109  case Instruction::Or:
110  case Instruction::Xor:
111  return {Weight, {anyIntType(), matchFirstType()}, buildOp};
112  case Instruction::FAdd:
113  case Instruction::FSub:
114  case Instruction::FMul:
115  case Instruction::FDiv:
116  case Instruction::FRem:
117  return {Weight, {anyFloatType(), matchFirstType()}, buildOp};
118  case Instruction::BinaryOpsEnd:
119  llvm_unreachable("Value out of range of enum");
120  }
121  llvm_unreachable("Covered switch");
122 }
123 
125  Instruction::OtherOps CmpOp,
126  CmpInst::Predicate Pred) {
127  auto buildOp = [CmpOp, Pred](ArrayRef<Value *> Srcs, Instruction *Inst) {
128  return CmpInst::Create(CmpOp, Pred, Srcs[0], Srcs[1], "C", Inst);
129  };
130 
131  switch (CmpOp) {
132  case Instruction::ICmp:
133  return {Weight, {anyIntType(), matchFirstType()}, buildOp};
134  case Instruction::FCmp:
135  return {Weight, {anyFloatType(), matchFirstType()}, buildOp};
136  default:
137  llvm_unreachable("CmpOp must be ICmp or FCmp");
138  }
139 }
140 
142  auto buildSplitBlock = [](ArrayRef<Value *> Srcs, Instruction *Inst) {
143  BasicBlock *Block = Inst->getParent();
144  BasicBlock *Next = Block->splitBasicBlock(Inst, "BB");
145 
146  // If it was an exception handling block, we are done.
147  if (Block->isEHPad())
148  return nullptr;
149 
150  // Loop back on this block by replacing the unconditional forward branch
151  // with a conditional with a backedge.
152  if (Block != &Block->getParent()->getEntryBlock()) {
153  BranchInst::Create(Block, Next, Srcs[0], Block->getTerminator());
154  Block->getTerminator()->eraseFromParent();
155 
156  // We need values for each phi in the block. Since there isn't a good way
157  // to do a variable number of input values currently, we just fill them
158  // with undef.
159  for (PHINode &PHI : Block->phis())
160  PHI.addIncoming(UndefValue::get(PHI.getType()), Block);
161  }
162  return nullptr;
163  };
164  SourcePred isInt1Ty{[](ArrayRef<Value *>, const Value *V) {
165  return V->getType()->isIntegerTy(1);
166  },
167  None};
168  return {Weight, {isInt1Ty}, buildSplitBlock};
169 }
170 
172  auto buildGEP = [](ArrayRef<Value *> Srcs, Instruction *Inst) {
173  Type *Ty = cast<PointerType>(Srcs[0]->getType())->getElementType();
174  auto Indices = makeArrayRef(Srcs).drop_front(1);
175  return GetElementPtrInst::Create(Ty, Srcs[0], Indices, "G", Inst);
176  };
177  // TODO: Handle aggregates and vectors
178  // TODO: Support multiple indices.
179  // TODO: Try to avoid meaningless accesses.
180  return {Weight, {sizedPtrType(), anyIntType()}, buildGEP};
181 }
182 
183 static uint64_t getAggregateNumElements(Type *T) {
184  assert(T->isAggregateType() && "Not a struct or array");
185  if (isa<StructType>(T))
186  return T->getStructNumElements();
187  return T->getArrayNumElements();
188 }
189 
191  auto Pred = [](ArrayRef<Value *> Cur, const Value *V) {
192  if (auto *CI = dyn_cast<ConstantInt>(V))
193  if (!CI->uge(getAggregateNumElements(Cur[0]->getType())))
194  return true;
195  return false;
196  };
197  auto Make = [](ArrayRef<Value *> Cur, ArrayRef<Type *> Ts) {
198  std::vector<Constant *> Result;
199  auto *Int32Ty = Type::getInt32Ty(Cur[0]->getContext());
200  uint64_t N = getAggregateNumElements(Cur[0]->getType());
201  // Create indices at the start, end, and middle, but avoid dups.
202  Result.push_back(ConstantInt::get(Int32Ty, 0));
203  if (N > 1)
204  Result.push_back(ConstantInt::get(Int32Ty, N - 1));
205  if (N > 2)
206  Result.push_back(ConstantInt::get(Int32Ty, N / 2));
207  return Result;
208  };
209  return {Pred, Make};
210 }
211 
213  auto buildExtract = [](ArrayRef<Value *> Srcs, Instruction *Inst) {
214  // TODO: It's pretty inefficient to shuffle this all through constants.
215  unsigned Idx = cast<ConstantInt>(Srcs[1])->getZExtValue();
216  return ExtractValueInst::Create(Srcs[0], {Idx}, "E", Inst);
217  };
218  // TODO: Should we handle multiple indices?
219  return {Weight, {anyAggregateType(), validExtractValueIndex()}, buildExtract};
220 }
221 
223  auto Pred = [](ArrayRef<Value *> Cur, const Value *V) {
224  if (auto *ArrayT = dyn_cast<ArrayType>(Cur[0]->getType()))
225  return V->getType() == ArrayT->getElementType();
226 
227  auto *STy = cast<StructType>(Cur[0]->getType());
228  for (int I = 0, E = STy->getNumElements(); I < E; ++I)
229  if (STy->getTypeAtIndex(I) == V->getType())
230  return true;
231  return false;
232  };
233  auto Make = [](ArrayRef<Value *> Cur, ArrayRef<Type *>) {
234  if (auto *ArrayT = dyn_cast<ArrayType>(Cur[0]->getType()))
235  return makeConstantsWithType(ArrayT->getElementType());
236 
237  std::vector<Constant *> Result;
238  auto *STy = cast<StructType>(Cur[0]->getType());
239  for (int I = 0, E = STy->getNumElements(); I < E; ++I)
240  makeConstantsWithType(STy->getTypeAtIndex(I), Result);
241  return Result;
242  };
243  return {Pred, Make};
244 }
245 
247  auto Pred = [](ArrayRef<Value *> Cur, const Value *V) {
248  auto *CTy = cast<CompositeType>(Cur[0]->getType());
249  if (auto *CI = dyn_cast<ConstantInt>(V))
250  if (CI->getBitWidth() == 32 &&
251  CTy->getTypeAtIndex(CI->getZExtValue()) == Cur[1]->getType())
252  return true;
253  return false;
254  };
255  auto Make = [](ArrayRef<Value *> Cur, ArrayRef<Type *> Ts) {
256  std::vector<Constant *> Result;
257  auto *Int32Ty = Type::getInt32Ty(Cur[0]->getContext());
258  auto *CTy = cast<CompositeType>(Cur[0]->getType());
259  for (int I = 0, E = getAggregateNumElements(CTy); I < E; ++I)
260  if (CTy->getTypeAtIndex(I) == Cur[1]->getType())
261  Result.push_back(ConstantInt::get(Int32Ty, I));
262  return Result;
263  };
264  return {Pred, Make};
265 }
266 
268  auto buildInsert = [](ArrayRef<Value *> Srcs, Instruction *Inst) {
269  // TODO: It's pretty inefficient to shuffle this all through constants.
270  unsigned Idx = cast<ConstantInt>(Srcs[2])->getZExtValue();
271  return InsertValueInst::Create(Srcs[0], Srcs[1], {Idx}, "I", Inst);
272  };
273  return {
274  Weight,
276  buildInsert};
277 }
278 
280  auto buildExtract = [](ArrayRef<Value *> Srcs, Instruction *Inst) {
281  return ExtractElementInst::Create(Srcs[0], Srcs[1], "E", Inst);
282  };
283  // TODO: Try to avoid undefined accesses.
284  return {Weight, {anyVectorType(), anyIntType()}, buildExtract};
285 }
286 
288  auto buildInsert = [](ArrayRef<Value *> Srcs, Instruction *Inst) {
289  return InsertElementInst::Create(Srcs[0], Srcs[1], Srcs[2], "I", Inst);
290  };
291  // TODO: Try to avoid undefined accesses.
292  return {Weight,
294  buildInsert};
295 }
296 
298  auto Pred = [](ArrayRef<Value *> Cur, const Value *V) {
299  return ShuffleVectorInst::isValidOperands(Cur[0], Cur[1], V);
300  };
301  auto Make = [](ArrayRef<Value *> Cur, ArrayRef<Type *> Ts) {
302  auto *FirstTy = cast<VectorType>(Cur[0]->getType());
303  auto *Int32Ty = Type::getInt32Ty(Cur[0]->getContext());
304  // TODO: It's straighforward to make up reasonable values, but listing them
305  // exhaustively would be insane. Come up with a couple of sensible ones.
306  return std::vector<Constant *>{
307  UndefValue::get(VectorType::get(Int32Ty, FirstTy->getNumElements()))};
308  };
309  return {Pred, Make};
310 }
311 
313  auto buildShuffle = [](ArrayRef<Value *> Srcs, Instruction *Inst) {
314  return new ShuffleVectorInst(Srcs[0], Srcs[1], Srcs[2], "S", Inst);
315  };
316  return {Weight,
318  buildShuffle};
319 }
const NoneType None
Definition: None.h:24
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks &#39;this&#39; from the containing basic block and deletes it.
Definition: Instruction.cpp:67
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
OpDescriptor insertElementDescriptor(unsigned Weight)
Definition: Operations.cpp:287
static SourcePred matchScalarInAggregate()
Definition: Operations.cpp:222
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value *> IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Definition: Instructions.h:863
unsigned less or equal
Definition: InstrTypes.h:900
unsigned less than
Definition: InstrTypes.h:899
0 1 0 0 True if ordered and less than
Definition: InstrTypes.h:880
This instruction constructs a fixed permutation of two input vectors.
void describeFuzzerControlFlowOps(std::vector< fuzzerop::OpDescriptor > &Ops)
Definition: Operations.cpp:71
1 1 1 0 True if unordered or not equal
Definition: InstrTypes.h:890
OpDescriptor binOpDescriptor(unsigned Weight, Instruction::BinaryOps Op)
Descriptors for individual operations.
Definition: Operations.cpp:92
1 0 0 1 True if unordered or equal
Definition: InstrTypes.h:885
static InsertElementInst * Create(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Definition: InstrTypes.h:884
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:451
uint64_t getArrayNumElements() const
Definition: DerivedTypes.h:388
OpDescriptor extractValueDescriptor(unsigned Weight)
Definition: Operations.cpp:212
static SourcePred validShuffleVectorIndex()
Definition: Operations.cpp:297
void describeFuzzerVectorOps(std::vector< fuzzerop::OpDescriptor > &Ops)
Definition: Operations.cpp:86
static SourcePred sizedPtrType()
Definition: OpDescriptor.h:144
0 1 0 1 True if ordered and less than or equal
Definition: InstrTypes.h:881
OpDescriptor extractElementDescriptor(unsigned Weight)
Definition: Operations.cpp:279
static SourcePred matchFirstType()
Match values that have the same type as the first source.
Definition: OpDescriptor.h:195
static bool isValidOperands(const Value *V1, const Value *V2, const Value *Mask)
Return true if a shufflevector instruction can be formed with the specified operands.
OpDescriptor shuffleVectorDescriptor(unsigned Weight)
Definition: Operations.cpp:312
static SourcePred anyFloatType()
Definition: OpDescriptor.h:122
static CmpInst * Create(OtherOps Op, Predicate predicate, Value *S1, Value *S2, const Twine &Name="", Instruction *InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate and the two operands.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
static SourcePred anyVectorType()
Definition: OpDescriptor.h:183
OpDescriptor splitBlockDescriptor(unsigned Weight)
Definition: Operations.cpp:141
const BasicBlock & getEntryBlock() const
Definition: Function.h:618
LLVM Basic Block Representation.
Definition: BasicBlock.h:59
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
static ExtractValueInst * Create(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
OpDescriptor gepDescriptor(unsigned Weight)
Definition: Operations.cpp:171
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
void describeFuzzerFloatOps(std::vector< fuzzerop::OpDescriptor > &Ops)
Definition: Operations.cpp:46
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:874
0 1 1 1 True if ordered (no nans)
Definition: InstrTypes.h:883
unsigned getStructNumElements() const
Definition: DerivedTypes.h:329
void describeFuzzerPointerOps(std::vector< fuzzerop::OpDescriptor > &Ops)
Definition: Operations.cpp:76
void makeConstantsWithType(Type *T, std::vector< Constant *> &Cs)
1 1 1 1 Always true (always folded)
Definition: InstrTypes.h:891
static UndefValue * get(Type *T)
Static factory methods - Return an &#39;undef&#39; object of the specified type.
Definition: Constants.cpp:1369
static wasm::ValType getType(const TargetRegisterClass *RC)
1 1 0 1 True if unordered, less than, or equal
Definition: InstrTypes.h:889
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static SourcePred validInsertValueIndex()
Definition: Operations.cpp:246
signed greater than
Definition: InstrTypes.h:901
0 0 1 0 True if ordered and greater than
Definition: InstrTypes.h:878
OpDescriptor insertValueDescriptor(unsigned Weight)
Definition: Operations.cpp:267
1 1 0 0 True if unordered or less than
Definition: InstrTypes.h:888
void describeFuzzerIntOps(std::vector< fuzzerop::OpDescriptor > &Ops)
Getters for the default sets of operations, per general category.
Definition: Operations.cpp:19
bool isAggregateType() const
Return true if the type is an aggregate type.
Definition: Type.h:255
signed less than
Definition: InstrTypes.h:903
static uint64_t getAggregateNumElements(Type *T)
Definition: Operations.cpp:183
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:598
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
A matcher/generator for finding suitable values for the next source in an operation&#39;s partially compl...
Definition: OpDescriptor.h:44
signed less or equal
Definition: InstrTypes.h:904
static SourcePred validExtractValueIndex()
Definition: Operations.cpp:190
void describeFuzzerAggregateOps(std::vector< fuzzerop::OpDescriptor > &Ops)
Definition: Operations.cpp:80
OpDescriptor cmpOpDescriptor(unsigned Weight, Instruction::OtherOps CmpOp, CmpInst::Predicate Pred)
Definition: Operations.cpp:124
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), Instruction *InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
static SourcePred anyAggregateType()
Definition: OpDescriptor.h:165
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:176
unsigned greater or equal
Definition: InstrTypes.h:898
static InsertValueInst * Create(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:108
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
0 1 1 0 True if ordered and operands are unequal
Definition: InstrTypes.h:882
A description of some operation we can build while fuzzing IR.
Definition: OpDescriptor.h:90
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
Definition: BasicBlock.h:308
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
Definition: BasicBlock.cpp:383
1 0 1 0 True if unordered or greater than
Definition: InstrTypes.h:886
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isEHPad() const
Return true if this basic block is an exception handling block.
Definition: BasicBlock.h:383
0 0 0 1 True if ordered and equal
Definition: InstrTypes.h:877
LLVM Value Representation.
Definition: Value.h:73
static Value * buildGEP(IRBuilderTy &IRB, Value *BasePtr, SmallVectorImpl< Value *> &Indices, Twine NamePrefix)
Build a GEP out of a base pointer and indices.
Definition: SROA.cpp:1358
1 0 1 1 True if unordered, greater than, or equal
Definition: InstrTypes.h:887
static VectorType * get(Type *ElementType, unsigned NumElements)
This static method is the primary way to construct an VectorType.
Definition: Type.cpp:593
static SourcePred matchScalarOfFirstType()
Match values that have the first source&#39;s scalar type.
Definition: OpDescriptor.h:208
unsigned greater than
Definition: InstrTypes.h:897
const TerminatorInst * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.cpp:120
static ExtractElementInst * Create(Value *Vec, Value *Idx, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
0 0 1 1 True if ordered and greater than or equal
Definition: InstrTypes.h:879
0 0 0 0 Always false (always folded)
Definition: InstrTypes.h:876
signed greater or equal
Definition: InstrTypes.h:902
IntegerType * Int32Ty
static SourcePred anyIntType()
Definition: OpDescriptor.h:114