1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[FuzzMutate] Don't create load as a new source if it doesn't match with the descriptor

Differential Revision: https://reviews.llvm.org/D40394

llvm-svn: 319439
This commit is contained in:
Igor Laevsky 2017-11-30 15:24:41 +00:00
parent 0061865148
commit 5feb1b9cc3
3 changed files with 102 additions and 11 deletions

View File

@ -45,22 +45,25 @@ Value *RandomIRBuilder::newSource(BasicBlock &BB, ArrayRef<Instruction *> Insts,
// Generate some constants to choose from.
auto RS = makeSampler<Value *>(Rand);
RS.sample(Pred.generate(Srcs, KnownTypes));
assert(!RS.isEmpty() && "Failed to generate sources");
// If we can find a pointer to load from, use it half the time.
Value *Ptr = findPointer(BB, Insts, Srcs, Pred);
if (Ptr)
RS.sample(Ptr, RS.totalWeight());
if (Ptr) {
// Create load from the chosen pointer
auto IP = BB.getFirstInsertionPt();
if (auto *I = dyn_cast<Instruction>(Ptr))
IP = ++I->getIterator();
auto *NewLoad = new LoadInst(Ptr, "L", &*IP);
Value *Result = RS.getSelection();
if (Result != Ptr)
return Result;
// Only sample this load if it really matches the descriptor
if (Pred.matches(Srcs, NewLoad))
RS.sample(NewLoad, RS.totalWeight());
else
NewLoad->eraseFromParent();
}
// If we choose the pointer, we need to create a load.
auto IP = BB.getFirstInsertionPt();
if (auto *I = dyn_cast<Instruction>(Ptr))
IP = ++I->getIterator();
return new LoadInst(Ptr, "L", &*IP);
assert(!RS.isEmpty() && "Failed to generate sources");
return RS.getSelection();
}
static bool isCompatibleReplacement(const Instruction *I, const Use &Operand,

View File

@ -9,4 +9,5 @@ add_llvm_unittest(FuzzMutateTests
OperationsTest.cpp
ReservoirSamplerTest.cpp
StrategiesTest.cpp
RandomIRBuilderTest.cpp
)

View File

@ -0,0 +1,87 @@
//===- RandomIRBuilderTest.cpp - Tests for injector strategy --------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/FuzzMutate/RandomIRBuilder.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/AsmParser/SlotMapping.h"
#include "llvm/FuzzMutate/IRMutator.h"
#include "llvm/FuzzMutate/OpDescriptor.h"
#include "llvm/FuzzMutate/Operations.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
using namespace llvm;
static constexpr int Seed = 5;
namespace {
std::unique_ptr<Module> parseAssembly(
const char *Assembly, LLVMContext &Context) {
SMDiagnostic Error;
std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context);
std::string ErrMsg;
raw_string_ostream OS(ErrMsg);
Error.print("", OS);
assert(M && !verifyModule(*M, &errs()));
return M;
}
TEST(RandomIRBuilderTest, ShuffleVectorIncorrectOperands) {
// Test that we don't create load instruction as a source for the shuffle
// vector operation.
LLVMContext Ctx;
const char *Source =
"define <2 x i32> @test(<2 x i1> %cond, <2 x i32> %a) {\n"
" %A = alloca <2 x i32>\n"
" %I = insertelement <2 x i32> %a, i32 1, i32 1\n"
" ret <2 x i32> undef\n"
"}";
auto M = parseAssembly(Source, Ctx);
fuzzerop::OpDescriptor Descr = fuzzerop::shuffleVectorDescriptor(1);
// Empty known types since we ShuffleVector descriptor doesn't care about them
RandomIRBuilder IB(Seed, {});
// Get first basic block of the first function
Function &F = *M->begin();
BasicBlock &BB = *F.begin();
SmallVector<Instruction *, 32> Insts;
for (auto I = BB.getFirstInsertionPt(), E = BB.end(); I != E; ++I)
Insts.push_back(&*I);
// Pick first and second sources
SmallVector<Value *, 2> Srcs;
ASSERT_TRUE(Descr.SourcePreds[0].matches(Srcs, Insts[1]));
Srcs.push_back(Insts[1]);
ASSERT_TRUE(Descr.SourcePreds[1].matches(Srcs, Insts[1]));
Srcs.push_back(Insts[1]);
// Create new source. Check that it always matches with the descriptor.
// Run some iterations to account for random decisions.
for (int i = 0; i < 10; ++i) {
Value *LastSrc = IB.newSource(BB, Insts, Srcs, Descr.SourcePreds[2]);
ASSERT_TRUE(Descr.SourcePreds[2].matches(Srcs, LastSrc));
}
}
}