mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #6160 from ethereum/rulelist-reject
Optimize obsolete ANDs in combination with certain SHIFTs
This commit is contained in:
commit
91a54f9b4d
@ -5,6 +5,8 @@ Language Features:
|
|||||||
|
|
||||||
Compiler Features:
|
Compiler Features:
|
||||||
* SMTChecker: Support arithmetic compound assignment operators.
|
* SMTChecker: Support arithmetic compound assignment operators.
|
||||||
|
* Optimizer: Add rule for shifts by constants larger than 255 for Constantinople.
|
||||||
|
* Optimizer: Add rule to simplify certain ANDs and SHL combinations
|
||||||
* Yul: Adds break and continue keywords to for-loop syntax.
|
* Yul: Adds break and continue keywords to for-loop syntax.
|
||||||
|
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart4(
|
|||||||
|
|
||||||
template <class Pattern>
|
template <class Pattern>
|
||||||
std::vector<SimplificationRule<Pattern>> simplificationRuleListPart5(
|
std::vector<SimplificationRule<Pattern>> simplificationRuleListPart5(
|
||||||
Pattern,
|
Pattern A,
|
||||||
Pattern,
|
Pattern,
|
||||||
Pattern,
|
Pattern,
|
||||||
Pattern X,
|
Pattern X,
|
||||||
@ -236,6 +236,22 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart5(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replace SHL >=256, X with 0
|
||||||
|
rules.push_back({
|
||||||
|
{Instruction::SHL, {A, X}},
|
||||||
|
[=]() -> Pattern { return u256(0); },
|
||||||
|
true,
|
||||||
|
[=]() { return A.d() >= 256; }
|
||||||
|
});
|
||||||
|
|
||||||
|
// Replace SHR >=256, X with 0
|
||||||
|
rules.push_back({
|
||||||
|
{Instruction::SHR, {A, X}},
|
||||||
|
[=]() -> Pattern { return u256(0); },
|
||||||
|
true,
|
||||||
|
[=]() { return A.d() >= 256; }
|
||||||
|
});
|
||||||
|
|
||||||
for (auto const& op: std::vector<Instruction>{
|
for (auto const& op: std::vector<Instruction>{
|
||||||
Instruction::ADDRESS,
|
Instruction::ADDRESS,
|
||||||
Instruction::CALLER,
|
Instruction::CALLER,
|
||||||
@ -375,6 +391,30 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart7(
|
|||||||
false
|
false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
std::function<bool()> feasibilityFunction = [=]() {
|
||||||
|
if (B.d() > 256)
|
||||||
|
return false;
|
||||||
|
unsigned bAsUint = static_cast<unsigned>(B.d());
|
||||||
|
return (A.d() & (u256(-1) >> bAsUint)) == (u256(-1) >> bAsUint);
|
||||||
|
};
|
||||||
|
|
||||||
|
rules.push_back({
|
||||||
|
// AND(A, SHR(B, X)) -> A & ((2^256-1) >> B) == ((2^256-1) >> B)
|
||||||
|
{Instruction::AND, {A, {Instruction::SHR, {B, X}}}},
|
||||||
|
[=]() -> Pattern { return {Instruction::SHR, {B, X}}; },
|
||||||
|
false,
|
||||||
|
feasibilityFunction
|
||||||
|
});
|
||||||
|
|
||||||
|
rules.push_back({
|
||||||
|
// AND(SHR(B, X), A) -> ((2^256-1) >> B) & A == ((2^256-1) >> B)
|
||||||
|
{Instruction::AND, {{Instruction::SHR, {B, X}}, A}},
|
||||||
|
[=]() -> Pattern { return {Instruction::SHR, {B, X}}; },
|
||||||
|
false,
|
||||||
|
feasibilityFunction
|
||||||
|
});
|
||||||
|
|
||||||
return rules;
|
return rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1180,6 +1180,84 @@ BOOST_AUTO_TEST_CASE(cse_sub_zero)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(cse_remove_redundant_shift_masking)
|
||||||
|
{
|
||||||
|
if (!dev::test::Options::get().evmVersion().hasBitwiseShifting())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int i = 1; i < 256; i++)
|
||||||
|
{
|
||||||
|
checkCSE({
|
||||||
|
u256(boost::multiprecision::pow(u256(2), i)-1),
|
||||||
|
Instruction::CALLVALUE,
|
||||||
|
u256(256-i),
|
||||||
|
Instruction::SHR,
|
||||||
|
Instruction::AND
|
||||||
|
}, {
|
||||||
|
Instruction::CALLVALUE,
|
||||||
|
u256(256-i),
|
||||||
|
Instruction::SHR,
|
||||||
|
});
|
||||||
|
|
||||||
|
checkCSE({
|
||||||
|
Instruction::CALLVALUE,
|
||||||
|
u256(256-i),
|
||||||
|
Instruction::SHR,
|
||||||
|
u256(boost::multiprecision::pow(u256(2), i)-1),
|
||||||
|
Instruction::AND
|
||||||
|
}, {
|
||||||
|
Instruction::CALLVALUE,
|
||||||
|
u256(256-i),
|
||||||
|
Instruction::SHR,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that opt. does NOT trigger
|
||||||
|
for (int i = 1; i < 255; i++)
|
||||||
|
{
|
||||||
|
checkCSE({
|
||||||
|
u256(boost::multiprecision::pow(u256(2), i)-1),
|
||||||
|
Instruction::CALLVALUE,
|
||||||
|
u256(255-i),
|
||||||
|
Instruction::SHR,
|
||||||
|
Instruction::AND
|
||||||
|
}, { // Opt. did some reordering
|
||||||
|
Instruction::CALLVALUE,
|
||||||
|
u256(255-i),
|
||||||
|
Instruction::SHR,
|
||||||
|
u256(boost::multiprecision::pow(u256(2), i)-1),
|
||||||
|
Instruction::AND
|
||||||
|
});
|
||||||
|
|
||||||
|
checkCSE({
|
||||||
|
Instruction::CALLVALUE,
|
||||||
|
u256(255-i),
|
||||||
|
Instruction::SHR,
|
||||||
|
u256(boost::multiprecision::pow(u256(2), i)-1),
|
||||||
|
Instruction::AND
|
||||||
|
}, { // Opt. did some reordering
|
||||||
|
u256(boost::multiprecision::pow(u256(2), i)-1),
|
||||||
|
Instruction::CALLVALUE,
|
||||||
|
u256(255-i),
|
||||||
|
Instruction::SHR,
|
||||||
|
Instruction::AND
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//(x >> (31*8)) & 0xffffffff
|
||||||
|
checkCSE({
|
||||||
|
Instruction::CALLVALUE,
|
||||||
|
u256(31*8),
|
||||||
|
Instruction::SHR,
|
||||||
|
u256(0xffffffff),
|
||||||
|
Instruction::AND
|
||||||
|
}, {
|
||||||
|
Instruction::CALLVALUE,
|
||||||
|
u256(31*8),
|
||||||
|
Instruction::SHR
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(cse_remove_unwanted_masking_of_address)
|
BOOST_AUTO_TEST_CASE(cse_remove_unwanted_masking_of_address)
|
||||||
{
|
{
|
||||||
vector<Instruction> ops{
|
vector<Instruction> ops{
|
||||||
@ -1250,6 +1328,48 @@ BOOST_AUTO_TEST_CASE(cse_remove_unwanted_masking_of_address)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(cse_replace_too_large_shift)
|
||||||
|
{
|
||||||
|
if (!dev::test::Options::get().evmVersion().hasBitwiseShifting())
|
||||||
|
return;
|
||||||
|
|
||||||
|
checkCSE({
|
||||||
|
Instruction::CALLVALUE,
|
||||||
|
u256(299),
|
||||||
|
Instruction::SHL
|
||||||
|
}, {
|
||||||
|
u256(0)
|
||||||
|
});
|
||||||
|
|
||||||
|
checkCSE({
|
||||||
|
Instruction::CALLVALUE,
|
||||||
|
u256(299),
|
||||||
|
Instruction::SHR
|
||||||
|
}, {
|
||||||
|
u256(0)
|
||||||
|
});
|
||||||
|
|
||||||
|
checkCSE({
|
||||||
|
Instruction::CALLVALUE,
|
||||||
|
u256(255),
|
||||||
|
Instruction::SHL
|
||||||
|
}, {
|
||||||
|
Instruction::CALLVALUE,
|
||||||
|
u256(255),
|
||||||
|
Instruction::SHL
|
||||||
|
});
|
||||||
|
|
||||||
|
checkCSE({
|
||||||
|
Instruction::CALLVALUE,
|
||||||
|
u256(255),
|
||||||
|
Instruction::SHR
|
||||||
|
}, {
|
||||||
|
Instruction::CALLVALUE,
|
||||||
|
u256(255),
|
||||||
|
Instruction::SHR
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user