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