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: | ||||
|  * 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. | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -216,7 +216,7 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart4( | ||||
| 
 | ||||
| template <class Pattern> | ||||
| std::vector<SimplificationRule<Pattern>> simplificationRuleListPart5( | ||||
| 	Pattern, | ||||
| 	Pattern A, | ||||
| 	Pattern, | ||||
| 	Pattern, | ||||
| 	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>{ | ||||
| 		Instruction::ADDRESS, | ||||
| 		Instruction::CALLER, | ||||
| @ -375,6 +391,30 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart7( | ||||
| 		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; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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) | ||||
| { | ||||
| 	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() | ||||
| 
 | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user