From: Igor Laevsky Date: Fri, 8 Dec 2017 08:53:16 +0000 (+0000) Subject: [FuzzMutate] Correctly insert sinks and sources around invoke instructions X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2ccc42083eefb7057e8e3863f78146c1a726d92c;p=llvm [FuzzMutate] Correctly insert sinks and sources around invoke instructions Differential Revision: https://reviews.llvm.org/D40840 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320136 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/FuzzMutate/RandomIRBuilder.cpp b/lib/FuzzMutate/RandomIRBuilder.cpp index 7dfe4c63e0b..e3303cf3cac 100644 --- a/lib/FuzzMutate/RandomIRBuilder.cpp +++ b/lib/FuzzMutate/RandomIRBuilder.cpp @@ -51,8 +51,10 @@ Value *RandomIRBuilder::newSource(BasicBlock &BB, ArrayRef Insts, if (Ptr) { // Create load from the chosen pointer auto IP = BB.getFirstInsertionPt(); - if (auto *I = dyn_cast(Ptr)) + if (auto *I = dyn_cast(Ptr)) { IP = ++I->getIterator(); + assert(IP != BB.end() && "guaranteed by the findPointer"); + } auto *NewLoad = new LoadInst(Ptr, "L", &*IP); // Only sample this load if it really matches the descriptor @@ -133,6 +135,11 @@ Value *RandomIRBuilder::findPointer(BasicBlock &BB, ArrayRef Insts, ArrayRef Srcs, SourcePred Pred) { auto IsMatchingPtr = [&Srcs, &Pred](Instruction *Inst) { + // Invoke instructions sometimes produce valid pointers but currently + // we can't insert loads or stores from them + if (isa(Inst)) + return false; + if (auto PtrTy = dyn_cast(Inst->getType())) // TODO: Check if this is horribly expensive. return Pred.matches(Srcs, UndefValue::get(PtrTy->getElementType())); diff --git a/unittests/FuzzMutate/RandomIRBuilderTest.cpp b/unittests/FuzzMutate/RandomIRBuilderTest.cpp index 7d69bda91cc..cd0b96bf859 100644 --- a/unittests/FuzzMutate/RandomIRBuilderTest.cpp +++ b/unittests/FuzzMutate/RandomIRBuilderTest.cpp @@ -200,4 +200,40 @@ TEST(RandomIRBuilderTest, InsertValueArray) { } } +TEST(RandomIRBuilderTest, Invokes) { + // Check that we never generate load or store after invoke instruction + + LLVMContext Ctx; + const char *SourceCode = + "declare i32* @f()" + "declare i32 @personality_function()" + "define i32* @test() personality i32 ()* @personality_function {\n" + "entry:\n" + " %val = invoke i32* @f()\n" + " to label %normal unwind label %exceptional\n" + "normal:\n" + " ret i32* %val\n" + "exceptional:\n" + " %landing_pad4 = landingpad token cleanup\n" + " ret i32* undef\n" + "}"; + auto M = parseAssembly(SourceCode, Ctx); + + + std::vector Types = {Type::getInt8Ty(Ctx)}; + RandomIRBuilder IB(Seed, Types); + + // Get first basic block of the test function + Function &F = *M->getFunction("test"); + BasicBlock &BB = *F.begin(); + + Instruction *Invoke = &*BB.begin(); + + // Find source but never insert new load after invoke + for (int i = 0; i < 10; ++i) { + (void)IB.findOrCreateSource(BB, {Invoke}, {}, fuzzerop::anyIntType()); + ASSERT_TRUE(!verifyModule(*M, &errs())); + } +} + }