brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.9 KiB · 666931c Raw
479 lines · cpp
1//===- OperationsTest.cpp - Tests for fuzzer operations -------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/FuzzMutate/Operations.h"10#include "llvm/AsmParser/Parser.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 "llvm/Support/SourceMgr.h"17#include "gmock/gmock.h"18#include "gtest/gtest.h"19#include <iostream>20 21// Define some pretty printers to help with debugging failures.22namespace llvm {23void PrintTo(Type *T, ::std::ostream *OS) {24  raw_os_ostream ROS(*OS);25  T->print(ROS);26}27 28void PrintTo(BasicBlock *BB, ::std::ostream *OS) {29  raw_os_ostream ROS(*OS);30  ROS << BB << " (" << BB->getName() << ")";31}32 33void PrintTo(Value *V, ::std::ostream *OS) {34  raw_os_ostream ROS(*OS);35  ROS << V << " (";36  V->print(ROS);37  ROS << ")";38}39void PrintTo(Constant *C, ::std::ostream *OS) { PrintTo(cast<Value>(C), OS); }40 41} // namespace llvm42 43using namespace llvm;44 45using testing::AllOf;46using testing::AnyOf;47using testing::Each;48using testing::ElementsAre;49using testing::Eq;50using testing::Ge;51using testing::PrintToString;52using testing::SizeIs;53using testing::Truly;54 55namespace {56std::unique_ptr<Module> parseAssembly(const char *Assembly,57                                      LLVMContext &Context) {58 59  SMDiagnostic Error;60  std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context);61 62  std::string ErrMsg;63  raw_string_ostream OS(ErrMsg);64  Error.print("", OS);65 66  assert(M && !verifyModule(*M, &errs()));67  return M;68}69 70MATCHER_P(TypesMatch, V, "has type " + PrintToString(V->getType())) {71  return arg->getType() == V->getType();72}73 74MATCHER_P(HasType, T, "") { return arg->getType() == T; }75 76TEST(OperationsTest, SourcePreds) {77  using namespace llvm::fuzzerop;78 79  LLVMContext Ctx;80 81  Constant *i1 = ConstantInt::getFalse(Ctx);82  Constant *i8 = ConstantInt::get(Type::getInt8Ty(Ctx), 3);83  Constant *i16 = ConstantInt::get(Type::getInt16Ty(Ctx), 1 << 15);84  Constant *i32 = ConstantInt::get(Type::getInt32Ty(Ctx), 0);85  Constant *i64 = ConstantInt::get(Type::getInt64Ty(Ctx),86                                   std::numeric_limits<uint64_t>::max());87  Constant *f16 = ConstantFP::getInfinity(Type::getHalfTy(Ctx));88  Constant *f32 = ConstantFP::get(Type::getFloatTy(Ctx), 0.0);89  Constant *f64 = ConstantFP::get(Type::getDoubleTy(Ctx), 123.45);90  Constant *s = ConstantStruct::get(StructType::create(Ctx, "OpaqueStruct"));91  Constant *a =92      ConstantArray::get(ArrayType::get(i32->getType(), 2), {i32, i32});93  Constant *v8i1 = ConstantVector::getSplat(ElementCount::getFixed(8), i1);94  Constant *v8i8 = ConstantVector::getSplat(ElementCount::getFixed(8), i8);95  Constant *v4f16 = ConstantVector::getSplat(ElementCount::getFixed(4), f16);96  Constant *p0i32 = ConstantPointerNull::get(PointerType::get(Ctx, 0));97  Constant *v8p0i32 =98      ConstantVector::getSplat(ElementCount::getFixed(8), p0i32);99  Constant *vni32 = ConstantVector::getSplat(ElementCount::getScalable(8), i32);100  Constant *vnf64 = ConstantVector::getSplat(ElementCount::getScalable(8), f64);101  Constant *vnp0i32 =102      ConstantVector::getSplat(ElementCount::getScalable(8), p0i32);103 104  auto OnlyI32 = onlyType(i32->getType());105  EXPECT_TRUE(OnlyI32.matches({}, i32));106  EXPECT_FALSE(OnlyI32.matches({}, i64));107  EXPECT_FALSE(OnlyI32.matches({}, p0i32));108  EXPECT_FALSE(OnlyI32.matches({}, a));109 110  EXPECT_THAT(OnlyI32.generate({}, {}),111              AllOf(SizeIs(Ge(1u)), Each(TypesMatch(i32))));112 113  auto AnyType = anyType();114  EXPECT_TRUE(AnyType.matches({}, i1));115  EXPECT_TRUE(AnyType.matches({}, f64));116  EXPECT_TRUE(AnyType.matches({}, s));117  EXPECT_TRUE(AnyType.matches({}, v8i8));118  EXPECT_TRUE(AnyType.matches({}, p0i32));119 120  EXPECT_THAT(121      AnyType.generate({}, {i32->getType(), f16->getType(), v8i8->getType()}),122      Each(AnyOf(TypesMatch(i32), TypesMatch(f16), TypesMatch(v8i8))));123 124  auto AnyInt = anyIntType();125  EXPECT_TRUE(AnyInt.matches({}, i1));126  EXPECT_TRUE(AnyInt.matches({}, i64));127  EXPECT_FALSE(AnyInt.matches({}, f32));128  EXPECT_FALSE(AnyInt.matches({}, v4f16));129 130  EXPECT_THAT(131      AnyInt.generate({}, {i32->getType(), f16->getType(), v8i8->getType()}),132      AllOf(SizeIs(Ge(1u)), Each(TypesMatch(i32))));133 134  auto AnyIntOrVecInt = anyIntOrVecIntType();135  EXPECT_TRUE(AnyIntOrVecInt.matches({}, i1));136  EXPECT_TRUE(AnyIntOrVecInt.matches({}, i64));137  EXPECT_FALSE(AnyIntOrVecInt.matches({}, f32));138  EXPECT_FALSE(AnyIntOrVecInt.matches({}, v4f16));139  EXPECT_TRUE(AnyIntOrVecInt.matches({}, v8i8));140  EXPECT_FALSE(AnyIntOrVecInt.matches({}, v4f16));141  EXPECT_FALSE(AnyIntOrVecInt.matches({}, v8p0i32));142  EXPECT_TRUE(AnyIntOrVecInt.matches({}, vni32));143  EXPECT_FALSE(AnyIntOrVecInt.matches({}, vnf64));144  EXPECT_FALSE(AnyIntOrVecInt.matches({}, vnp0i32));145 146  EXPECT_THAT(AnyIntOrVecInt.generate({}, {v8i8->getType()}),147              AllOf(Each(TypesMatch(v8i8))));148 149  auto BoolOrVecBool = boolOrVecBoolType();150  EXPECT_TRUE(BoolOrVecBool.matches({}, i1));151  EXPECT_FALSE(BoolOrVecBool.matches({}, i64));152  EXPECT_FALSE(BoolOrVecBool.matches({}, f32));153  EXPECT_FALSE(BoolOrVecBool.matches({}, v4f16));154  EXPECT_TRUE(BoolOrVecBool.matches({}, v8i1));155  EXPECT_FALSE(BoolOrVecBool.matches({}, v4f16));156  EXPECT_FALSE(BoolOrVecBool.matches({}, v8p0i32));157  EXPECT_FALSE(BoolOrVecBool.matches({}, vni32));158  EXPECT_FALSE(BoolOrVecBool.matches({}, vnf64));159  EXPECT_FALSE(BoolOrVecBool.matches({}, vnp0i32));160 161  EXPECT_THAT(BoolOrVecBool.generate({}, {v8i8->getType(), v8i1->getType()}),162              AllOf(Each(TypesMatch(v8i1))));163 164  auto AnyFP = anyFloatType();165  EXPECT_TRUE(AnyFP.matches({}, f16));166  EXPECT_TRUE(AnyFP.matches({}, f32));167  EXPECT_FALSE(AnyFP.matches({}, i16));168  EXPECT_FALSE(AnyFP.matches({}, p0i32));169  EXPECT_FALSE(AnyFP.matches({}, v4f16));170 171  EXPECT_THAT(172      AnyFP.generate({}, {i32->getType(), f16->getType(), v8i8->getType()}),173      AllOf(SizeIs(Ge(1u)), Each(TypesMatch(f16))));174 175  auto AnyFPOrVecFP = anyFloatOrVecFloatType();176  EXPECT_TRUE(AnyFPOrVecFP.matches({}, f16));177  EXPECT_TRUE(AnyFPOrVecFP.matches({}, f32));178  EXPECT_FALSE(AnyFPOrVecFP.matches({}, i16));179  EXPECT_FALSE(AnyFPOrVecFP.matches({}, p0i32));180  EXPECT_TRUE(AnyFPOrVecFP.matches({}, v4f16));181  EXPECT_FALSE(AnyFPOrVecFP.matches({}, v8p0i32));182  EXPECT_FALSE(AnyFPOrVecFP.matches({}, vni32));183  EXPECT_TRUE(AnyFPOrVecFP.matches({}, vnf64));184  EXPECT_FALSE(AnyFPOrVecFP.matches({}, vnp0i32));185 186  EXPECT_THAT(AnyFPOrVecFP.generate(187                  {}, {i32->getType(), f16->getType(), v8i8->getType()}),188              AllOf(SizeIs(Ge(1u)), Each(TypesMatch(f16))));189  EXPECT_THAT(AnyFPOrVecFP.generate({}, {v4f16->getType()}),190              AllOf(SizeIs(Ge(1u)), Each(TypesMatch(v4f16))));191 192  auto AnyPtr = anyPtrType();193  EXPECT_TRUE(AnyPtr.matches({}, p0i32));194  EXPECT_FALSE(AnyPtr.matches({}, i8));195  EXPECT_FALSE(AnyPtr.matches({}, a));196  EXPECT_FALSE(AnyPtr.matches({}, v8i8));197  EXPECT_FALSE(AnyPtr.matches({}, v8p0i32));198  EXPECT_FALSE(AnyPtr.matches({}, vni32));199 200  auto isPointer = [](Value *V) { return V->getType()->isPointerTy(); };201  EXPECT_THAT(202      AnyPtr.generate({}, {i32->getType(), f16->getType(), v8i8->getType()}),203      AllOf(SizeIs(Ge(3u)), Each(Truly(isPointer))));204 205  auto AnyVec = anyVectorType();206  EXPECT_TRUE(AnyVec.matches({}, v8i8));207  EXPECT_TRUE(AnyVec.matches({}, v4f16));208  EXPECT_FALSE(AnyVec.matches({}, i8));209  EXPECT_FALSE(AnyVec.matches({}, a));210  EXPECT_FALSE(AnyVec.matches({}, s));211  EXPECT_TRUE(AnyVec.matches({}, v8p0i32));212  EXPECT_TRUE(AnyVec.matches({}, vni32));213  EXPECT_TRUE(AnyVec.matches({}, vnf64));214  EXPECT_TRUE(AnyVec.matches({}, vnp0i32));215 216  EXPECT_THAT(AnyVec.generate({}, {v8i8->getType()}), Each(TypesMatch(v8i8)));217 218  auto First = matchFirstType();219  EXPECT_TRUE(First.matches({i8}, i8));220  EXPECT_TRUE(First.matches({s, a}, s));221  EXPECT_FALSE(First.matches({f16}, f32));222  EXPECT_FALSE(First.matches({v4f16, f64}, f64));223 224  EXPECT_THAT(First.generate({i8}, {}), Each(TypesMatch(i8)));225  EXPECT_THAT(First.generate({f16}, {i8->getType()}), Each(TypesMatch(f16)));226  EXPECT_THAT(First.generate({v8i8, i32}, {}), Each(TypesMatch(v8i8)));227 228  auto FirstLength = matchFirstLengthWAnyType();229  EXPECT_TRUE(FirstLength.matches({v8i8}, v8i1));230 231  EXPECT_THAT(FirstLength.generate({v8i1}, {i8->getType()}),232              Each(TypesMatch(v8i8)));233 234  auto Second = matchSecondType();235  EXPECT_TRUE(Second.matches({i32, i8}, i8));236  EXPECT_TRUE(Second.matches({i8, f16}, f16));237 238  EXPECT_THAT(Second.generate({v8i8, i32}, {}), Each(TypesMatch(i32)));239  EXPECT_THAT(Second.generate({f32, f16}, {f16->getType()}),240              Each(TypesMatch(f16)));241 242  auto FirstScalar = matchScalarOfFirstType();243  EXPECT_TRUE(FirstScalar.matches({v8i8}, i8));244  EXPECT_TRUE(FirstScalar.matches({i8}, i8));245  EXPECT_TRUE(FirstScalar.matches({v4f16}, f16));246 247  EXPECT_THAT(FirstScalar.generate({v8i8}, {i8->getType()}),248              Each(TypesMatch(i8)));249}250 251TEST(OperationsTest, SplitBlock) {252  LLVMContext Ctx;253 254  Module M("M", Ctx);255  Function *F = Function::Create(FunctionType::get(Type::getVoidTy(Ctx), {},256                                                   /*isVarArg=*/false),257                                 GlobalValue::ExternalLinkage, "f", &M);258  auto SBOp = fuzzerop::splitBlockDescriptor(1);259 260  // Create a block with only a return and split it on the return.261  auto *BB = BasicBlock::Create(Ctx, "BB", F);262  auto *RI = ReturnInst::Create(Ctx, BB);263  SBOp.BuilderFunc({PoisonValue::get(Type::getInt1Ty(Ctx))}, RI->getIterator());264 265  // We should end up with an unconditional branch from BB to BB1, and the266  // return ends up in BB1.267  auto *UncondBr = cast<BranchInst>(BB->getTerminator());268  ASSERT_TRUE(UncondBr->isUnconditional());269  auto *BB1 = UncondBr->getSuccessor(0);270  ASSERT_THAT(RI->getParent(), Eq(BB1));271 272  // Now add an instruction to BB1 and split on that.273  auto *AI = new AllocaInst(Type::getInt8Ty(Ctx), 0, "a", RI->getIterator());274  Value *Cond = ConstantInt::getFalse(Ctx);275  SBOp.BuilderFunc({Cond}, AI->getIterator());276 277  // We should end up with a loop back on BB1 and the instruction we split on278  // moves to BB2.279  auto *CondBr = cast<BranchInst>(BB1->getTerminator());280  EXPECT_THAT(CondBr->getCondition(), Eq(Cond));281  ASSERT_THAT(CondBr->getNumSuccessors(), Eq(2u));282  ASSERT_THAT(CondBr->getSuccessor(0), Eq(BB1));283  auto *BB2 = CondBr->getSuccessor(1);284  EXPECT_THAT(AI->getParent(), Eq(BB2));285  EXPECT_THAT(RI->getParent(), Eq(BB2));286 287  EXPECT_FALSE(verifyModule(M, &errs()));288}289 290TEST(OperationsTest, SplitEHBlock) {291  // Check that we will not try to branch back to the landingpad block using292  // regular branch instruction293 294  LLVMContext Ctx;295  const char *SourceCode =296      "declare ptr @f()"297      "declare i32 @personality_function()"298      "define ptr @test() personality ptr @personality_function {\n"299      "entry:\n"300      "  %val = invoke ptr @f()\n"301      "          to label %normal unwind label %exceptional\n"302      "normal:\n"303      "  ret ptr %val\n"304      "exceptional:\n"305      "  %landing_pad4 = landingpad token cleanup\n"306      "  ret ptr undef\n"307      "}";308  auto M = parseAssembly(SourceCode, Ctx);309 310  // Get the landingpad block311  BasicBlock &BB = *std::next(M->getFunction("test")->begin(), 2);312 313  fuzzerop::OpDescriptor Descr = fuzzerop::splitBlockDescriptor(1);314 315  Descr.BuilderFunc({ConstantInt::getTrue(Ctx)}, BB.getFirstInsertionPt());316  ASSERT_TRUE(!verifyModule(*M, &errs()));317}318 319TEST(OperationsTest, SplitBlockWithPhis) {320  LLVMContext Ctx;321 322  Type *Int8Ty = Type::getInt8Ty(Ctx);323 324  Module M("M", Ctx);325  Function *F = Function::Create(FunctionType::get(Type::getVoidTy(Ctx), {},326                                                   /*isVarArg=*/false),327                                 GlobalValue::ExternalLinkage, "f", &M);328  auto SBOp = fuzzerop::splitBlockDescriptor(1);329 330  // Create 3 blocks with an if-then branch.331  auto *BB1 = BasicBlock::Create(Ctx, "BB1", F);332  auto *BB2 = BasicBlock::Create(Ctx, "BB2", F);333  auto *BB3 = BasicBlock::Create(Ctx, "BB3", F);334  BranchInst::Create(BB2, BB3, ConstantInt::getFalse(Ctx), BB1);335  BranchInst::Create(BB3, BB2);336 337  // Set up phi nodes selecting values for the incoming edges.338  auto *PHI1 = PHINode::Create(Int8Ty, /*NumReservedValues=*/2, "p1", BB3);339  PHI1->addIncoming(ConstantInt::get(Int8Ty, 0), BB1);340  PHI1->addIncoming(ConstantInt::get(Int8Ty, 1), BB2);341  auto *PHI2 = PHINode::Create(Int8Ty, /*NumReservedValues=*/2, "p2", BB3);342  PHI2->addIncoming(ConstantInt::get(Int8Ty, 1), BB1);343  PHI2->addIncoming(ConstantInt::get(Int8Ty, 0), BB2);344  auto *RI = ReturnInst::Create(Ctx, BB3);345 346  // Now we split the block with PHI nodes, making sure they're all updated.347  Value *Cond = ConstantInt::getFalse(Ctx);348  SBOp.BuilderFunc({Cond}, RI->getIterator());349 350  // Make sure the PHIs are updated with a value for the third incoming edge.351  EXPECT_THAT(PHI1->getNumIncomingValues(), Eq(3u));352  EXPECT_THAT(PHI2->getNumIncomingValues(), Eq(3u));353  EXPECT_FALSE(verifyModule(M, &errs()));354}355 356TEST(OperationsTest, GEP) {357  LLVMContext Ctx;358 359  Type *Int8PtrTy = PointerType::getUnqual(Ctx);360  Type *Int32Ty = Type::getInt32Ty(Ctx);361 362  Module M("M", Ctx);363  Function *F = Function::Create(FunctionType::get(Type::getVoidTy(Ctx), {},364                                                   /*isVarArg=*/false),365                                 GlobalValue::ExternalLinkage, "f", &M);366  auto *BB = BasicBlock::Create(Ctx, "BB", F);367  auto *RI = ReturnInst::Create(Ctx, BB);368 369  auto GEPOp = fuzzerop::gepDescriptor(1);370  EXPECT_TRUE(GEPOp.SourcePreds[0].matches({}, PoisonValue::get(Int8PtrTy)));371  EXPECT_TRUE(GEPOp.SourcePreds[1].matches({PoisonValue::get(Int8PtrTy)},372                                           ConstantInt::get(Int32Ty, 0)));373 374  GEPOp.BuilderFunc({PoisonValue::get(Int8PtrTy), ConstantInt::get(Int32Ty, 0)},375                    RI->getIterator());376  EXPECT_FALSE(verifyModule(M, &errs()));377}378 379TEST(OperationsTest, GEPPointerOperand) {380  // Check that we only pick sized pointers for the GEP instructions381 382  LLVMContext Ctx;383  const char *SourceCode = "declare void @f()\n"384                           "define void @test(target(\"foo\") %o) {\n"385                           "  %a = alloca i64, i32 10\n"386                           "  ret void\n"387                           "}";388  auto M = parseAssembly(SourceCode, Ctx);389 390  fuzzerop::OpDescriptor Descr = fuzzerop::gepDescriptor(1);391 392  // Get first basic block of the test function393  Function &F = *M->getFunction("test");394  BasicBlock &BB = *F.begin();395 396  // Don't match %o397  ASSERT_FALSE(Descr.SourcePreds[0].matches({}, &*F.arg_begin()));398 399  // Match %a400  ASSERT_TRUE(Descr.SourcePreds[0].matches({}, &*BB.begin()));401}402 403TEST(OperationsTest, ExtractAndInsertValue) {404  LLVMContext Ctx;405 406  Type *Int8PtrTy = PointerType::getUnqual(Ctx);407  Type *Int32Ty = Type::getInt32Ty(Ctx);408  Type *Int64Ty = Type::getInt64Ty(Ctx);409 410  Type *StructTy = StructType::create(Ctx, {Int8PtrTy, Int32Ty});411  Type *OpaqueTy = StructType::create(Ctx, "OpaqueStruct");412  Type *ZeroSizedArrayTy = ArrayType::get(Int64Ty, 0);413  Type *ArrayTy = ArrayType::get(Int64Ty, 4);414  Type *VectorTy = FixedVectorType::get(Int32Ty, 2);415 416  auto EVOp = fuzzerop::extractValueDescriptor(1);417  auto IVOp = fuzzerop::insertValueDescriptor(1);418 419  // Sanity check the source preds.420  Constant *SVal = PoisonValue::get(StructTy);421  Constant *OVal = PoisonValue::get(OpaqueTy);422  Constant *AVal = PoisonValue::get(ArrayTy);423  Constant *ZAVal = PoisonValue::get(ZeroSizedArrayTy);424  Constant *VVal = PoisonValue::get(VectorTy);425 426  EXPECT_TRUE(EVOp.SourcePreds[0].matches({}, SVal));427  EXPECT_FALSE(EVOp.SourcePreds[0].matches({}, OVal));428  EXPECT_TRUE(EVOp.SourcePreds[0].matches({}, AVal));429  EXPECT_FALSE(EVOp.SourcePreds[0].matches({}, VVal));430  EXPECT_TRUE(IVOp.SourcePreds[0].matches({}, SVal));431  EXPECT_FALSE(IVOp.SourcePreds[0].matches({}, OVal));432  EXPECT_TRUE(IVOp.SourcePreds[0].matches({}, AVal));433  EXPECT_FALSE(IVOp.SourcePreds[0].matches({}, VVal));434 435  // Don't consider zero sized arrays as viable sources436  EXPECT_FALSE(EVOp.SourcePreds[0].matches({}, ZAVal));437  EXPECT_FALSE(IVOp.SourcePreds[0].matches({}, ZAVal));438 439  // Make sure we're range checking appropriately.440  EXPECT_TRUE(441      EVOp.SourcePreds[1].matches({SVal}, ConstantInt::get(Int32Ty, 0)));442  EXPECT_TRUE(443      EVOp.SourcePreds[1].matches({SVal}, ConstantInt::get(Int32Ty, 1)));444  EXPECT_FALSE(445      EVOp.SourcePreds[1].matches({SVal}, ConstantInt::get(Int32Ty, 2)));446  EXPECT_FALSE(447      EVOp.SourcePreds[1].matches({OVal}, ConstantInt::get(Int32Ty, 0)));448  EXPECT_FALSE(449      EVOp.SourcePreds[1].matches({OVal}, ConstantInt::get(Int32Ty, 65536)));450  EXPECT_TRUE(451      EVOp.SourcePreds[1].matches({AVal}, ConstantInt::get(Int32Ty, 0)));452  EXPECT_TRUE(453      EVOp.SourcePreds[1].matches({AVal}, ConstantInt::get(Int32Ty, 3)));454  EXPECT_FALSE(455      EVOp.SourcePreds[1].matches({AVal}, ConstantInt::get(Int32Ty, 4)));456 457  EXPECT_THAT(458      EVOp.SourcePreds[1].generate({SVal}, {}),459      ElementsAre(ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, 1)));460 461  // InsertValue should accept any type in the struct, but only in positions462  // where it makes sense.463  EXPECT_TRUE(IVOp.SourcePreds[1].matches({SVal}, PoisonValue::get(Int8PtrTy)));464  EXPECT_TRUE(IVOp.SourcePreds[1].matches({SVal}, PoisonValue::get(Int32Ty)));465  EXPECT_FALSE(IVOp.SourcePreds[1].matches({SVal}, PoisonValue::get(Int64Ty)));466  EXPECT_FALSE(IVOp.SourcePreds[2].matches({SVal, PoisonValue::get(Int32Ty)},467                                           ConstantInt::get(Int32Ty, 0)));468  EXPECT_TRUE(IVOp.SourcePreds[2].matches({SVal, PoisonValue::get(Int32Ty)},469                                          ConstantInt::get(Int32Ty, 1)));470 471  EXPECT_THAT(IVOp.SourcePreds[1].generate({SVal}, {}),472              Each(AnyOf(HasType(Int32Ty), HasType(Int8PtrTy))));473  EXPECT_THAT(474      IVOp.SourcePreds[2].generate({SVal, ConstantInt::get(Int32Ty, 0)}, {}),475      ElementsAre(ConstantInt::get(Int32Ty, 1)));476}477 478} // namespace479