1 //===- OperationsTest.cpp - Tests for fuzzer operations -------------------===//
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 #include "llvm/FuzzMutate/Operations.h"
11 #include "llvm/AsmParser/Parser.h"
12 #include "llvm/FuzzMutate/OpDescriptor.h"
13 #include "llvm/IR/Constants.h"
14 #include "llvm/IR/Instructions.h"
15 #include "llvm/IR/Module.h"
16 #include "llvm/IR/Verifier.h"
17 #include "llvm/Support/SourceMgr.h"
18 #include "gmock/gmock.h"
19 #include "gtest/gtest.h"
20 #include <iostream>
21 
22 // Define some pretty printers to help with debugging failures.
23 namespace llvm {
24 void PrintTo(Type *T, ::std::ostream *OS) {
25   raw_os_ostream ROS(*OS);
26   T->print(ROS);
27 }
28 
29 void PrintTo(BasicBlock *BB, ::std::ostream *OS) {
30   raw_os_ostream ROS(*OS);
31   ROS << BB << " (" << BB->getName() << ")";
32 }
33 
34 void PrintTo(Value *V, ::std::ostream *OS) {
35   raw_os_ostream ROS(*OS);
36   ROS << V << " (";
37   V->print(ROS);
38   ROS << ")";
39 }
40 void PrintTo(Constant *C, ::std::ostream *OS) { PrintTo(cast<Value>(C), OS); }
41 
42 } // namespace llvm
43 
44 using namespace llvm;
45 
46 using testing::AllOf;
47 using testing::AnyOf;
48 using testing::ElementsAre;
49 using testing::Eq;
50 using testing::Ge;
51 using testing::Each;
52 using testing::Truly;
53 using testing::NotNull;
54 using testing::PrintToString;
55 using testing::SizeIs;
56 
57 namespace {
58 std::unique_ptr<Module> parseAssembly(
59     const char *Assembly, LLVMContext &Context) {
60 
61   SMDiagnostic Error;
62   std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context);
63 
64   std::string ErrMsg;
65   raw_string_ostream OS(ErrMsg);
66   Error.print("", OS);
67 
68   assert(M && !verifyModule(*M, &errs()));
69   return M;
70 }
71 
72 MATCHER_P(TypesMatch, V, "has type " + PrintToString(V->getType())) {
73   return arg->getType() == V->getType();
74 }
75 
76 MATCHER_P(HasType, T, "") { return arg->getType() == T; }
77 
78 TEST(OperationsTest, SourcePreds) {
79   using namespace llvm::fuzzerop;
80 
81   LLVMContext Ctx;
82 
83   Constant *i1 = ConstantInt::getFalse(Ctx);
84   Constant *i8 = ConstantInt::get(Type::getInt8Ty(Ctx), 3);
85   Constant *i16 = ConstantInt::get(Type::getInt16Ty(Ctx), 1 << 15);
86   Constant *i32 = ConstantInt::get(Type::getInt32Ty(Ctx), 0);
87   Constant *i64 = ConstantInt::get(Type::getInt64Ty(Ctx),
88                                    std::numeric_limits<uint64_t>::max());
89   Constant *f16 = ConstantFP::getInfinity(Type::getHalfTy(Ctx));
90   Constant *f32 = ConstantFP::get(Type::getFloatTy(Ctx), 0.0);
91   Constant *f64 = ConstantFP::get(Type::getDoubleTy(Ctx), 123.45);
92   Constant *s =
93       ConstantStruct::get(StructType::create(Ctx, "OpaqueStruct"));
94   Constant *a =
95       ConstantArray::get(ArrayType::get(i32->getType(), 2), {i32, i32});
96   Constant *v8i8 = ConstantVector::getSplat(8, i8);
97   Constant *v4f16 = ConstantVector::getSplat(4, f16);
98   Constant *p0i32 =
99       ConstantPointerNull::get(PointerType::get(i32->getType(), 0));
100 
101   auto OnlyI32 = onlyType(i32->getType());
102   EXPECT_TRUE(OnlyI32.matches({}, i32));
103   EXPECT_FALSE(OnlyI32.matches({}, i64));
104   EXPECT_FALSE(OnlyI32.matches({}, p0i32));
105   EXPECT_FALSE(OnlyI32.matches({}, a));
106 
107   EXPECT_THAT(OnlyI32.generate({}, {}),
108               AllOf(SizeIs(Ge(1u)), Each(TypesMatch(i32))));
109 
110   auto AnyType = anyType();
111   EXPECT_TRUE(AnyType.matches({}, i1));
112   EXPECT_TRUE(AnyType.matches({}, f64));
113   EXPECT_TRUE(AnyType.matches({}, s));
114   EXPECT_TRUE(AnyType.matches({}, v8i8));
115   EXPECT_TRUE(AnyType.matches({}, p0i32));
116 
117   EXPECT_THAT(
118       AnyType.generate({}, {i32->getType(), f16->getType(), v8i8->getType()}),
119       Each(AnyOf(TypesMatch(i32), TypesMatch(f16), TypesMatch(v8i8))));
120 
121   auto AnyInt = anyIntType();
122   EXPECT_TRUE(AnyInt.matches({}, i1));
123   EXPECT_TRUE(AnyInt.matches({}, i64));
124   EXPECT_FALSE(AnyInt.matches({}, f32));
125   EXPECT_FALSE(AnyInt.matches({}, v4f16));
126 
127   EXPECT_THAT(
128       AnyInt.generate({}, {i32->getType(), f16->getType(), v8i8->getType()}),
129       AllOf(SizeIs(Ge(1u)), Each(TypesMatch(i32))));
130 
131   auto AnyFP = anyFloatType();
132   EXPECT_TRUE(AnyFP.matches({}, f16));
133   EXPECT_TRUE(AnyFP.matches({}, f32));
134   EXPECT_FALSE(AnyFP.matches({}, i16));
135   EXPECT_FALSE(AnyFP.matches({}, p0i32));
136   EXPECT_FALSE(AnyFP.matches({}, v4f16));
137 
138   EXPECT_THAT(
139       AnyFP.generate({}, {i32->getType(), f16->getType(), v8i8->getType()}),
140       AllOf(SizeIs(Ge(1u)), Each(TypesMatch(f16))));
141 
142   auto AnyPtr = anyPtrType();
143   EXPECT_TRUE(AnyPtr.matches({}, p0i32));
144   EXPECT_FALSE(AnyPtr.matches({}, i8));
145   EXPECT_FALSE(AnyPtr.matches({}, a));
146   EXPECT_FALSE(AnyPtr.matches({}, v8i8));
147 
148   auto isPointer = [](Value *V) { return V->getType()->isPointerTy(); };
149   EXPECT_THAT(
150       AnyPtr.generate({}, {i32->getType(), f16->getType(), v8i8->getType()}),
151       AllOf(SizeIs(Ge(3u)), Each(Truly(isPointer))));
152 
153   auto AnyVec = anyVectorType();
154   EXPECT_TRUE(AnyVec.matches({}, v8i8));
155   EXPECT_TRUE(AnyVec.matches({}, v4f16));
156   EXPECT_FALSE(AnyVec.matches({}, i8));
157   EXPECT_FALSE(AnyVec.matches({}, a));
158   EXPECT_FALSE(AnyVec.matches({}, s));
159 
160   EXPECT_THAT(AnyVec.generate({}, {v8i8->getType()}),
161               ElementsAre(TypesMatch(v8i8)));
162 
163   auto First = matchFirstType();
164   EXPECT_TRUE(First.matches({i8}, i8));
165   EXPECT_TRUE(First.matches({s, a}, s));
166   EXPECT_FALSE(First.matches({f16}, f32));
167   EXPECT_FALSE(First.matches({v4f16, f64}, f64));
168 
169   EXPECT_THAT(First.generate({i8}, {}), Each(TypesMatch(i8)));
170   EXPECT_THAT(First.generate({f16}, {i8->getType()}),
171               Each(TypesMatch(f16)));
172   EXPECT_THAT(First.generate({v8i8, i32}, {}), Each(TypesMatch(v8i8)));
173 }
174 
175 TEST(OperationsTest, SplitBlock) {
176   LLVMContext Ctx;
177 
178   Module M("M", Ctx);
179   Function *F = Function::Create(FunctionType::get(Type::getVoidTy(Ctx), {},
180                                                    /*isVarArg=*/false),
181                                  GlobalValue::ExternalLinkage, "f", &M);
182   auto SBOp = fuzzerop::splitBlockDescriptor(1);
183 
184   // Create a block with only a return and split it on the return.
185   auto *BB = BasicBlock::Create(Ctx, "BB", F);
186   auto *RI = ReturnInst::Create(Ctx, BB);
187   SBOp.BuilderFunc({UndefValue::get(Type::getInt1Ty(Ctx))}, RI);
188 
189   // We should end up with an unconditional branch from BB to BB1, and the
190   // return ends up in BB1.
191   auto *UncondBr = cast<BranchInst>(BB->getTerminator());
192   ASSERT_TRUE(UncondBr->isUnconditional());
193   auto *BB1 = UncondBr->getSuccessor(0);
194   ASSERT_THAT(RI->getParent(), Eq(BB1));
195 
196   // Now add an instruction to BB1 and split on that.
197   auto *AI = new AllocaInst(Type::getInt8Ty(Ctx), 0, "a", RI);
198   Value *Cond = ConstantInt::getFalse(Ctx);
199   SBOp.BuilderFunc({Cond}, AI);
200 
201   // We should end up with a loop back on BB1 and the instruction we split on
202   // moves to BB2.
203   auto *CondBr = cast<BranchInst>(BB1->getTerminator());
204   EXPECT_THAT(CondBr->getCondition(), Eq(Cond));
205   ASSERT_THAT(CondBr->getNumSuccessors(), Eq(2u));
206   ASSERT_THAT(CondBr->getSuccessor(0), Eq(BB1));
207   auto *BB2 = CondBr->getSuccessor(1);
208   EXPECT_THAT(AI->getParent(), Eq(BB2));
209   EXPECT_THAT(RI->getParent(), Eq(BB2));
210 
211   EXPECT_FALSE(verifyModule(M, &errs()));
212 }
213 
214 TEST(OperationsTest, SplitBlockWithPhis) {
215   LLVMContext Ctx;
216 
217   Type *Int8Ty = Type::getInt8Ty(Ctx);
218 
219   Module M("M", Ctx);
220   Function *F = Function::Create(FunctionType::get(Type::getVoidTy(Ctx), {},
221                                                    /*isVarArg=*/false),
222                                  GlobalValue::ExternalLinkage, "f", &M);
223   auto SBOp = fuzzerop::splitBlockDescriptor(1);
224 
225   // Create 3 blocks with an if-then branch.
226   auto *BB1 = BasicBlock::Create(Ctx, "BB1", F);
227   auto *BB2 = BasicBlock::Create(Ctx, "BB2", F);
228   auto *BB3 = BasicBlock::Create(Ctx, "BB3", F);
229   BranchInst::Create(BB2, BB3, ConstantInt::getFalse(Ctx), BB1);
230   BranchInst::Create(BB3, BB2);
231 
232   // Set up phi nodes selecting values for the incoming edges.
233   auto *PHI1 = PHINode::Create(Int8Ty, /*NumReservedValues=*/2, "p1", BB3);
234   PHI1->addIncoming(ConstantInt::get(Int8Ty, 0), BB1);
235   PHI1->addIncoming(ConstantInt::get(Int8Ty, 1), BB2);
236   auto *PHI2 = PHINode::Create(Int8Ty, /*NumReservedValues=*/2, "p2", BB3);
237   PHI2->addIncoming(ConstantInt::get(Int8Ty, 1), BB1);
238   PHI2->addIncoming(ConstantInt::get(Int8Ty, 0), BB2);
239   auto *RI = ReturnInst::Create(Ctx, BB3);
240 
241   // Now we split the block with PHI nodes, making sure they're all updated.
242   Value *Cond = ConstantInt::getFalse(Ctx);
243   SBOp.BuilderFunc({Cond}, RI);
244 
245   // Make sure the PHIs are updated with a value for the third incoming edge.
246   EXPECT_THAT(PHI1->getNumIncomingValues(), Eq(3u));
247   EXPECT_THAT(PHI2->getNumIncomingValues(), Eq(3u));
248   EXPECT_FALSE(verifyModule(M, &errs()));
249 }
250 
251 TEST(OperationsTest, GEP) {
252   LLVMContext Ctx;
253 
254   Type *Int8PtrTy = Type::getInt8PtrTy(Ctx);
255   Type *Int32Ty = Type::getInt32Ty(Ctx);
256 
257   Module M("M", Ctx);
258   Function *F = Function::Create(FunctionType::get(Type::getVoidTy(Ctx), {},
259                                                    /*isVarArg=*/false),
260                                  GlobalValue::ExternalLinkage, "f", &M);
261   auto *BB = BasicBlock::Create(Ctx, "BB", F);
262   auto *RI = ReturnInst::Create(Ctx, BB);
263 
264   auto GEPOp = fuzzerop::gepDescriptor(1);
265   EXPECT_TRUE(GEPOp.SourcePreds[0].matches({}, UndefValue::get(Int8PtrTy)));
266   EXPECT_TRUE(GEPOp.SourcePreds[1].matches({UndefValue::get(Int8PtrTy)},
267                                            ConstantInt::get(Int32Ty, 0)));
268 
269   GEPOp.BuilderFunc({UndefValue::get(Int8PtrTy), ConstantInt::get(Int32Ty, 0)},
270                     RI);
271   EXPECT_FALSE(verifyModule(M, &errs()));
272 }
273 
274 
275 TEST(OperationsTest, GEPPointerOperand) {
276   // Check that we only pick sized pointers for the GEP instructions
277 
278   LLVMContext Ctx;
279   const char *SourceCode =
280       "declare void @f()\n"
281       "define void @test() {\n"
282       "  %v = bitcast void ()* @f to i64 (i8 addrspace(4)*)*\n"
283       "  %a = alloca i64, i32 10\n"
284       "  ret void\n"
285       "}";
286   auto M = parseAssembly(SourceCode, Ctx);
287 
288   fuzzerop::OpDescriptor Descr = fuzzerop::gepDescriptor(1);
289 
290   // Get first basic block of the test function
291   Function &F = *M->getFunction("test");
292   BasicBlock &BB = *F.begin();
293 
294   // Don't match %v
295   ASSERT_FALSE(Descr.SourcePreds[0].matches({}, &*BB.begin()));
296 
297   // Match %a
298   ASSERT_TRUE(Descr.SourcePreds[0].matches({}, &*std::next(BB.begin())));
299 }
300 
301 TEST(OperationsTest, ExtractAndInsertValue) {
302   LLVMContext Ctx;
303 
304   Type *Int8PtrTy = Type::getInt8PtrTy(Ctx);
305   Type *Int32Ty = Type::getInt32Ty(Ctx);
306   Type *Int64Ty = Type::getInt64Ty(Ctx);
307 
308   Type *StructTy = StructType::create(Ctx, {Int8PtrTy, Int32Ty});
309   Type *OpaqueTy = StructType::create(Ctx, "OpaqueStruct");
310   Type *ArrayTy = ArrayType::get(Int64Ty, 4);
311   Type *VectorTy = VectorType::get(Int32Ty, 2);
312 
313   auto EVOp = fuzzerop::extractValueDescriptor(1);
314   auto IVOp = fuzzerop::insertValueDescriptor(1);
315 
316   // Sanity check the source preds.
317   Constant *SVal = UndefValue::get(StructTy);
318   Constant *OVal = UndefValue::get(OpaqueTy);
319   Constant *AVal = UndefValue::get(ArrayTy);
320   Constant *VVal = UndefValue::get(VectorTy);
321 
322   EXPECT_TRUE(EVOp.SourcePreds[0].matches({}, SVal));
323   EXPECT_TRUE(EVOp.SourcePreds[0].matches({}, OVal));
324   EXPECT_TRUE(EVOp.SourcePreds[0].matches({}, AVal));
325   EXPECT_FALSE(EVOp.SourcePreds[0].matches({}, VVal));
326   EXPECT_TRUE(IVOp.SourcePreds[0].matches({}, SVal));
327   EXPECT_TRUE(IVOp.SourcePreds[0].matches({}, OVal));
328   EXPECT_TRUE(IVOp.SourcePreds[0].matches({}, AVal));
329   EXPECT_FALSE(IVOp.SourcePreds[0].matches({}, VVal));
330 
331   // Make sure we're range checking appropriately.
332   EXPECT_TRUE(
333       EVOp.SourcePreds[1].matches({SVal}, ConstantInt::get(Int32Ty, 0)));
334   EXPECT_TRUE(
335       EVOp.SourcePreds[1].matches({SVal}, ConstantInt::get(Int32Ty, 1)));
336   EXPECT_FALSE(
337       EVOp.SourcePreds[1].matches({SVal}, ConstantInt::get(Int32Ty, 2)));
338   EXPECT_FALSE(
339       EVOp.SourcePreds[1].matches({OVal}, ConstantInt::get(Int32Ty, 0)));
340   EXPECT_FALSE(
341       EVOp.SourcePreds[1].matches({OVal}, ConstantInt::get(Int32Ty, 65536)));
342   EXPECT_TRUE(
343       EVOp.SourcePreds[1].matches({AVal}, ConstantInt::get(Int32Ty, 0)));
344   EXPECT_TRUE(
345       EVOp.SourcePreds[1].matches({AVal}, ConstantInt::get(Int32Ty, 3)));
346   EXPECT_FALSE(
347       EVOp.SourcePreds[1].matches({AVal}, ConstantInt::get(Int32Ty, 4)));
348 
349   EXPECT_THAT(
350       EVOp.SourcePreds[1].generate({SVal}, {}),
351       ElementsAre(ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, 1)));
352 
353   // InsertValue should accept any type in the struct, but only in positions
354   // where it makes sense.
355   EXPECT_TRUE(IVOp.SourcePreds[1].matches({SVal}, UndefValue::get(Int8PtrTy)));
356   EXPECT_TRUE(IVOp.SourcePreds[1].matches({SVal}, UndefValue::get(Int32Ty)));
357   EXPECT_FALSE(IVOp.SourcePreds[1].matches({SVal}, UndefValue::get(Int64Ty)));
358   EXPECT_FALSE(IVOp.SourcePreds[2].matches({SVal, UndefValue::get(Int32Ty)},
359                                            ConstantInt::get(Int32Ty, 0)));
360   EXPECT_TRUE(IVOp.SourcePreds[2].matches({SVal, UndefValue::get(Int32Ty)},
361                                           ConstantInt::get(Int32Ty, 1)));
362 
363   EXPECT_THAT(IVOp.SourcePreds[1].generate({SVal}, {}),
364               Each(AnyOf(HasType(Int32Ty), HasType(Int8PtrTy))));
365   EXPECT_THAT(
366       IVOp.SourcePreds[2].generate({SVal, ConstantInt::get(Int32Ty, 0)}, {}),
367       ElementsAre(ConstantInt::get(Int32Ty, 1)));
368 }
369 
370 }
371