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:
parent
0061865148
commit
5feb1b9cc3
@ -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,
|
||||
|
@ -9,4 +9,5 @@ add_llvm_unittest(FuzzMutateTests
|
||||
OperationsTest.cpp
|
||||
ReservoirSamplerTest.cpp
|
||||
StrategiesTest.cpp
|
||||
RandomIRBuilderTest.cpp
|
||||
)
|
||||
|
87
unittests/FuzzMutate/RandomIRBuilderTest.cpp
Normal file
87
unittests/FuzzMutate/RandomIRBuilderTest.cpp
Normal 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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user