From: Igor Laevsky Date: Thu, 30 Nov 2017 15:29:16 +0000 (+0000) Subject: [FuzzMutate] Don't use index operands as sinks X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=21b2a0025415ae45137c0a41f5e62d02762c1b68;p=llvm [FuzzMutate] Don't use index operands as sinks Differential Revision: https://reviews.llvm.org/D40396 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319441 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/FuzzMutate/RandomIRBuilder.cpp b/lib/FuzzMutate/RandomIRBuilder.cpp index 3c9a35986be..7dfe4c63e0b 100644 --- a/lib/FuzzMutate/RandomIRBuilder.cpp +++ b/lib/FuzzMutate/RandomIRBuilder.cpp @@ -76,12 +76,13 @@ static bool isCompatibleReplacement(const Instruction *I, const Use &Operand, case Instruction::ExtractValue: // TODO: We could potentially validate these, but for now just leave indices // alone. - if (Operand.getOperandNo() > 1) + if (Operand.getOperandNo() >= 1) return false; break; case Instruction::InsertValue: case Instruction::InsertElement: - if (Operand.getOperandNo() > 2) + case Instruction::ShuffleVector: + if (Operand.getOperandNo() >= 2) return false; break; default: diff --git a/unittests/FuzzMutate/RandomIRBuilderTest.cpp b/unittests/FuzzMutate/RandomIRBuilderTest.cpp index 55b75cd2653..5e1b338a95f 100644 --- a/unittests/FuzzMutate/RandomIRBuilderTest.cpp +++ b/unittests/FuzzMutate/RandomIRBuilderTest.cpp @@ -130,4 +130,38 @@ TEST(RandomIRBuilderTest, InsertValueIndexes) { } } +TEST(RandomIRBuilderTest, ShuffleVectorSink) { + // Check that we will never use shuffle vector mask as a sink form the + // unrelated operation. + + LLVMContext Ctx; + const char *SourceCode = + "define void @test(<4 x i32> %a) {\n" + " %S1 = shufflevector <4 x i32> %a, <4 x i32> %a, <4 x i32> undef\n" + " %S2 = shufflevector <4 x i32> %a, <4 x i32> %a, <4 x i32> undef\n" + " ret void\n" + "}"; + auto M = parseAssembly(SourceCode, Ctx); + + fuzzerop::OpDescriptor IVDescr = fuzzerop::insertValueDescriptor(1); + + RandomIRBuilder IB(Seed, {}); + + // Get first basic block of the first function + Function &F = *M->begin(); + BasicBlock &BB = *F.begin(); + + // Source is %S1 + Instruction *Source = &*BB.begin(); + // Sink is %S2 + SmallVector Sinks = {&*std::next(BB.begin())}; + + // Loop to account for random decisions + for (int i = 0; i < 10; ++i) { + // Try to connect S1 to S2. We should always create new sink. + IB.connectToSink(BB, Sinks, Source); + ASSERT_TRUE(!verifyModule(*M, &errs())); + } +} + }