[llvm] 23481bf - [FuzzMutate] Update InstModifierStrategy
Peter Rong via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 18 15:57:24 PST 2022
Author: Peter Rong
Date: 2022-11-18T15:54:22-08:00
New Revision: 23481bfe5a09e96931a4712cc236075a3ae3a5c9
URL: https://github.com/llvm/llvm-project/commit/23481bfe5a09e96931a4712cc236075a3ae3a5c9
DIFF: https://github.com/llvm/llvm-project/commit/23481bfe5a09e96931a4712cc236075a3ae3a5c9.diff
LOG: [FuzzMutate] Update InstModifierStrategy
We can randomly switch two operands of an instruction now
Signed-off-by: Peter Rong <PeterRong96 at gmail.com>
Added:
Modified:
llvm/lib/FuzzMutate/IRMutator.cpp
llvm/unittests/FuzzMutate/StrategiesTest.cpp
Removed:
################################################################################
diff --git a/llvm/lib/FuzzMutate/IRMutator.cpp b/llvm/lib/FuzzMutate/IRMutator.cpp
index a879b09112623..9e4517b91a324 100644
--- a/llvm/lib/FuzzMutate/IRMutator.cpp
+++ b/llvm/lib/FuzzMutate/IRMutator.cpp
@@ -218,8 +218,8 @@ void InstModificationIRStrategy::mutate(Instruction &Inst,
case Instruction::Mul:
case Instruction::Sub:
case Instruction::Shl:
- Modifications.push_back([&Inst]() { Inst.setHasNoSignedWrap(true); }),
- Modifications.push_back([&Inst]() { Inst.setHasNoSignedWrap(false); });
+ Modifications.push_back([&Inst]() { Inst.setHasNoSignedWrap(true); });
+ Modifications.push_back([&Inst]() { Inst.setHasNoSignedWrap(false); });
Modifications.push_back([&Inst]() { Inst.setHasNoUnsignedWrap(true); });
Modifications.push_back([&Inst]() { Inst.setHasNoUnsignedWrap(false); });
@@ -244,6 +244,54 @@ void InstModificationIRStrategy::mutate(Instruction &Inst,
break;
}
+ // Randomly switch operands of instructions
+ std::pair<int, int> NoneItem({-1, -1}), ShuffleItems(NoneItem);
+ switch (Inst.getOpcode()) {
+ case Instruction::SDiv:
+ case Instruction::UDiv:
+ case Instruction::SRem:
+ case Instruction::URem:
+ case Instruction::FDiv:
+ case Instruction::FRem: {
+ // Verify that the after shuffle the second operand is not
+ // constant 0.
+ Value *Operand = Inst.getOperand(0);
+ if (Constant *C = dyn_cast<Constant>(Operand)) {
+ if (!C->isZeroValue()) {
+ ShuffleItems = {0, 1};
+ }
+ }
+ break;
+ }
+ case Instruction::Select:
+ ShuffleItems = {1, 2};
+ break;
+ case Instruction::Add:
+ case Instruction::Sub:
+ case Instruction::Mul:
+ case Instruction::Shl:
+ case Instruction::LShr:
+ case Instruction::AShr:
+ case Instruction::And:
+ case Instruction::Or:
+ case Instruction::Xor:
+ case Instruction::FAdd:
+ case Instruction::FSub:
+ case Instruction::FMul:
+ case Instruction::ICmp:
+ case Instruction::FCmp:
+ case Instruction::ShuffleVector:
+ ShuffleItems = {0, 1};
+ break;
+ }
+ if (ShuffleItems != NoneItem) {
+ Modifications.push_back([&Inst, &ShuffleItems]() {
+ Value *Op0 = Inst.getOperand(ShuffleItems.first);
+ Inst.setOperand(ShuffleItems.first, Inst.getOperand(ShuffleItems.second));
+ Inst.setOperand(ShuffleItems.second, Op0);
+ });
+ }
+
auto RS = makeSampler(IB.Rand, Modifications);
if (RS)
RS.getSelection()();
diff --git a/llvm/unittests/FuzzMutate/StrategiesTest.cpp b/llvm/unittests/FuzzMutate/StrategiesTest.cpp
index 3f3f3c56c0386..33aa73eb9ba28 100644
--- a/llvm/unittests/FuzzMutate/StrategiesTest.cpp
+++ b/llvm/unittests/FuzzMutate/StrategiesTest.cpp
@@ -37,24 +37,13 @@ std::unique_ptr<IRMutator> createInjectorMutator() {
return std::make_unique<IRMutator>(std::move(Types), std::move(Strategies));
}
-std::unique_ptr<IRMutator> createDeleterMutator() {
+template <class Strategy> std::unique_ptr<IRMutator> createMutator() {
std::vector<TypeGetter> Types{
Type::getInt1Ty, Type::getInt8Ty, Type::getInt16Ty, Type::getInt32Ty,
Type::getInt64Ty, Type::getFloatTy, Type::getDoubleTy};
std::vector<std::unique_ptr<IRMutationStrategy>> Strategies;
- Strategies.push_back(std::make_unique<InstDeleterIRStrategy>());
-
- return std::make_unique<IRMutator>(std::move(Types), std::move(Strategies));
-}
-
-std::unique_ptr<IRMutator> createInstModifierMutator() {
- std::vector<TypeGetter> Types{
- Type::getInt1Ty, Type::getInt8Ty, Type::getInt16Ty, Type::getInt32Ty,
- Type::getInt64Ty, Type::getFloatTy, Type::getDoubleTy};
-
- std::vector<std::unique_ptr<IRMutationStrategy>> Strategies;
- Strategies.push_back(std::make_unique<InstModificationIRStrategy>());
+ Strategies.push_back(std::make_unique<Strategy>());
return std::make_unique<IRMutator>(std::move(Types), std::move(Strategies));
}
@@ -113,7 +102,7 @@ TEST(InstDeleterIRStrategyTest, EmptyFunction) {
"ret i32 %L6\n"
"}\n";
- auto Mutator = createDeleterMutator();
+ auto Mutator = createMutator<InstDeleterIRStrategy>();
ASSERT_TRUE(Mutator);
IterateOnSource(Source, *Mutator);
@@ -139,7 +128,7 @@ TEST(InstDeleterIRStrategyTest, PhiNodes) {
ret i32 %a.0\n\
}";
- auto Mutator = createDeleterMutator();
+ auto Mutator = createMutator<InstDeleterIRStrategy>();
ASSERT_TRUE(Mutator);
IterateOnSource(Source, *Mutator);
@@ -154,7 +143,7 @@ static void checkModifyNoUnsignedAndNoSignedWrap(StringRef Opc) {
ret i32 %a\n\
}");
- auto Mutator = createInstModifierMutator();
+ auto Mutator = createMutator<InstModificationIRStrategy>();
ASSERT_TRUE(Mutator);
auto M = parseAssembly(Source.data(), Ctx);
@@ -198,7 +187,7 @@ TEST(InstModificationIRStrategyTest, ICmp) {
ret i1 %a\n\
}";
- auto Mutator = createInstModifierMutator();
+ auto Mutator = createMutator<InstModificationIRStrategy>();
ASSERT_TRUE(Mutator);
auto M = parseAssembly(Source.data(), Ctx);
@@ -223,7 +212,7 @@ TEST(InstModificationIRStrategyTest, GEP) {
ret i32* %gep\n\
}";
- auto Mutator = createInstModifierMutator();
+ auto Mutator = createMutator<InstModificationIRStrategy>();
ASSERT_TRUE(Mutator);
auto M = parseAssembly(Source.data(), Ctx);
@@ -239,4 +228,83 @@ TEST(InstModificationIRStrategyTest, GEP) {
EXPECT_TRUE(FoundInbounds);
}
+
+/// The caller has to guarantee that function argument are used in the SAME
+/// place as the operand.
+void VerfyOperandShuffled(StringRef Source, std::pair<int, int> ShuffleItems) {
+ LLVMContext Ctx;
+ auto Mutator = createMutator<InstModificationIRStrategy>();
+ ASSERT_TRUE(Mutator);
+
+ auto M = parseAssembly(Source.data(), Ctx);
+ auto &F = *M->begin();
+ Instruction *Inst = &*F.begin()->begin();
+ ASSERT_TRUE(M && !verifyModule(*M, &errs()));
+ ASSERT_TRUE(Inst->getOperand(ShuffleItems.first) ==
+ dyn_cast<Value>(F.getArg(ShuffleItems.first)));
+ ASSERT_TRUE(Inst->getOperand(ShuffleItems.second) ==
+ dyn_cast<Value>(F.getArg(ShuffleItems.second)));
+
+ Mutator->mutateModule(*M, 0, Source.size(), Source.size() + 100);
+ EXPECT_TRUE(!verifyModule(*M, &errs()));
+
+ EXPECT_TRUE(Inst->getOperand(ShuffleItems.first) ==
+ dyn_cast<Value>(F.getArg(ShuffleItems.second)));
+ EXPECT_TRUE(Inst->getOperand(ShuffleItems.second) ==
+ dyn_cast<Value>(F.getArg(ShuffleItems.first)));
+}
+
+TEST(InstModificationIRStrategyTest, ShuffleFAdd) {
+ StringRef Source = "\n\
+ define float @test(float %0, float %1) {\n\
+ %add = fadd float %0, %1\n\
+ ret float %add\n\
+ }";
+ VerfyOperandShuffled(Source, {0, 1});
+}
+TEST(InstModificationIRStrategyTest, ShuffleSelect) {
+ StringRef Source = "\n\
+ define float @test(i1 %0, float %1, float %2) {\n\
+ %select = select i1 %0, float %1, float %2\n\
+ ret float %select\n\
+ }";
+ VerfyOperandShuffled(Source, {1, 2});
+}
+
+void VerfyDivDidntShuffle(StringRef Source) {
+ LLVMContext Ctx;
+ auto Mutator = createMutator<InstModificationIRStrategy>();
+ ASSERT_TRUE(Mutator);
+
+ auto M = parseAssembly(Source.data(), Ctx);
+ auto &F = *M->begin();
+ Instruction *Inst = &*F.begin()->begin();
+ ASSERT_TRUE(M && !verifyModule(*M, &errs()));
+
+ EXPECT_TRUE(isa<Constant>(Inst->getOperand(0)));
+ EXPECT_TRUE(Inst->getOperand(1) == dyn_cast<Value>(F.getArg(0)));
+
+ Mutator->mutateModule(*M, Seed, Source.size(), Source.size() + 100);
+ EXPECT_TRUE(!verifyModule(*M, &errs()));
+
+ // Didn't shuffle.
+ EXPECT_TRUE(isa<Constant>(Inst->getOperand(0)));
+ EXPECT_TRUE(Inst->getOperand(1) == dyn_cast<Value>(F.getArg(0)));
+}
+TEST(InstModificationIRStrategyTest, DidntShuffleSDiv) {
+ StringRef Source = "\n\
+ define i32 @test(i32 %0) {\n\
+ %div = sdiv i32 0, %0\n\
+ ret i32 %div\n\
+ }";
+ VerfyDivDidntShuffle(Source);
+}
+TEST(InstModificationIRStrategyTest, DidntShuffleFRem) {
+ StringRef Source = "\n\
+ define <2 x double> @test(<2 x double> %0) {\n\
+ %div = frem <2 x double> <double 0.0, double 0.0>, %0\n\
+ ret <2 x double> %div\n\
+ }";
+ VerfyDivDidntShuffle(Source);
+}
} // namespace
More information about the llvm-commits
mailing list