diff options
author | Peter Rong <PeterRong96@gmail.com> | 2022-11-28 19:50:59 -0800 |
---|---|---|
committer | Peter Rong <PeterRong96@gmail.com> | 2022-11-29 13:07:26 -0800 |
commit | 50921a2174405fbac04a4c9aaeb6993153f05703 (patch) | |
tree | 9c19dd8cc59894d0d11c9bea5b17a107594a1f46 /llvm/unittests/FuzzMutate | |
parent | 21d9f725df8ba177dfa8a6a719618d5078dbb7a8 (diff) | |
download | llvm-50921a2174405fbac04a4c9aaeb6993153f05703.zip llvm-50921a2174405fbac04a4c9aaeb6993153f05703.tar.gz llvm-50921a2174405fbac04a4c9aaeb6993153f05703.tar.bz2 |
[FuzzMutate] Fix a bug in `connectToSink` which might invalidate the whole module.
`connectToSink` uses a value by putting it in a future instruction.
It will replace the operand of a future instruction with the current value.
However, if current value is an `Instruction` and put into a switch case, the module is invalid.
We fix that by only connecting to Br/Switch's condition, and don't touch other operands.
Will have other strategies to mutate other Br/Switch operands to be patched once this patch is passed
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D138890
Diffstat (limited to 'llvm/unittests/FuzzMutate')
-rw-r--r-- | llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp b/llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp index 95f01ab..95d4a38 100644 --- a/llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp +++ b/llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp @@ -13,6 +13,7 @@ #include "llvm/FuzzMutate/IRMutator.h" #include "llvm/FuzzMutate/OpDescriptor.h" #include "llvm/FuzzMutate/Operations.h" +#include "llvm/FuzzMutate/Random.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" @@ -292,4 +293,49 @@ TEST(RandomIRBuilderTest, SwiftError) { } } +TEST(RandomIRBuilderTest, dontConnectToSwitch) { + // Check that we never put anything into switch's case branch + // If we accidently put a variable, the module is invalid. + LLVMContext Ctx; + const char *SourceCode = "\n\ + define void @test(i1 %C1, i1 %C2, i32 %I, i32 %J) { \n\ + Entry: \n\ + %I.1 = add i32 %I, 42 \n\ + %J.1 = add i32 %J, 42 \n\ + %IJ = add i32 %I, %J \n\ + switch i32 %I, label %Default [ \n\ + i32 1, label %OnOne \n\ + ] \n\ + Default: \n\ + %CIEqJ = icmp eq i32 %I.1, %J.1 \n\ + %CISltJ = icmp slt i32 %I.1, %J.1 \n\ + %CAnd = and i1 %C1, %C2 \n\ + br i1 %CIEqJ, label %Default, label %Exit \n\ + OnOne: \n\ + br i1 %C1, label %OnOne, label %Exit \n\ + Exit: \n\ + ret void \n\ + }"; + + std::vector<Type *> Types = {Type::getInt32Ty(Ctx), Type::getInt1Ty(Ctx)}; + RandomIRBuilder IB(Seed, Types); + for (int i = 0; i < 20; i++) { + std::unique_ptr<Module> M = parseAssembly(SourceCode, Ctx); + Function &F = *M->getFunction("test"); + auto RS = makeSampler(IB.Rand, make_pointer_range(F)); + BasicBlock *BB = RS.getSelection(); + SmallVector<Instruction *, 32> Insts; + for (auto I = BB->getFirstInsertionPt(), E = BB->end(); I != E; ++I) + Insts.push_back(&*I); + if (Insts.size() < 2) + continue; + // Choose an instruction and connect to later operations. + size_t IP = uniform<size_t>(IB.Rand, 1, Insts.size() - 1); + Instruction *Inst = Insts[IP - 1]; + auto ConnectAfter = makeArrayRef(Insts).slice(IP); + IB.connectToSink(*BB, ConnectAfter, Inst); + ASSERT_FALSE(verifyModule(*M, &errs())); + } +} + } // namespace |