Skip to content

Commit 43db7cb

Browse files
committed
[FuzzMutate] SinkInstructionStrategy
Randomlly select an instruction and try to use it in the future by replacing it with another instruction's operand. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D138948
1 parent 6a91a5e commit 43db7cb

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

llvm/include/llvm/FuzzMutate/IRMutator.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,19 @@ class InstModificationIRStrategy : public IRMutationStrategy {
118118
void mutate(Instruction &Inst, RandomIRBuilder &IB) override;
119119
};
120120

121+
/// Strategy to select a random instruction and add a new sink (user) to it to
122+
/// increate data dependency.
123+
class SinkInstructionStrategy : public IRMutationStrategy {
124+
public:
125+
uint64_t getWeight(size_t CurrentSize, size_t MaxSize,
126+
uint64_t CurrentWeight) override {
127+
return 2;
128+
}
129+
130+
void mutate(Function &F, RandomIRBuilder &IB) override;
131+
void mutate(BasicBlock &BB, RandomIRBuilder &IB) override;
132+
};
133+
121134
/// Strategy to randomly select a block and shuffle the operations without
122135
/// affecting data dependency.
123136
class ShuffleBlockStrategy : public IRMutationStrategy {

llvm/lib/FuzzMutate/IRMutator.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,29 @@ void InstModificationIRStrategy::mutate(Instruction &Inst,
299299
RS.getSelection()();
300300
}
301301

302+
void SinkInstructionStrategy::mutate(Function &F, RandomIRBuilder &IB) {
303+
for (BasicBlock &BB : F) {
304+
this->mutate(BB, IB);
305+
}
306+
}
307+
void SinkInstructionStrategy::mutate(BasicBlock &BB, RandomIRBuilder &IB) {
308+
SmallVector<Instruction *, 32> Insts;
309+
for (auto I = BB.getFirstInsertionPt(), E = BB.end(); I != E; ++I)
310+
Insts.push_back(&*I);
311+
if (Insts.size() < 1)
312+
return;
313+
// Choose an Instruction to mutate.
314+
uint64_t Idx = uniform<uint64_t>(IB.Rand, 0, Insts.size() - 1);
315+
Instruction *Inst = Insts[Idx];
316+
// `Idx + 1` so we don't sink to ourselves.
317+
auto InstsAfter = makeArrayRef(Insts).slice(Idx + 1);
318+
LLVMContext &C = BB.getParent()->getParent()->getContext();
319+
// Don't sink terminators, void function calls, etc.
320+
if (Inst->getType() != Type::getVoidTy(C))
321+
// Find a new sink and wire up the results of the operation.
322+
IB.connectToSink(BB, InstsAfter, Inst);
323+
}
324+
302325
void ShuffleBlockStrategy::mutate(BasicBlock &BB, RandomIRBuilder &IB) {
303326

304327
SmallPtrSet<Instruction *, 8> AliveInsts;

llvm/unittests/FuzzMutate/StrategiesTest.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,38 @@ TEST(InstModificationIRStrategyTest, DidntShuffleFRem) {
310310
VerfyDivDidntShuffle(Source);
311311
}
312312

313+
TEST(SinkInstructionStrategy, Operand) {
314+
LLVMContext Ctx;
315+
StringRef Source = "\n\
316+
define i32 @test(i1 %C1, i1 %C2, i1 %C3, i32 %I, i32 %J) { \n\
317+
Entry: \n\
318+
%I100 = add i32 %I, 100 \n\
319+
switch i32 %I100, label %BB0 [ \n\
320+
i32 42, label %BB1 \n\
321+
] \n\
322+
BB0: \n\
323+
%IAJ = add i32 %I, %J \n\
324+
%ISJ = sub i32 %I, %J \n\
325+
br label %Exit \n\
326+
BB1: \n\
327+
%IJ = mul i32 %I, %J \n\
328+
%C = and i1 %C2, %C3 \n\
329+
br i1 %C, label %BB0, label %Exit \n\
330+
Exit: \n\
331+
ret i32 %I \n\
332+
}";
333+
auto Mutator = createMutator<SinkInstructionStrategy>();
334+
ASSERT_TRUE(Mutator);
335+
336+
auto M = parseAssembly(Source.data(), Ctx);
337+
std::mt19937 mt(Seed);
338+
std::uniform_int_distribution<int> RandInt(INT_MIN, INT_MAX);
339+
for (int i = 0; i < 100; i++) {
340+
Mutator->mutateModule(*M, RandInt(mt), Source.size(), Source.size() + 1024);
341+
EXPECT_FALSE(verifyModule(*M, &errs()));
342+
}
343+
}
344+
313345
static void VerifyBlockShuffle(StringRef Source) {
314346
LLVMContext Ctx;
315347
auto Mutator = createMutator<ShuffleBlockStrategy>();

0 commit comments

Comments
 (0)