From d209ff981473ae4733c4521e80c427c6ada8a8a3 Mon Sep 17 00:00:00 2001 From: Igor Laevsky Date: Wed, 13 Dec 2017 11:49:04 +0000 Subject: [PATCH] [FuzzMutate] Only generate loads and stores to the first class sized types Differential Revision: https://reviews.llvm.org/D41109 llvm-svn: 320573 --- llvm/lib/FuzzMutate/RandomIRBuilder.cpp | 8 ++++- .../FuzzMutate/RandomIRBuilderTest.cpp | 30 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/llvm/lib/FuzzMutate/RandomIRBuilder.cpp b/llvm/lib/FuzzMutate/RandomIRBuilder.cpp index e3303cf3cac2..8fe9d0dc8579 100644 --- a/llvm/lib/FuzzMutate/RandomIRBuilder.cpp +++ b/llvm/lib/FuzzMutate/RandomIRBuilder.cpp @@ -140,9 +140,15 @@ Value *RandomIRBuilder::findPointer(BasicBlock &BB, if (isa(Inst)) return false; - if (auto PtrTy = dyn_cast(Inst->getType())) + if (auto PtrTy = dyn_cast(Inst->getType())) { + // We can never generate loads from non first class or non sized types + if (!PtrTy->getElementType()->isSized() || + !PtrTy->getElementType()->isFirstClassType()) + return false; + // TODO: Check if this is horribly expensive. return Pred.matches(Srcs, UndefValue::get(PtrTy->getElementType())); + } return false; }; if (auto RS = makeSampler(Rand, make_filter_range(Insts, IsMatchingPtr))) diff --git a/llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp b/llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp index cd0b96bf8596..b60da6cbf9fc 100644 --- a/llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp +++ b/llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp @@ -236,4 +236,34 @@ TEST(RandomIRBuilderTest, Invokes) { } } +TEST(RandomIRBuilderTest, FirstClassTypes) { + // Check that we never insert new source as a load from non first class + // or unsized type. + + LLVMContext Ctx; + const char *SourceCode = "%Opaque = type opaque\n" + "define void @test(i8* %ptr) {\n" + "entry:\n" + " %tmp = bitcast i8* %ptr to i32* (i32*)*\n" + " %tmp1 = bitcast i8* %ptr to %Opaque*\n" + " ret void\n" + "}"; + auto M = parseAssembly(SourceCode, Ctx); + + std::vector Types = {Type::getInt8Ty(Ctx)}; + RandomIRBuilder IB(Seed, Types); + + Function &F = *M->getFunction("test"); + BasicBlock &BB = *F.begin(); + // Non first class type + Instruction *FuncPtr = &*BB.begin(); + // Unsized type + Instruction *OpaquePtr = &*std::next(BB.begin()); + + for (int i = 0; i < 10; ++i) { + Value *V = IB.findOrCreateSource(BB, {FuncPtr, OpaquePtr}); + ASSERT_FALSE(isa(V)); + } +} + }