diff --git a/test/tools/ossfuzz/CMakeLists.txt b/test/tools/ossfuzz/CMakeLists.txt
index a6d4addc1..790aa3f9d 100644
--- a/test/tools/ossfuzz/CMakeLists.txt
+++ b/test/tools/ossfuzz/CMakeLists.txt
@@ -87,7 +87,14 @@ if (OSSFUZZ)
set_target_properties(yul_proto_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
target_compile_options(yul_proto_ossfuzz PUBLIC ${COMPILE_OPTIONS} -Wno-sign-conversion)
- add_executable(yul_proto_diff_ossfuzz yulProto_diff_ossfuzz.cpp yulFuzzerCommon.cpp protoToYul.cpp yulProto.pb.cc)
+ add_executable(
+ yul_proto_diff_ossfuzz
+ yulProto_diff_ossfuzz.cpp
+ yulFuzzerCommon.cpp
+ protoToYul.cpp
+ yulProto.pb.cc
+ YulOptimizerStepTest.cpp
+ )
target_include_directories(yul_proto_diff_ossfuzz PRIVATE /usr/include/libprotobuf-mutator)
target_link_libraries(yul_proto_diff_ossfuzz PRIVATE yul
yulInterpreter
@@ -104,6 +111,7 @@ if (OSSFUZZ)
protoToYul.cpp
yulProto.pb.cc
protomutators/YulProtoMutator.cpp
+ YulOptimizerStepTest.cpp
)
target_include_directories(yul_proto_diff_custom_mutate_ossfuzz PRIVATE /usr/include/libprotobuf-mutator)
target_link_libraries(yul_proto_diff_custom_mutate_ossfuzz PRIVATE yul
diff --git a/test/tools/ossfuzz/YulOptimizerStepTest.cpp b/test/tools/ossfuzz/YulOptimizerStepTest.cpp
new file mode 100644
index 000000000..bccd64b93
--- /dev/null
+++ b/test/tools/ossfuzz/YulOptimizerStepTest.cpp
@@ -0,0 +1,367 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see .
+*/
+
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+
+using namespace solidity;
+using namespace solidity::util;
+using namespace solidity::langutil;
+using namespace solidity::yul;
+using namespace solidity::yul::test;
+using namespace solidity::frontend;
+using namespace solidity::frontend::test;
+using namespace std;
+
+YulOptimizerStepTest::YulOptimizerStepTest(
+ shared_ptr _obj,
+ Dialect const& _dialect,
+ string const& _optimizerStep
+)
+{
+ m_object = _obj;
+ m_ast = m_object->code;
+ m_analysisInfo = m_object->analysisInfo;
+ m_dialect = &_dialect;
+ m_optimizerStep = _optimizerStep;
+}
+
+shared_ptr YulOptimizerStepTest::run()
+{
+ soltestAssert(m_dialect, "Dialect not set.");
+
+ updateContext();
+
+ if (m_optimizerStep == "disambiguator")
+ disambiguate();
+ else if (m_optimizerStep == "nameDisplacer")
+ {
+ disambiguate();
+ NameDisplacer{
+ *m_nameDispenser,
+ {"illegal1"_yulstring, "illegal2"_yulstring, "illegal3"_yulstring, "illegal4"_yulstring, "illegal5"_yulstring}
+ }(*m_ast);
+ }
+ else if (m_optimizerStep == "blockFlattener")
+ {
+ disambiguate();
+ BlockFlattener::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "constantOptimiser")
+ {
+ GasMeter meter(dynamic_cast(*m_dialect), false, 200);
+ ConstantOptimiser{dynamic_cast(*m_dialect), meter}(*m_ast);
+ }
+ else if (m_optimizerStep == "varDeclInitializer")
+ VarDeclInitializer::run(*m_context, *m_ast);
+ else if (m_optimizerStep == "varNameCleaner")
+ {
+ FunctionHoister::run(*m_context, *m_ast);
+ VarNameCleaner::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "forLoopConditionIntoBody")
+ {
+ disambiguate();
+ ForLoopConditionIntoBody::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "forLoopInitRewriter")
+ {
+ disambiguate();
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "commonSubexpressionEliminator")
+ {
+ disambiguate();
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ FunctionHoister::run(*m_context, *m_ast);
+ CommonSubexpressionEliminator::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "conditionalUnsimplifier")
+ {
+ disambiguate();
+ ConditionalUnsimplifier::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "conditionalSimplifier")
+ {
+ disambiguate();
+ ConditionalSimplifier::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "expressionSplitter")
+ ExpressionSplitter::run(*m_context, *m_ast);
+ else if (m_optimizerStep == "expressionJoiner")
+ {
+ disambiguate();
+ ExpressionJoiner::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "splitJoin")
+ {
+ disambiguate();
+ ExpressionSplitter::run(*m_context, *m_ast);
+ ExpressionJoiner::run(*m_context, *m_ast);
+ ExpressionJoiner::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "functionGrouper")
+ {
+ disambiguate();
+ FunctionGrouper::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "functionHoister")
+ {
+ disambiguate();
+ FunctionHoister::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "expressionInliner")
+ {
+ disambiguate();
+ ExpressionInliner::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "fullInliner")
+ {
+ disambiguate();
+ FunctionHoister::run(*m_context, *m_ast);
+ FunctionGrouper::run(*m_context, *m_ast);
+ ExpressionSplitter::run(*m_context, *m_ast);
+ FullInliner::run(*m_context, *m_ast);
+ ExpressionJoiner::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "mainFunction")
+ {
+ disambiguate();
+ FunctionGrouper::run(*m_context, *m_ast);
+ MainFunction::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "rematerialiser")
+ {
+ disambiguate();
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ FunctionHoister::run(*m_context, *m_ast);
+ Rematerialiser::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "expressionSimplifier")
+ {
+ disambiguate();
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ FunctionHoister::run(*m_context, *m_ast);
+ ExpressionSimplifier::run(*m_context, *m_ast);
+ ExpressionSimplifier::run(*m_context, *m_ast);
+ ExpressionSimplifier::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "fullSimplify")
+ {
+ disambiguate();
+ ExpressionSplitter::run(*m_context, *m_ast);
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ FunctionHoister::run(*m_context, *m_ast);
+ CommonSubexpressionEliminator::run(*m_context, *m_ast);
+ ExpressionSimplifier::run(*m_context, *m_ast);
+ UnusedPruner::run(*m_context, *m_ast);
+ CircularReferencesPruner::run(*m_context, *m_ast);
+ DeadCodeEliminator::run(*m_context, *m_ast);
+ ExpressionJoiner::run(*m_context, *m_ast);
+ ExpressionJoiner::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "unusedPruner")
+ {
+ disambiguate();
+ UnusedPruner::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "circularReferencesPruner")
+ {
+ disambiguate();
+ FunctionHoister::run(*m_context, *m_ast);
+ CircularReferencesPruner::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "deadCodeEliminator")
+ {
+ disambiguate();
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ DeadCodeEliminator::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "ssaTransform")
+ {
+ disambiguate();
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ SSATransform::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "redundantAssignEliminator")
+ {
+ disambiguate();
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ RedundantAssignEliminator::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "ssaPlusCleanup")
+ {
+ disambiguate();
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ SSATransform::run(*m_context, *m_ast);
+ RedundantAssignEliminator::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "loadResolver")
+ {
+ disambiguate();
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ FunctionHoister::run(*m_context, *m_ast);
+ ExpressionSplitter::run(*m_context, *m_ast);
+ CommonSubexpressionEliminator::run(*m_context, *m_ast);
+ ExpressionSimplifier::run(*m_context, *m_ast);
+
+ LoadResolver::run(*m_context, *m_ast);
+
+ UnusedPruner::run(*m_context, *m_ast);
+ ExpressionJoiner::run(*m_context, *m_ast);
+ ExpressionJoiner::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "loopInvariantCodeMotion")
+ {
+ disambiguate();
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ FunctionHoister::run(*m_context, *m_ast);
+ LoopInvariantCodeMotion::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "controlFlowSimplifier")
+ {
+ disambiguate();
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ ControlFlowSimplifier::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "structuralSimplifier")
+ {
+ disambiguate();
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ FunctionHoister::run(*m_context, *m_ast);
+ LiteralRematerialiser::run(*m_context, *m_ast);
+ StructuralSimplifier::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "equivalentFunctionCombiner")
+ {
+ disambiguate();
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ FunctionHoister::run(*m_context, *m_ast);
+ EquivalentFunctionCombiner::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "ssaReverser")
+ {
+ disambiguate();
+ SSAReverser::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "ssaAndBack")
+ {
+ disambiguate();
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ // apply SSA
+ SSATransform::run(*m_context, *m_ast);
+ RedundantAssignEliminator::run(*m_context, *m_ast);
+ // reverse SSA
+ SSAReverser::run(*m_context, *m_ast);
+ FunctionHoister::run(*m_context, *m_ast);
+ CommonSubexpressionEliminator::run(*m_context, *m_ast);
+ UnusedPruner::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "stackCompressor")
+ {
+ disambiguate();
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ FunctionHoister::run(*m_context, *m_ast);
+ FunctionGrouper::run(*m_context, *m_ast);
+ size_t maxIterations = 16;
+ StackCompressor::run(*m_dialect, *m_object, true, maxIterations);
+ BlockFlattener::run(*m_context, *m_ast);
+ }
+ else if (m_optimizerStep == "wordSizeTransform")
+ {
+ disambiguate();
+ ExpressionSplitter::run(*m_context, *m_ast);
+ WordSizeTransform::run(*m_dialect, *m_dialect, *m_ast, *m_nameDispenser);
+ }
+ else if (m_optimizerStep == "fullSuite")
+ {
+ GasMeter meter(dynamic_cast(*m_dialect), false, 200);
+ OptimiserSuite::run(*m_dialect, &meter, *m_object, true, solidity::frontend::OptimiserSettings::DefaultYulOptimiserSteps);
+ }
+ else
+ solUnimplemented("Invalid optimization step");
+
+#if 0
+ std::cout << AsmPrinter{*m_dialect}(*m_ast) << std::endl;
+#endif
+
+ return m_ast;
+}
+
+void YulOptimizerStepTest::disambiguate()
+{
+ *m_ast = std::get(Disambiguator(*m_dialect, *m_analysisInfo)(*m_ast));
+ m_analysisInfo.reset();
+ updateContext();
+}
+
+void YulOptimizerStepTest::updateContext()
+{
+ m_nameDispenser = make_unique(*m_dialect, *m_ast, m_reservedIdentifiers);
+ m_context = make_unique(OptimiserStepContext{
+ *m_dialect,
+ *m_nameDispenser,
+ m_reservedIdentifiers
+ });
+}
diff --git a/test/tools/ossfuzz/YulOptimizerStepTest.h b/test/tools/ossfuzz/YulOptimizerStepTest.h
new file mode 100644
index 000000000..db5673181
--- /dev/null
+++ b/test/tools/ossfuzz/YulOptimizerStepTest.h
@@ -0,0 +1,73 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see .
+*/
+
+#pragma once
+
+#include
+#include
+
+#include
+
+#include
+#include
+
+namespace solidity::langutil
+{
+class Scanner;
+class Error;
+using ErrorList = std::vector>;
+class EVMVersion;
+}
+
+namespace solidity::yul
+{
+struct AsmAnalysisInfo;
+struct Block;
+struct Dialect;
+struct Object;
+}
+
+namespace solidity::yul::test
+{
+
+class YulOptimizerStepTest
+{
+public:
+ explicit YulOptimizerStepTest(
+ std::shared_ptr _obj,
+ Dialect const& _dialect,
+ std::string const& _optimizerStep
+ );
+ std::shared_ptr run();
+
+private:
+ void disambiguate();
+ void updateContext();
+
+ std::string m_optimizerStep;
+
+ Dialect const* m_dialect = nullptr;
+ std::set m_reservedIdentifiers;
+ std::unique_ptr m_nameDispenser;
+ std::unique_ptr m_context;
+
+ std::shared_ptr m_ast;
+ std::shared_ptr m_analysisInfo;
+ std::shared_ptr m_object;
+};
+
+}
diff --git a/test/tools/ossfuzz/protoToYul.cpp b/test/tools/ossfuzz/protoToYul.cpp
index aeb8fc665..9dc6cfbac 100644
--- a/test/tools/ossfuzz/protoToYul.cpp
+++ b/test/tools/ossfuzz/protoToYul.cpp
@@ -1905,6 +1905,87 @@ void ProtoConverter::buildObjectScopeTree(Object const& _x)
m_objectScope.emplace(objectName, node);
}
+string ProtoConverter::optStepToString(Program_OptimizerStep const& _x)
+{
+ switch (_x)
+ {
+ case Program_OptimizerStep_FULLSUITE:
+ return "fullSuite";
+ case Program_OptimizerStep_DISAMBIGUATOR:
+ return "disambiguator";
+ case Program_OptimizerStep_NAMEDISPLACER:
+ return "nameDisplacer";
+ case Program_OptimizerStep_BLOCKFLATTENER:
+ return "blockFlattener";
+ case Program_OptimizerStep_CONSTANTOPTIMISER:
+ return "constantOptimiser";
+ case Program_OptimizerStep_VARDECLINITIALIZER:
+ return "varDeclInitializer";
+ case Program_OptimizerStep_VARNAMECLEANER:
+ return "varNameCleaner";
+ case Program_OptimizerStep_FORLOOPCONDITIONINTOBODY:
+ return "forLoopConditionIntoBody";
+ case Program_OptimizerStep_FORLOOPINITREWRITER:
+ return "forLoopInitRewriter";
+ case Program_OptimizerStep_COMMONSUBEXPRESSIONELIMINATOR:
+ return "commonSubexpressionEliminator";
+ case Program_OptimizerStep_CONDITIONALUNSIMPLIFIER:
+ return "conditionalUnsimplifier";
+ case Program_OptimizerStep_CONDITIONALSIMPLIFIER:
+ return "conditionalSimplifier";
+ case Program_OptimizerStep_EXPRESSIONSPLITTER:
+ return "expressionSplitter";
+ case Program_OptimizerStep_EXPRESSIONJOINER:
+ return "expressionJoiner";
+ case Program_OptimizerStep_SPLITJOIN:
+ return "splitJoin";
+ case Program_OptimizerStep_FUNCTIONGROUPER:
+ return "functionGrouper";
+ case Program_OptimizerStep_FUNCTIONHOISTER:
+ return "functionHoister";
+ case Program_OptimizerStep_EXPRESSIONINLINER:
+ return "expressionInliner";
+ case Program_OptimizerStep_FULLINLINER:
+ return "fullInliner";
+ case Program_OptimizerStep_REMATERIALISER:
+ return "rematerialiser";
+ case Program_OptimizerStep_EXPRESSIONSIMPLIFIER:
+ return "expressionSimplifier";
+ case Program_OptimizerStep_FULLSIMPLIFY:
+ return "fullSimplify";
+ case Program_OptimizerStep_UNUSEDPRUNER:
+ return "unusedPruner";
+ case Program_OptimizerStep_CIRCULARREFERENCESPRUNER:
+ return "circularReferencesPruner";
+ case Program_OptimizerStep_DEADCODEELIMINATOR:
+ return "deadCodeEliminator";
+ case Program_OptimizerStep_SSATRANSFORM:
+ return "ssaTransform";
+ case Program_OptimizerStep_REDUNDANTASSIGNELIMINATOR:
+ return "redundantAssignEliminator";
+ case Program_OptimizerStep_SSAPLUSCLEANUP:
+ return "ssaPlusCleanup";
+ case Program_OptimizerStep_LOADRESOLVER:
+ return "loadResolver";
+ case Program_OptimizerStep_LOOPINVARIANTCODEMOTION:
+ return "loopInvariantCodeMotion";
+ case Program_OptimizerStep_CONTROLFLOWSIMPLIFIER:
+ return "controlFlowSimplifier";
+ case Program_OptimizerStep_STRUCTURALSIMPLIFIER:
+ return "structuralSimplifier";
+ case Program_OptimizerStep_EQUIVALENTFUNCTIONCOMBINER:
+ return "equivalentFunctionCombiner";
+ case Program_OptimizerStep_SSAREVERSER:
+ return "ssaReverser";
+ case Program_OptimizerStep_SSAANDBACK:
+ return "ssaAndBack";
+ case Program_OptimizerStep_STACKCOMPRESSION:
+ return "stackCompressor";
+ default:
+ return "fullSuite";
+ }
+}
+
void ProtoConverter::visit(Program const& _x)
{
// Initialize input size
@@ -1913,6 +1994,9 @@ void ProtoConverter::visit(Program const& _x)
// Record EVM Version
m_evmVersion = evmVersionMapping(_x.ver());
+ // Record optimizer step
+ m_optimizerStep = optStepToString(_x.step());
+
// Program is either a Yul object or a block of
// statements.
switch (_x.program_oneof_case())
diff --git a/test/tools/ossfuzz/protoToYul.h b/test/tools/ossfuzz/protoToYul.h
index bf9963726..2968b8abd 100644
--- a/test/tools/ossfuzz/protoToYul.h
+++ b/test/tools/ossfuzz/protoToYul.h
@@ -65,6 +65,12 @@ public:
return m_evmVersion;
}
+ /// Returns optimizer step string
+ std::string optStepString()
+ {
+ return m_optimizerStep;
+ }
+
private:
void visit(BinaryOp const&);
@@ -291,6 +297,9 @@ private:
/// enum of type Program_Version
solidity::langutil::EVMVersion evmVersionMapping(Program_Version const& _x);
+ /// Returns string representation of an optimization step.
+ std::string optStepToString(Program_OptimizerStep const& _x);
+
/// Returns a monotonically increasing counter that starts from zero.
unsigned counter()
{
@@ -390,5 +399,7 @@ private:
bool m_forInitScopeExtEnabled;
/// Object that holds the targeted evm version specified by protobuf input
solidity::langutil::EVMVersion m_evmVersion;
+ /// Optimizer step
+ std::string m_optimizerStep;
};
}
diff --git a/test/tools/ossfuzz/yulFuzzerCommon.cpp b/test/tools/ossfuzz/yulFuzzerCommon.cpp
index d977c7761..32387b844 100644
--- a/test/tools/ossfuzz/yulFuzzerCommon.cpp
+++ b/test/tools/ossfuzz/yulFuzzerCommon.cpp
@@ -63,7 +63,7 @@ yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret(
}
catch (ExpressionNestingLimitReached const&)
{
- reason = TerminationReason::ExpresionNestingLimitReached;
+ reason = TerminationReason::ExpressionNestingLimitReached;
}
catch (ExplicitlyTerminated const&)
{
diff --git a/test/tools/ossfuzz/yulFuzzerCommon.h b/test/tools/ossfuzz/yulFuzzerCommon.h
index a32c75705..08ce47f2a 100644
--- a/test/tools/ossfuzz/yulFuzzerCommon.h
+++ b/test/tools/ossfuzz/yulFuzzerCommon.h
@@ -28,7 +28,7 @@ struct yulFuzzerUtil
ExplicitlyTerminated,
StepLimitReached,
TraceLimitReached,
- ExpresionNestingLimitReached,
+ ExpressionNestingLimitReached,
None
};
diff --git a/test/tools/ossfuzz/yulProto.proto b/test/tools/ossfuzz/yulProto.proto
index 00ddc329d..5eb3e6824 100644
--- a/test/tools/ossfuzz/yulProto.proto
+++ b/test/tools/ossfuzz/yulProto.proto
@@ -410,11 +410,50 @@ message Program {
ISTANBUL = 6;
BERLIN = 7;
}
+ enum OptimizerStep {
+ FULLSUITE = 0;
+ DISAMBIGUATOR = 1;
+ NAMEDISPLACER = 2;
+ BLOCKFLATTENER = 3;
+ CONSTANTOPTIMISER = 4;
+ VARDECLINITIALIZER = 5;
+ VARNAMECLEANER = 6;
+ FORLOOPCONDITIONINTOBODY = 7;
+ FORLOOPINITREWRITER = 8;
+ COMMONSUBEXPRESSIONELIMINATOR = 9;
+ CONDITIONALUNSIMPLIFIER = 10;
+ CONDITIONALSIMPLIFIER = 11;
+ EXPRESSIONSPLITTER = 12;
+ EXPRESSIONJOINER = 13;
+ SPLITJOIN = 14;
+ FUNCTIONGROUPER = 15;
+ FUNCTIONHOISTER = 16;
+ EXPRESSIONINLINER = 17;
+ FULLINLINER = 18;
+ REMATERIALISER = 19;
+ EXPRESSIONSIMPLIFIER = 20;
+ FULLSIMPLIFY = 21;
+ UNUSEDPRUNER = 22;
+ CIRCULARREFERENCESPRUNER = 23;
+ DEADCODEELIMINATOR = 24;
+ SSATRANSFORM = 25;
+ REDUNDANTASSIGNELIMINATOR = 26;
+ SSAPLUSCLEANUP = 27;
+ LOADRESOLVER = 28;
+ LOOPINVARIANTCODEMOTION = 29;
+ CONTROLFLOWSIMPLIFIER = 30;
+ STRUCTURALSIMPLIFIER = 31;
+ EQUIVALENTFUNCTIONCOMBINER = 32;
+ SSAREVERSER = 33;
+ SSAANDBACK = 34;
+ STACKCOMPRESSION = 35;
+ }
oneof program_oneof {
Block block = 1;
Object obj = 2;
}
required Version ver = 3;
+ required OptimizerStep step = 4;
}
package solidity.yul.test.yul_fuzzer;
diff --git a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp
index 2ee2b702e..5191c7e5a 100644
--- a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp
+++ b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp
@@ -19,6 +19,7 @@
#include
#include
+#include
#include
#include
#include
@@ -59,6 +60,7 @@ DEFINE_PROTO_FUZZER(Program const& _input)
ProtoConverter converter;
string yul_source = converter.programToString(_input);
EVMVersion version = converter.version();
+ string optStep = converter.optStepString();
if (const char* dump_path = getenv("PROTO_FUZZER_DUMP_PATH"))
{
@@ -91,24 +93,29 @@ DEFINE_PROTO_FUZZER(Program const& _input)
ostringstream os1;
ostringstream os2;
+ auto const& evmDialect = EVMDialect::strictAssemblyForEVMObjects(version);
yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret(
os1,
stack.parserResult()->code,
- EVMDialect::strictAssemblyForEVMObjects(version)
+ evmDialect
);
if (
termReason == yulFuzzerUtil::TerminationReason::StepLimitReached ||
- termReason == yulFuzzerUtil::TerminationReason::TraceLimitReached ||
- termReason == yulFuzzerUtil::TerminationReason::ExpresionNestingLimitReached
+ termReason == yulFuzzerUtil::TerminationReason::ExpressionNestingLimitReached ||
+ termReason == yulFuzzerUtil::TerminationReason::TraceLimitReached
)
- return;
+ return;
- stack.optimize();
+ YulOptimizerStepTest optimizerStepTest(
+ stack.parserResult(),
+ evmDialect,
+ optStep
+ );
termReason = yulFuzzerUtil::interpret(
os2,
- stack.parserResult()->code,
- EVMDialect::strictAssemblyForEVMObjects(version)
+ optimizerStepTest.run(),
+ evmDialect
);
if (
termReason == yulFuzzerUtil::TerminationReason::StepLimitReached ||