diff --git a/libsolidity/interface/OptimiserSettings.h b/libsolidity/interface/OptimiserSettings.h index 1ca46ccbc260..d736eb63a178 100644 --- a/libsolidity/interface/OptimiserSettings.h +++ b/libsolidity/interface/OptimiserSettings.h @@ -47,6 +47,8 @@ struct OptimiserSettings "xa[r]EscLM" // Turn into SSA and simplify "Vcul [j]" // Reverse SSA + "k" // preprocessing after some simplifications + // should have good "compilability" property here. "Trpeul" // Run functional expression inliner diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index c0082f5d69fd..e14e03cfabdc 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -93,6 +93,8 @@ add_library(yul optimiser/ConditionalUnsimplifier.h optimiser/ControlFlowSimplifier.cpp optimiser/ControlFlowSimplifier.h + optimiser/ConstantFunctionEvaluator.cpp + optimiser/ConstantFunctionEvaluator.h optimiser/DataFlowAnalyzer.cpp optimiser/DataFlowAnalyzer.h optimiser/DeadCodeEliminator.cpp @@ -192,6 +194,10 @@ add_library(yul optimiser/VarDeclInitializer.h optimiser/VarNameCleaner.cpp optimiser/VarNameCleaner.h + tools/interpreter/Interpreter.h + tools/interpreter/Interpreter.cpp + tools/interpreter/EVMInstructionInterpreter.h + tools/interpreter/EVMInstructionInterpreter.cpp ) target_link_libraries(yul PUBLIC evmasm solutil langutil smtutil fmt::fmt-header-only) diff --git a/libyul/optimiser/ConstantFunctionEvaluator.cpp b/libyul/optimiser/ConstantFunctionEvaluator.cpp new file mode 100644 index 000000000000..02eaa747fc4d --- /dev/null +++ b/libyul/optimiser/ConstantFunctionEvaluator.cpp @@ -0,0 +1,405 @@ +/* + 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 . +*/ +// SPDX-License-Identifier: GPL-3.0 +/** + * Optimiser component that performs function inlining for arbitrary functions. + */ + +#include + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +using namespace solidity; +using namespace solidity::evmasm; +using namespace solidity::yul; +using namespace solidity::yul::tools::interpreter; + +using namespace std::literals::string_literals; + +void ConstantFunctionEvaluator::run(OptimiserStepContext& _context, Block& _ast) +{ + ConstantFunctionEvaluator(_context.dialect)(_ast); +} + + +ConstantFunctionEvaluator::ConstantFunctionEvaluator(Dialect const& _dialect): + m_dialect(_dialect), + m_rootScope(), + m_currentScope(&m_rootScope) +{ +} + +void ConstantFunctionEvaluator::operator()(FunctionDefinition& _function) +{ + ASTModifier::operator()(_function); + if (_function.parameters.size() > 0) return ; + + InterpreterState state; + // TODO make these configurable + state.maxExprNesting = 100; + state.maxSteps = 10000; + state.maxTraceSize = 0; + // This must be limited, because the stack is also used in this optimizer component + state.maxRecursionDepth = 64; + + std::map returnVariables; + for (auto const& retVar: _function.returnVariables) + { + returnVariables[retVar.name] = 0; + } + + ArithmeticOnlyInterpreter interpreter( + state, + m_dialect, + *m_currentScope, + /* _callerRecursionDepth=*/ 0, + returnVariables + ); + try + { + interpreter(_function.body); + } catch (InterpreterTerminatedGeneric const&) + { + // won't replace body + return ; + } + + Block newBody; + newBody.debugData = _function.body.debugData; + + // After the execution, all debug data got swept away. To still maintain + // useful information, we assign the literal debug data with the debug data + // of the function itself. + // One case this assignment is helpful is in the case of function with only + // one return variable. In this case, it would likely be a solidity + // constant. + langutil::DebugData::ConstPtr literalDebugData = _function.debugData; + + for (auto const& retVar: _function.returnVariables) + { + Identifier ident; + ident.name = retVar.name; + + Literal val; + val.debugData = literalDebugData; + val.kind = LiteralKind::Number; + val.value = LiteralValue(interpreter.valueOfVariable(retVar.name)); + + Assignment assignment; + assignment.variableNames = { std::move(ident) }; + assignment.value = { std::make_unique(std::move(val)) }; + + newBody.statements.push_back(std::move(assignment)); + } + _function.body = std::move(newBody); +} + +void ConstantFunctionEvaluator::operator()(Block& _block) +{ + enterScope(_block); + + for (auto const& statement: _block.statements) + if (std::holds_alternative(statement)) + { + FunctionDefinition const& funDef = std::get(statement); + m_currentScope->names.emplace(funDef.name, &funDef); + } + + for (auto& statement: _block.statements) + { + visit(statement); + } + + leaveScope(); +} + +void ConstantFunctionEvaluator::enterScope(Block const& _block) +{ + if (!m_currentScope->subScopes.count(&_block)) + m_currentScope->subScopes[&_block] = std::make_unique(Scope{ + {}, + {}, + m_currentScope, + }); + m_currentScope = m_currentScope->subScopes[&_block].get(); +} + +void ConstantFunctionEvaluator::leaveScope() +{ + m_currentScope = m_currentScope->parent; + yulAssert(m_currentScope, ""); +} + +u256 ArithmeticOnlyInterpreter::evaluate(Expression const& _expression) +{ + ArithmeticOnlyExpressionEvaluator ev( + m_state, + m_dialect, + *m_scope, + m_variables, + m_disableExternalCalls, + m_disableMemoryTrace, + m_recursionDepth + ); + ev.visit(_expression); + return ev.value(); +} + +std::vector ArithmeticOnlyInterpreter::evaluateMulti(Expression const& _expression) +{ + ArithmeticOnlyExpressionEvaluator ev( + m_state, + m_dialect, + *m_scope, + m_variables, + m_disableExternalCalls, + m_disableMemoryTrace, + m_recursionDepth + ); + ev.visit(_expression); + return ev.values(); +} + + +void ArithmeticOnlyExpressionEvaluator::operator()(FunctionCall const& _funCall) +{ + FunctionCallType fnCallType = determineFunctionCallType(_funCall); + if (fnCallType == FunctionCallType::BuiltinNonArithmetic) + { + BOOST_THROW_EXCEPTION(BuiltinNonArithmeticFunctionInvoked()); + } + ExpressionEvaluator::operator()(_funCall); +} + +ArithmeticOnlyExpressionEvaluator::FunctionCallType +ArithmeticOnlyExpressionEvaluator::determineFunctionCallType(FunctionCall const& _funCall) +{ + if (EVMDialect const* dialect = dynamic_cast(&m_dialect)) + { + if (BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name)) + { + if (fun->instruction) + { + switch (*fun->instruction) + { + // --------------- arithmetic --------------- + case Instruction::ADD: + case Instruction::MUL: + case Instruction::SUB: + case Instruction::DIV: + case Instruction::SDIV: + case Instruction::MOD: + case Instruction::SMOD: + case Instruction::EXP: + case Instruction::NOT: + case Instruction::LT: + case Instruction::GT: + case Instruction::SLT: + case Instruction::SGT: + case Instruction::EQ: + case Instruction::ISZERO: + case Instruction::AND: + case Instruction::OR: + case Instruction::XOR: + case Instruction::BYTE: + case Instruction::SHL: + case Instruction::SHR: + case Instruction::SAR: + case Instruction::ADDMOD: + case Instruction::MULMOD: + case Instruction::SIGNEXTEND: + return FunctionCallType::BuiltinArithmetic; + // --------------- stop --------------------------- + case Instruction::STOP: + // --------------- blockchain stuff --------------- + case Instruction::KECCAK256: + case Instruction::ADDRESS: + case Instruction::BALANCE: + case Instruction::SELFBALANCE: + case Instruction::ORIGIN: + case Instruction::CALLER: + case Instruction::CALLVALUE: + case Instruction::CALLDATALOAD: + case Instruction::CALLDATASIZE: + case Instruction::CALLDATACOPY: + case Instruction::CODESIZE: + case Instruction::CODECOPY: + case Instruction::GASPRICE: + case Instruction::CHAINID: + case Instruction::BASEFEE: + case Instruction::BLOBHASH: + case Instruction::BLOBBASEFEE: + case Instruction::EXTCODESIZE: + case Instruction::EXTCODEHASH: + case Instruction::EXTCODECOPY: + case Instruction::RETURNDATASIZE: + case Instruction::RETURNDATACOPY: + case Instruction::MCOPY: + case Instruction::BLOCKHASH: + case Instruction::COINBASE: + case Instruction::TIMESTAMP: + case Instruction::NUMBER: + case Instruction::PREVRANDAO: + case Instruction::GASLIMIT: + // --------------- memory / storage / logs --------------- + case Instruction::MLOAD: + case Instruction::MSTORE: + case Instruction::MSTORE8: + case Instruction::SLOAD: + case Instruction::SSTORE: + case Instruction::PC: + case Instruction::MSIZE: + case Instruction::GAS: + case Instruction::LOG0: + case Instruction::LOG1: + case Instruction::LOG2: + case Instruction::LOG3: + case Instruction::LOG4: + case Instruction::TLOAD: + case Instruction::TSTORE: + // --------------- calls --------------- + case Instruction::CREATE: + case Instruction::CREATE2: + case Instruction::CALL: + case Instruction::CALLCODE: + case Instruction::DELEGATECALL: + case Instruction::STATICCALL: + case Instruction::RETURN: + case Instruction::REVERT: + case Instruction::INVALID: + case Instruction::SELFDESTRUCT: + return FunctionCallType::BuiltinNonArithmetic; + + // --------------- pop only discard value. ------------------ + case Instruction::POP: + return FunctionCallType::BuiltinArithmetic; + + // --------------- invalid in strict assembly --------------- + case Instruction::JUMP: + case Instruction::JUMPI: + case Instruction::JUMPDEST: + case Instruction::PUSH0: + case Instruction::PUSH1: + case Instruction::PUSH2: + case Instruction::PUSH3: + case Instruction::PUSH4: + case Instruction::PUSH5: + case Instruction::PUSH6: + case Instruction::PUSH7: + case Instruction::PUSH8: + case Instruction::PUSH9: + case Instruction::PUSH10: + case Instruction::PUSH11: + case Instruction::PUSH12: + case Instruction::PUSH13: + case Instruction::PUSH14: + case Instruction::PUSH15: + case Instruction::PUSH16: + case Instruction::PUSH17: + case Instruction::PUSH18: + case Instruction::PUSH19: + case Instruction::PUSH20: + case Instruction::PUSH21: + case Instruction::PUSH22: + case Instruction::PUSH23: + case Instruction::PUSH24: + case Instruction::PUSH25: + case Instruction::PUSH26: + case Instruction::PUSH27: + case Instruction::PUSH28: + case Instruction::PUSH29: + case Instruction::PUSH30: + case Instruction::PUSH31: + case Instruction::PUSH32: + case Instruction::DUP1: + case Instruction::DUP2: + case Instruction::DUP3: + case Instruction::DUP4: + case Instruction::DUP5: + case Instruction::DUP6: + case Instruction::DUP7: + case Instruction::DUP8: + case Instruction::DUP9: + case Instruction::DUP10: + case Instruction::DUP11: + case Instruction::DUP12: + case Instruction::DUP13: + case Instruction::DUP14: + case Instruction::DUP15: + case Instruction::DUP16: + case Instruction::SWAP1: + case Instruction::SWAP2: + case Instruction::SWAP3: + case Instruction::SWAP4: + case Instruction::SWAP5: + case Instruction::SWAP6: + case Instruction::SWAP7: + case Instruction::SWAP8: + case Instruction::SWAP9: + case Instruction::SWAP10: + case Instruction::SWAP11: + case Instruction::SWAP12: + case Instruction::SWAP13: + case Instruction::SWAP14: + case Instruction::SWAP15: + case Instruction::SWAP16: + { + yulAssert(false, ""); + } + } + } + else + { + static std::set const NON_INSTRUCTION_FUNC_NAME = { + "datasize", + "dataoffset", + "datacopy", + "memoryguard", + "loadimmutable", + "setimmutable", + "linkersymbol" + }; + if (NON_INSTRUCTION_FUNC_NAME.count(fun->name.str())) + { + return FunctionCallType::BuiltinNonArithmetic; + } + if (boost::algorithm::starts_with(fun->name.str(), "verbatim")) + { + return FunctionCallType::BuiltinNonArithmetic; + } + } + + yulAssert(false, "Can not determine function call type for function " + fun->name.str()); + } + } + + return FunctionCallType::InvokeOther; +} diff --git a/libyul/optimiser/ConstantFunctionEvaluator.h b/libyul/optimiser/ConstantFunctionEvaluator.h new file mode 100644 index 000000000000..4b7f753fb72d --- /dev/null +++ b/libyul/optimiser/ConstantFunctionEvaluator.h @@ -0,0 +1,174 @@ +/* + 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 . +*/ +// SPDX-License-Identifier: GPL-3.0 +/** + * Optimiser component that evaluates constant functions and replace theirs body + * with evaluated result. + */ +#pragma once + +#include + +#include +#include +#include +#include + +namespace solidity::yul +{ + + +/** + * Optimiser component that evaluates constant functions and replace theirs body + * with evaluated result. + * + * A function is _constant_ if it satisfies all of the following criteria: + * - It take no arguments + * - If executed, this function only perform arithmetic operations and calls + * other function (that only does arithmetic expression). This means + * if any of reading from/writing to any memory, logging, creating contract, ... + * operations encountered, the function is not constant. + * + * Non-constant functions are left unchanged after the transformation. + * + * Under the hood, this component will use yul interpreter to evaluate the function. + * + * For example, this component may change the following code: + * + * function foo() -> x + * { + * let u, v := bar() + * x := add(u, v) + * } + * + * function bar() -> u, v + * { + * switch iszero(0) { u := 6 v := 9 } + * default { u := 4 v := 20 } + * } + * + * into + * + * function foo() -> x + * { x := 15 } + * + * function bar() -> u, v + * { u, v := 6, 9 } + */ +class ConstantFunctionEvaluator: public ASTModifier +{ +public: + static constexpr char const* name{"ConstantFunctionEvaluator"}; + static void run(OptimiserStepContext& _context, Block& _ast); + + void operator()(FunctionDefinition& _function) override; + void operator()(Block& _block) override; + +private: + ConstantFunctionEvaluator(Dialect const& _dialect); + + void enterScope(Block const& _block); + void leaveScope(); + + Dialect const& m_dialect; + tools::interpreter::Scope m_rootScope; + tools::interpreter::Scope* m_currentScope; +}; + + +} + +namespace solidity::yul::tools::interpreter +{ + +class BuiltinNonArithmeticFunctionInvoked: public InterpreterTerminatedGeneric +{ +}; + +class UnlimitedLiteralEncountered: public InterpreterTerminatedGeneric +{ +}; + +class ArithmeticOnlyInterpreter : public Interpreter +{ +public: + ArithmeticOnlyInterpreter( + InterpreterState& _state, + Dialect const& _dialect, + Scope& _scope, + size_t _callerRecursionDepth, + std::map _variables = {} + ): Interpreter( + _state, + _dialect, + _scope, + /* _disableExternalCalls=*/ false, // we disable by explicit check + /* _disableMemoryTracing=*/ true, + _callerRecursionDepth, + _variables + ) + { + } + +protected: + virtual u256 evaluate(Expression const& _expression) override; + virtual std::vector evaluateMulti(Expression const& _expression) override; +}; + +class ArithmeticOnlyExpressionEvaluator: public ExpressionEvaluator +{ +public: + using ExpressionEvaluator::ExpressionEvaluator; + + void operator()(FunctionCall const& _funCall) override; + +protected: + enum class FunctionCallType + { + BuiltinArithmetic, + BuiltinNonArithmetic, + InvokeOther, + }; + + virtual std::unique_ptr makeInterpreterCopy(std::map _variables = {}) const override + { + return std::make_unique( + m_state, + m_dialect, + m_scope, + m_recursionDepth, + std::move(_variables) + ); + } + virtual std::unique_ptr makeInterpreterNew(InterpreterState& _state, Scope& _scope) const override + { + return std::make_unique( + _state, + m_dialect, + _scope, + m_recursionDepth + ); + } + + u256 getValueForUnlimitedLiteral(Literal const&) override + { + BOOST_THROW_EXCEPTION(UnlimitedLiteralEncountered()); + } + FunctionCallType determineFunctionCallType(FunctionCall const& _funCall); +}; + +} diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index d7043e42f30f..948d40cd2113 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -264,6 +265,7 @@ std::map> const& OptimiserSuite::all ConditionalSimplifier, ConditionalUnsimplifier, ControlFlowSimplifier, + ConstantFunctionEvaluator, DeadCodeEliminator, EqualStoreEliminator, EquivalentFunctionCombiner, @@ -305,6 +307,7 @@ std::map const& OptimiserSuite::stepNameToAbbreviationMap() {ConditionalSimplifier::name, 'C'}, {ConditionalUnsimplifier::name, 'U'}, {ControlFlowSimplifier::name, 'n'}, + {ConstantFunctionEvaluator::name, 'k'}, {DeadCodeEliminator::name, 'D'}, {EqualStoreEliminator::name, 'E'}, {EquivalentFunctionCombiner::name, 'v'}, diff --git a/libyul/tools/interpreter/EVMInstructionInterpreter.cpp b/libyul/tools/interpreter/EVMInstructionInterpreter.cpp new file mode 100644 index 000000000000..1813fe15b390 --- /dev/null +++ b/libyul/tools/interpreter/EVMInstructionInterpreter.cpp @@ -0,0 +1,706 @@ +/* + 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 . +*/ +// SPDX-License-Identifier: GPL-3.0 +/** + * Yul interpreter module that evaluates EVM instructions. + */ + +#include + +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +using namespace solidity; +using namespace solidity::evmasm; +using namespace solidity::yul; +using namespace solidity::yul::tools::interpreter; + +using solidity::util::h160; +using solidity::util::h256; +using solidity::util::keccak256; + +namespace +{ + +/// Reads 32 bytes from @a _data at position @a _offset bytes while +/// interpreting @a _data to be padded with an infinite number of zero +/// bytes beyond its end. +u256 readZeroExtended(bytes const& _data, u256 const& _offset) +{ + if (_offset >= _data.size()) + return 0; + else if (_offset + 32 <= _data.size()) + return *reinterpret_cast(_data.data() + static_cast(_offset)); + else + { + size_t off = static_cast(_offset); + u256 val; + for (size_t i = 0; i < 32; ++i) + { + val <<= 8; + if (off + i < _data.size()) + val += _data[off + i]; + } + return val; + } +} + +} + +namespace solidity::yul::tools::interpreter +{ + +void copyZeroExtended( + std::map& _target, + bytes const& _source, + size_t _targetOffset, + size_t _sourceOffset, + size_t _size +) +{ + for (size_t i = 0; i < _size; ++i) + _target[_targetOffset + i] = (_sourceOffset + i < _source.size() ? _source[_sourceOffset + i] : 0); +} + +void copyZeroExtendedWithOverlap( + std::map& _target, + std::map const& _source, + size_t _targetOffset, + size_t _sourceOffset, + size_t _size +) +{ + if (_targetOffset >= _sourceOffset) + for (size_t i = _size; i > 0; --i) + _target[_targetOffset + i - 1] = (_source.count(_sourceOffset + i - 1) != 0 ? _source.at(_sourceOffset + i - 1) : 0); + else + for (size_t i = 0; i < _size; ++i) + _target[_targetOffset + i] = (_source.count(_sourceOffset + i) != 0 ? _source.at(_sourceOffset + i) : 0); +} + +} + +using u512 = boost::multiprecision::number>; + +u256 EVMInstructionInterpreter::eval( + evmasm::Instruction _instruction, + std::vector const& _arguments +) +{ + using namespace solidity::evmasm; + using evmasm::Instruction; + + auto info = instructionInfo(_instruction, m_evmVersion); + yulAssert(static_cast(info.args) == _arguments.size(), ""); + + auto const& arg = _arguments; + switch (_instruction) + { + case Instruction::STOP: + logTrace(_instruction); + BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); + // --------------- arithmetic --------------- + case Instruction::ADD: + return arg[0] + arg[1]; + case Instruction::MUL: + return arg[0] * arg[1]; + case Instruction::SUB: + return arg[0] - arg[1]; + case Instruction::DIV: + return arg[1] == 0 ? 0 : arg[0] / arg[1]; + case Instruction::SDIV: + return arg[1] == 0 ? 0 : s2u(u2s(arg[0]) / u2s(arg[1])); + case Instruction::MOD: + return arg[1] == 0 ? 0 : arg[0] % arg[1]; + case Instruction::SMOD: + return arg[1] == 0 ? 0 : s2u(u2s(arg[0]) % u2s(arg[1])); + case Instruction::EXP: + return exp256(arg[0], arg[1]); + case Instruction::NOT: + return ~arg[0]; + case Instruction::LT: + return arg[0] < arg[1] ? 1 : 0; + case Instruction::GT: + return arg[0] > arg[1] ? 1 : 0; + case Instruction::SLT: + return u2s(arg[0]) < u2s(arg[1]) ? 1 : 0; + case Instruction::SGT: + return u2s(arg[0]) > u2s(arg[1]) ? 1 : 0; + case Instruction::EQ: + return arg[0] == arg[1] ? 1 : 0; + case Instruction::ISZERO: + return arg[0] == 0 ? 1 : 0; + case Instruction::AND: + return arg[0] & arg[1]; + case Instruction::OR: + return arg[0] | arg[1]; + case Instruction::XOR: + return arg[0] ^ arg[1]; + case Instruction::BYTE: + return arg[0] >= 32 ? 0 : (arg[1] >> unsigned(8 * (31 - arg[0]))) & 0xff; + case Instruction::SHL: + return arg[0] > 255 ? 0 : (arg[1] << unsigned(arg[0])); + case Instruction::SHR: + return arg[0] > 255 ? 0 : (arg[1] >> unsigned(arg[0])); + case Instruction::SAR: + { + static u256 const hibit = u256(1) << 255; + if (arg[0] >= 256) + return arg[1] & hibit ? u256(-1) : 0; + else + { + unsigned amount = unsigned(arg[0]); + u256 v = arg[1] >> amount; + if (arg[1] & hibit) + v |= u256(-1) << (256 - amount); + return v; + } + } + case Instruction::ADDMOD: + return arg[2] == 0 ? 0 : u256((u512(arg[0]) + u512(arg[1])) % arg[2]); + case Instruction::MULMOD: + return arg[2] == 0 ? 0 : u256((u512(arg[0]) * u512(arg[1])) % arg[2]); + case Instruction::SIGNEXTEND: + if (arg[0] >= 31) + return arg[1]; + else + { + unsigned testBit = unsigned(arg[0]) * 8 + 7; + u256 ret = arg[1]; + u256 mask = ((u256(1) << testBit) - 1); + if (boost::multiprecision::bit_test(ret, testBit)) + ret |= ~mask; + else + ret &= mask; + return ret; + } + // --------------- blockchain stuff --------------- + case Instruction::KECCAK256: + { + if (!accessMemory(arg[0], arg[1])) + return u256("0x1234cafe1234cafe1234cafe") + arg[0]; + uint64_t offset = uint64_t(arg[0] & uint64_t(-1)); + uint64_t size = uint64_t(arg[1] & uint64_t(-1)); + return u256(keccak256(m_state.readMemory(offset, size))); + } + case Instruction::ADDRESS: + return h256(m_state.address, h256::AlignRight); + case Instruction::BALANCE: + if (arg[0] == h256(m_state.address, h256::AlignRight)) + return m_state.selfbalance; + else + return m_state.balance; + case Instruction::SELFBALANCE: + return m_state.selfbalance; + case Instruction::ORIGIN: + return h256(m_state.origin, h256::AlignRight); + case Instruction::CALLER: + return h256(m_state.caller, h256::AlignRight); + case Instruction::CALLVALUE: + return m_state.callvalue; + case Instruction::CALLDATALOAD: + return readZeroExtended(m_state.calldata, arg[0]); + case Instruction::CALLDATASIZE: + return m_state.calldata.size(); + case Instruction::CALLDATACOPY: + if (accessMemory(arg[0], arg[2])) + copyZeroExtended( + m_state.memory, m_state.calldata, + size_t(arg[0]), size_t(arg[1]), size_t(arg[2]) + ); + logTrace(_instruction, arg); + return 0; + case Instruction::CODESIZE: + return m_state.code.size(); + case Instruction::CODECOPY: + if (accessMemory(arg[0], arg[2])) + copyZeroExtended( + m_state.memory, m_state.code, + size_t(arg[0]), size_t(arg[1]), size_t(arg[2]) + ); + logTrace(_instruction, arg); + return 0; + case Instruction::GASPRICE: + return m_state.gasprice; + case Instruction::CHAINID: + return m_state.chainid; + case Instruction::BASEFEE: + return m_state.basefee; + case Instruction::BLOBHASH: + return blobHash(arg[0]); + case Instruction::BLOBBASEFEE: + return m_state.blobbasefee; + case Instruction::EXTCODESIZE: + return u256(keccak256(h256(arg[0]))) & 0xffffff; + case Instruction::EXTCODEHASH: + return u256(keccak256(h256(arg[0] + 1))); + case Instruction::EXTCODECOPY: + if (accessMemory(arg[1], arg[3])) + // TODO this way extcodecopy and codecopy do the same thing. + copyZeroExtended( + m_state.memory, m_state.code, + size_t(arg[1]), size_t(arg[2]), size_t(arg[3]) + ); + logTrace(_instruction, arg); + return 0; + case Instruction::RETURNDATASIZE: + return m_state.returndata.size(); + case Instruction::RETURNDATACOPY: + if (accessMemory(arg[0], arg[2])) + copyZeroExtended( + m_state.memory, m_state.returndata, + size_t(arg[0]), size_t(arg[1]), size_t(arg[2]) + ); + logTrace(_instruction, arg); + return 0; + case Instruction::MCOPY: + if (accessMemory(arg[1], arg[2]) && accessMemory(arg[0], arg[2])) + copyZeroExtendedWithOverlap( + m_state.memory, + m_state.memory, + static_cast(arg[0]), + static_cast(arg[1]), + static_cast(arg[2]) + ); + logTrace(_instruction, arg); + return 0; + case Instruction::BLOCKHASH: + if (arg[0] >= m_state.blockNumber || arg[0] + 256 < m_state.blockNumber) + return 0; + else + return 0xaaaaaaaa + (arg[0] - m_state.blockNumber - 256); + case Instruction::COINBASE: + return h256(m_state.coinbase, h256::AlignRight); + case Instruction::TIMESTAMP: + return m_state.timestamp; + case Instruction::NUMBER: + return m_state.blockNumber; + case Instruction::PREVRANDAO: + return (m_evmVersion < langutil::EVMVersion::paris()) ? m_state.difficulty : m_state.prevrandao; + case Instruction::GASLIMIT: + return m_state.gaslimit; + // --------------- memory / storage / logs --------------- + case Instruction::MLOAD: + accessMemory(arg[0], 0x20); + return readMemoryWord(arg[0]); + case Instruction::MSTORE: + accessMemory(arg[0], 0x20); + writeMemoryWord(arg[0], arg[1]); + return 0; + case Instruction::MSTORE8: + accessMemory(arg[0], 1); + m_state.memory[arg[0]] = uint8_t(arg[1] & 0xff); + return 0; + case Instruction::SLOAD: + return m_state.storage[h256(arg[0])]; + case Instruction::SSTORE: + m_state.storage[h256(arg[0])] = h256(arg[1]); + return 0; + case Instruction::PC: + return 0x77; + case Instruction::MSIZE: + return m_state.msize; + case Instruction::GAS: + return 0x99; + case Instruction::LOG0: + accessMemory(arg[0], arg[1]); + logTrace(_instruction, arg); + return 0; + case Instruction::LOG1: + accessMemory(arg[0], arg[1]); + logTrace(_instruction, arg); + return 0; + case Instruction::LOG2: + accessMemory(arg[0], arg[1]); + logTrace(_instruction, arg); + return 0; + case Instruction::LOG3: + accessMemory(arg[0], arg[1]); + logTrace(_instruction, arg); + return 0; + case Instruction::LOG4: + accessMemory(arg[0], arg[1]); + logTrace(_instruction, arg); + return 0; + case Instruction::TLOAD: + return m_state.transientStorage[h256(arg[0])]; + case Instruction::TSTORE: + m_state.transientStorage[h256(arg[0])] = h256(arg[1]); + return 0; + // --------------- calls --------------- + case Instruction::CREATE: + accessMemory(arg[1], arg[2]); + logTrace(_instruction, arg); + if (arg[2] != 0) + return (0xcccccc + arg[1]) & u256("0xffffffffffffffffffffffffffffffffffffffff"); + else + return 0xcccccc; + case Instruction::CREATE2: + accessMemory(arg[1], arg[2]); + logTrace(_instruction, arg); + if (arg[2] != 0) + return (0xdddddd + arg[1]) & u256("0xffffffffffffffffffffffffffffffffffffffff"); + else + return 0xdddddd; + case Instruction::CALL: + case Instruction::CALLCODE: + accessMemory(arg[3], arg[4]); + accessMemory(arg[5], arg[6]); + logTrace(_instruction, arg); + // Randomly fail based on the called address if it isn't a call to self. + // Used for fuzzing. + return ( + (arg[0] > 0) && + (arg[1] == util::h160::Arith(m_state.address) || (arg[1] & 1)) + ) ? 1 : 0; + case Instruction::DELEGATECALL: + case Instruction::STATICCALL: + accessMemory(arg[2], arg[3]); + accessMemory(arg[4], arg[5]); + logTrace(_instruction, arg); + // Randomly fail based on the called address if it isn't a call to self. + // Used for fuzzing. + return ( + (arg[0] > 0) && + (arg[1] == util::h160::Arith(m_state.address) || (arg[1] & 1)) + ) ? 1 : 0; + case Instruction::RETURN: + { + m_state.returndata = {}; + if (accessMemory(arg[0], arg[1])) + m_state.returndata = m_state.readMemory(arg[0], arg[1]); + logTrace(_instruction, arg, m_state.returndata); + BOOST_THROW_EXCEPTION(ExplicitlyTerminatedWithReturn()); + } + case Instruction::REVERT: + accessMemory(arg[0], arg[1]); + logTrace(_instruction, arg); + m_state.storage.clear(); + m_state.transientStorage.clear(); + BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); + case Instruction::INVALID: + logTrace(_instruction); + m_state.storage.clear(); + m_state.transientStorage.clear(); + m_state.trace.clear(); + BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); + case Instruction::SELFDESTRUCT: + logTrace(_instruction, arg); + m_state.storage.clear(); + m_state.transientStorage.clear(); + m_state.trace.clear(); + BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); + case Instruction::POP: + break; + // --------------- invalid in strict assembly --------------- + case Instruction::JUMP: + case Instruction::JUMPI: + case Instruction::JUMPDEST: + case Instruction::PUSH0: + case Instruction::PUSH1: + case Instruction::PUSH2: + case Instruction::PUSH3: + case Instruction::PUSH4: + case Instruction::PUSH5: + case Instruction::PUSH6: + case Instruction::PUSH7: + case Instruction::PUSH8: + case Instruction::PUSH9: + case Instruction::PUSH10: + case Instruction::PUSH11: + case Instruction::PUSH12: + case Instruction::PUSH13: + case Instruction::PUSH14: + case Instruction::PUSH15: + case Instruction::PUSH16: + case Instruction::PUSH17: + case Instruction::PUSH18: + case Instruction::PUSH19: + case Instruction::PUSH20: + case Instruction::PUSH21: + case Instruction::PUSH22: + case Instruction::PUSH23: + case Instruction::PUSH24: + case Instruction::PUSH25: + case Instruction::PUSH26: + case Instruction::PUSH27: + case Instruction::PUSH28: + case Instruction::PUSH29: + case Instruction::PUSH30: + case Instruction::PUSH31: + case Instruction::PUSH32: + case Instruction::DUP1: + case Instruction::DUP2: + case Instruction::DUP3: + case Instruction::DUP4: + case Instruction::DUP5: + case Instruction::DUP6: + case Instruction::DUP7: + case Instruction::DUP8: + case Instruction::DUP9: + case Instruction::DUP10: + case Instruction::DUP11: + case Instruction::DUP12: + case Instruction::DUP13: + case Instruction::DUP14: + case Instruction::DUP15: + case Instruction::DUP16: + case Instruction::SWAP1: + case Instruction::SWAP2: + case Instruction::SWAP3: + case Instruction::SWAP4: + case Instruction::SWAP5: + case Instruction::SWAP6: + case Instruction::SWAP7: + case Instruction::SWAP8: + case Instruction::SWAP9: + case Instruction::SWAP10: + case Instruction::SWAP11: + case Instruction::SWAP12: + case Instruction::SWAP13: + case Instruction::SWAP14: + case Instruction::SWAP15: + case Instruction::SWAP16: + { + yulAssert(false, ""); + return 0; + } + } + + return 0; +} + +u256 EVMInstructionInterpreter::evalBuiltin( + BuiltinFunctionForEVM const& _fun, + std::vector const& _arguments, + std::vector const& _evaluatedArguments +) +{ + if (_fun.instruction) + return eval(*_fun.instruction, _evaluatedArguments); + + std::string fun = _fun.name.str(); + // Evaluate datasize/offset/copy instructions + if (fun == "datasize" || fun == "dataoffset") + { + std::string arg = formatLiteral(std::get(_arguments.at(0))); + if (arg.length() < 32) + arg.resize(32, 0); + if (fun == "datasize") + return u256(keccak256(arg)) & 0xfff; + else + { + // Force different value than for datasize + arg[31]++; + arg[31]++; + return u256(keccak256(arg)) & 0xfff; + } + } + else if (fun == "datacopy") + { + // This is identical to codecopy. + if ( + _evaluatedArguments.at(2) != 0 && + accessMemory(_evaluatedArguments.at(0), _evaluatedArguments.at(2)) + ) + copyZeroExtended( + m_state.memory, + m_state.code, + size_t(_evaluatedArguments.at(0)), + size_t(_evaluatedArguments.at(1) & std::numeric_limits::max()), + size_t(_evaluatedArguments.at(2)) + ); + return 0; + } + else if (fun == "memoryguard") + return _evaluatedArguments.at(0); + else { + m_state.trace.push_back("Unknown builtin: " + fun); + BOOST_THROW_EXCEPTION(UnsupportedBuiltinFunctionEvaluated()); + } + return 0; +} + + +bool EVMInstructionInterpreter::accessMemory(u256 const& _offset, u256 const& _size) +{ + if (_size == 0) + return true; + + if (_offset <= (_offset + _size) && (_offset + _size) <= (_offset + _size + 0x1f)) + { + u256 newMSize = (_offset + _size + 0x1f) & ~u256(0x1f); + m_state.msize = std::max(m_state.msize, newMSize); + // We only record accesses to contiguous memory chunks that are at most s_maxRangeSize bytes + // in size and at an offset of at most numeric_limits::max() - s_maxRangeSize + return _size <= s_maxRangeSize && _offset <= u256(std::numeric_limits::max() - s_maxRangeSize); + } + + m_state.msize = u256(-1); + return false; +} + +bytes EVMInstructionInterpreter::readMemory(u256 const& _offset, u256 const& _size) +{ + yulAssert(_size <= s_maxRangeSize, "Too large read."); + bytes data(size_t(_size), uint8_t(0)); + for (size_t i = 0; i < data.size(); ++i) + data[i] = m_state.memory[_offset + i]; + return data; +} + +u256 EVMInstructionInterpreter::readMemoryWord(u256 const& _offset) +{ + return u256(h256(m_state.readMemory(_offset, 32))); +} + +void EVMInstructionInterpreter::writeMemoryWord(u256 const& _offset, u256 const& _value) +{ + for (size_t i = 0; i < 32; i++) + m_state.memory[_offset + i] = uint8_t((_value >> (8 * (31 - i))) & 0xff); +} + + +void EVMInstructionInterpreter::logTrace( + evmasm::Instruction _instruction, + std::vector const& _arguments, + bytes const& _data +) +{ + logTrace( + evmasm::instructionInfo(_instruction, m_evmVersion).name, + SemanticInformation::memory(_instruction) == SemanticInformation::Effect::Write, + _arguments, + _data + ); +} + +void EVMInstructionInterpreter::logTrace( + std::string const& _pseudoInstruction, + bool _writesToMemory, + std::vector const& _arguments, + bytes const& _data +) +{ + if (!(_writesToMemory && memWriteTracingDisabled())) + { + std::string message = _pseudoInstruction + "("; + std::pair inputMemoryPtrModified = isInputMemoryPtrModified(_pseudoInstruction, _arguments); + for (size_t i = 0; i < _arguments.size(); ++i) + { + bool printZero = inputMemoryPtrModified.first && inputMemoryPtrModified.second == i; + u256 arg = printZero ? 0 : _arguments[i]; + message += (i > 0 ? ", " : "") + formatNumber(arg); + } + message += ")"; + if (!_data.empty()) + message += " [" + util::toHex(_data) + "]"; + m_state.trace.emplace_back(std::move(message)); + if (m_state.maxTraceSize > 0 && m_state.trace.size() >= m_state.maxTraceSize) + { + m_state.trace.emplace_back("Trace size limit reached."); + BOOST_THROW_EXCEPTION(TraceLimitReached()); + } + } +} + +std::pair EVMInstructionInterpreter::isInputMemoryPtrModified( + std::string const& _pseudoInstruction, + std::vector const& _arguments +) +{ + if (_pseudoInstruction == "RETURN" || _pseudoInstruction == "REVERT") + { + if (_arguments[1] == 0) + return {true, 0}; + else + return {false, 0}; + } + else if ( + _pseudoInstruction == "RETURNDATACOPY" || _pseudoInstruction == "CALLDATACOPY" + || _pseudoInstruction == "CODECOPY") + { + if (_arguments[2] == 0) + return {true, 0}; + else + return {false, 0}; + } + else if (_pseudoInstruction == "EXTCODECOPY") + { + if (_arguments[3] == 0) + return {true, 1}; + else + return {false, 0}; + } + else if ( + _pseudoInstruction == "LOG0" || _pseudoInstruction == "LOG1" || _pseudoInstruction == "LOG2" + || _pseudoInstruction == "LOG3" || _pseudoInstruction == "LOG4") + { + if (_arguments[1] == 0) + return {true, 0}; + else + return {false, 0}; + } + if (_pseudoInstruction == "CREATE" || _pseudoInstruction == "CREATE2") + { + if (_arguments[2] == 0) + return {true, 1}; + else + return {false, 0}; + } + if (_pseudoInstruction == "CALL" || _pseudoInstruction == "CALLCODE") + { + if (_arguments[4] == 0) + return {true, 3}; + else + return {false, 0}; + } + else if (_pseudoInstruction == "DELEGATECALL" || _pseudoInstruction == "STATICCALL") + { + if (_arguments[3] == 0) + return {true, 2}; + else + return {false, 0}; + } + else + return {false, 0}; +} + +h256 EVMInstructionInterpreter::blobHash(u256 const& _index) +{ + yulAssert(m_evmVersion.hasBlobHash()); + if (_index >= m_state.blobCommitments.size()) + return util::FixedHash<32>{}; + + h256 hashedCommitment = h256(picosha2::hash256(toBigEndian(m_state.blobCommitments[static_cast(_index)]))); + yulAssert(m_state.blobHashVersion.size == 1); + hashedCommitment[0] = *m_state.blobHashVersion.data(); + yulAssert(hashedCommitment.size == 32); + return hashedCommitment; +} diff --git a/libyul/tools/interpreter/EVMInstructionInterpreter.h b/libyul/tools/interpreter/EVMInstructionInterpreter.h new file mode 100644 index 000000000000..f1c2a203b96d --- /dev/null +++ b/libyul/tools/interpreter/EVMInstructionInterpreter.h @@ -0,0 +1,177 @@ +/* + 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 . +*/ +// SPDX-License-Identifier: GPL-3.0 +/** + * Yul interpreter module that evaluates EVM instructions. + */ + +#pragma once + +#include + +#include +#include +#include + +#include + +#include + +namespace solidity::evmasm +{ +enum class Instruction: uint8_t; +} + +namespace solidity::yul +{ +class YulString; +struct BuiltinFunctionForEVM; +} + +namespace solidity::yul::tools::interpreter +{ + +/// Copy @a _size bytes of @a _source at offset @a _sourceOffset to +/// @a _target at offset @a _targetOffset. Behaves as if @a _source would +/// continue with an infinite sequence of zero bytes beyond its end. +void copyZeroExtended( + std::map& _target, + bytes const& _source, + size_t _targetOffset, + size_t _sourceOffset, + size_t _size +); + +/// Copy @a _size bytes of @a _source at offset @a _sourceOffset to +/// @a _target at offset @a _targetOffset. Behaves as if @a _source would +/// continue with an infinite sequence of zero bytes beyond its end. +/// When target and source areas overlap, behaves as if the data was copied +/// using an intermediate buffer. +void copyZeroExtendedWithOverlap( + std::map& _target, + std::map const& _source, + size_t _targetOffset, + size_t _sourceOffset, + size_t _size +); + +struct InterpreterState; + +/** + * Interprets EVM instructions based on the current state and logs instructions with + * side-effects. + * + * Since this is mainly meant to be used for differential fuzz testing, it is focused + * on a single contract only, does not do any gas counting and differs from the correct + * implementation in many ways: + * + * - If memory access to a "large" memory position is performed, a deterministic + * value is returned. Data that is stored in a "large" memory position is not + * retained. + * - The blockhash instruction returns a fixed value if the argument is in range. + * - Extcodesize returns a deterministic value depending on the address. + * - Extcodecopy copies a deterministic value depending on the address. + * - And many other things + * + * The main focus is that the generated execution trace is the same for equivalent executions + * and likely to be different for non-equivalent executions. + */ +class EVMInstructionInterpreter +{ +public: + explicit EVMInstructionInterpreter(langutil::EVMVersion _evmVersion, InterpreterState& _state, bool _disableMemWriteTrace): + m_evmVersion(_evmVersion), + m_state(_state), + m_disableMemoryWriteInstructions(_disableMemWriteTrace) + {} + /// Evaluate instruction + u256 eval(evmasm::Instruction _instruction, std::vector const& _arguments); + /// Evaluate builtin function + u256 evalBuiltin( + BuiltinFunctionForEVM const& _fun, + std::vector const& _arguments, + std::vector const& _evaluatedArguments + ); + + /// @returns the blob versioned hash + util::h256 blobHash(u256 const& _index); + +private: + /// Checks if the memory access is valid and adjusts msize accordingly. + /// @returns true if memory access is valid, false otherwise + /// A valid memory access must satisfy all of the following pre-requisites: + /// - Sum of @param _offset and @param _size do not overflow modulo u256 + /// - Sum of @param _offset, @param _size, and 31 do not overflow modulo u256 (see note below) + /// - @param _size is lesser than or equal to @a s_maxRangeSize + /// - @param _offset is lesser than or equal to the difference of numeric_limits::max() + /// and @a s_maxRangeSize + /// Note: Memory expansion is carried out in multiples of 32 bytes. + bool accessMemory(u256 const& _offset, u256 const& _size = 32); + /// @returns the memory contents at the provided address. + /// Does not adjust msize, use @a accessMemory for that + bytes readMemory(u256 const& _offset, u256 const& _size = 32); + /// @returns the memory contents at the provided address. + /// Does not adjust msize, use @a accessMemory for that + u256 readMemoryWord(u256 const& _offset); + /// @returns writes a word to memory + /// Does not adjust msize, use @a accessMemory for that + void writeMemoryWord(u256 const& _offset, u256 const& _value); + + void logTrace( + evmasm::Instruction _instruction, + std::vector const& _arguments = {}, + bytes const& _data = {} + ); + /// Appends a log to the trace representing an instruction or similar operation by string, + /// with arguments and auxiliary data (if nonempty). Flag @param _writesToMemory indicates + /// whether the instruction writes to (true) or does not write to (false) memory. + void logTrace( + std::string const& _pseudoInstruction, + bool _writesToMemory, + std::vector const& _arguments = {}, + bytes const& _data = {} + ); + + /// @returns a pair of boolean and size_t whose first value is true if @param _pseudoInstruction + /// is a Yul instruction that the Yul optimizer's loadResolver step rewrites the input + /// memory pointer value to zero if that instruction's read length (contained within @param + // _arguments) is zero, and whose second value is the positional index of the input memory + // pointer argument. + /// If the Yul instruction is unaffected or affected but read length is non-zero, the first + /// value is false. + std::pair isInputMemoryPtrModified( + std::string const& _pseudoInstruction, + std::vector const& _arguments + ); + + /// @returns disable trace flag. + bool memWriteTracingDisabled() + { + return m_disableMemoryWriteInstructions; + } + + langutil::EVMVersion m_evmVersion; + InterpreterState& m_state; + /// Flag to disable trace of instructions that write to memory. + bool m_disableMemoryWriteInstructions; + +public: + /// Maximum length for range-based memory access operations. + static constexpr unsigned s_maxRangeSize = 0xffff; +}; + +} // solidity::yul::interpreter::tools diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/Interpreter.cpp new file mode 100644 index 000000000000..48fc4932a80c --- /dev/null +++ b/libyul/tools/interpreter/Interpreter.cpp @@ -0,0 +1,519 @@ +/* + 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 . +*/ +// SPDX-License-Identifier: GPL-3.0 +/** + * Yul interpreter. + */ + +#include + +#include + +#include +#include +#include +#include + +#include + +#include + +#include + +#include +#include + +using namespace solidity; +using namespace solidity::yul; +using namespace solidity::yul::tools::interpreter; + +using solidity::util::h256; + +void InterpreterState::dumpStorage(std::ostream& _out) const +{ + for (auto const& [slot, value]: storage) + if (value != h256{}) + _out << " " << slot.hex() << ": " << value.hex() << std::endl; +} + +void InterpreterState::dumpTransientStorage(std::ostream& _out) const +{ + for (auto const& [slot, value]: transientStorage) + if (value != h256{}) + _out << " " << slot.hex() << ": " << value.hex() << std::endl; +} + +void InterpreterState::dumpTraceAndState(std::ostream& _out, bool _disableMemoryTrace) const +{ + _out << "Trace:" << std::endl; + for (auto const& line: trace) + _out << " " << line << std::endl; + if (!_disableMemoryTrace) + { + _out << "Memory dump:\n"; + std::map words; + for (auto const& [offset, value]: memory) + words[(offset / 0x20) * 0x20] |= u256(uint32_t(value)) << (256 - 8 - 8 * static_cast(offset % 0x20)); + for (auto const& [offset, value]: words) + if (value != 0) + _out << " " << std::uppercase << std::hex << std::setw(4) << offset << ": " << h256(value).hex() << std::endl; + } + _out << "Storage dump:" << std::endl; + dumpStorage(_out); + + _out << "Transient storage dump:" << std::endl; + dumpTransientStorage(_out); + + if (!calldata.empty()) + { + _out << "Calldata dump:"; + + for (size_t offset = 0; offset < calldata.size(); ++offset) + if (calldata[offset] != 0) + { + if (offset % 32 == 0) + _out << + std::endl << + " " << + std::uppercase << + std::hex << + std::setfill(' ') << + std::setw(4) << + offset << + ": "; + + _out << + std::hex << + std::setw(2) << + std::setfill('0') << + static_cast(calldata[offset]); + } + + _out << std::endl; + } +} + +void Interpreter::run( + InterpreterState& _state, + Dialect const& _dialect, + Block const& _ast, + bool _disableExternalCalls, + bool _disableMemoryTrace +) +{ + Scope scope; + Interpreter{_state, _dialect, scope, _disableExternalCalls, _disableMemoryTrace, 0}(_ast); +} + +void Interpreter::operator()(ExpressionStatement const& _expressionStatement) +{ + evaluateMulti(_expressionStatement.expression); +} + +void Interpreter::operator()(Assignment const& _assignment) +{ + solAssert(_assignment.value, ""); + std::vector values = evaluateMulti(*_assignment.value); + solAssert(values.size() == _assignment.variableNames.size(), ""); + for (size_t i = 0; i < values.size(); ++i) + { + YulName varName = _assignment.variableNames.at(i).name; + solAssert(m_variables.count(varName), ""); + m_variables[varName] = values.at(i); + } +} + +void Interpreter::operator()(VariableDeclaration const& _declaration) +{ + std::vector values(_declaration.variables.size(), 0); + if (_declaration.value) + values = evaluateMulti(*_declaration.value); + + solAssert(values.size() == _declaration.variables.size(), ""); + for (size_t i = 0; i < values.size(); ++i) + { + YulName varName = _declaration.variables.at(i).name; + solAssert(!m_variables.count(varName), ""); + m_variables[varName] = values.at(i); + m_scope->names.emplace(varName, nullptr); + } +} + +void Interpreter::operator()(If const& _if) +{ + solAssert(_if.condition, ""); + if (evaluate(*_if.condition) != 0) + (*this)(_if.body); +} + +void Interpreter::operator()(Switch const& _switch) +{ + solAssert(_switch.expression, ""); + u256 val = evaluate(*_switch.expression); + solAssert(!_switch.cases.empty(), ""); + for (auto const& c: _switch.cases) + // Default case has to be last. + if (!c.value || evaluate(*c.value) == val) + { + (*this)(c.body); + break; + } +} + +void Interpreter::operator()(FunctionDefinition const&) +{ +} + +void Interpreter::operator()(ForLoop const& _forLoop) +{ + solAssert(_forLoop.condition, ""); + + enterScope(_forLoop.pre); + ScopeGuard g([this]{ leaveScope(); }); + + for (auto const& statement: _forLoop.pre.statements) + { + visit(statement); + if (m_state.controlFlowState == ControlFlowState::Leave) + return; + } + while (evaluate(*_forLoop.condition) != 0) + { + // Increment step for each loop iteration for loops with + // an empty body and post blocks to prevent a deadlock. + if (_forLoop.body.statements.size() == 0 && _forLoop.post.statements.size() == 0) + incrementStep(); + + m_state.controlFlowState = ControlFlowState::Default; + (*this)(_forLoop.body); + if (m_state.controlFlowState == ControlFlowState::Break || m_state.controlFlowState == ControlFlowState::Leave) + break; + + m_state.controlFlowState = ControlFlowState::Default; + (*this)(_forLoop.post); + if (m_state.controlFlowState == ControlFlowState::Leave) + break; + } + if (m_state.controlFlowState != ControlFlowState::Leave) + m_state.controlFlowState = ControlFlowState::Default; +} + +void Interpreter::operator()(Break const&) +{ + m_state.controlFlowState = ControlFlowState::Break; +} + +void Interpreter::operator()(Continue const&) +{ + m_state.controlFlowState = ControlFlowState::Continue; +} + +void Interpreter::operator()(Leave const&) +{ + m_state.controlFlowState = ControlFlowState::Leave; +} + +void Interpreter::operator()(Block const& _block) +{ + enterScope(_block); + // Register functions. + for (auto const& statement: _block.statements) + if (std::holds_alternative(statement)) + { + FunctionDefinition const& funDef = std::get(statement); + m_scope->names.emplace(funDef.name, &funDef); + } + + for (auto const& statement: _block.statements) + { + incrementStep(); + visit(statement); + if (m_state.controlFlowState != ControlFlowState::Default) + break; + } + + leaveScope(); +} + +u256 Interpreter::evaluate(Expression const& _expression) +{ + ExpressionEvaluator ev(m_state, m_dialect, *m_scope, m_variables, m_disableExternalCalls, m_disableMemoryTrace, m_recursionDepth); + ev.visit(_expression); + return ev.value(); +} + +std::vector Interpreter::evaluateMulti(Expression const& _expression) +{ + ExpressionEvaluator ev(m_state, m_dialect, *m_scope, m_variables, m_disableExternalCalls, m_disableMemoryTrace, m_recursionDepth); + ev.visit(_expression); + return ev.values(); +} + +void Interpreter::enterScope(Block const& _block) +{ + if (!m_scope->subScopes.count(&_block)) + m_scope->subScopes[&_block] = std::make_unique(Scope{ + {}, + {}, + m_scope + }); + m_scope = m_scope->subScopes[&_block].get(); +} + +void Interpreter::leaveScope() +{ + for (auto const& [var, funDeclaration]: m_scope->names) + if (!funDeclaration) + m_variables.erase(var); + m_scope = m_scope->parent; + yulAssert(m_scope, ""); +} + +void Interpreter::incrementStep() +{ + // recursion depth is checked here since `incrementStep` got called + // when an actual statement is executed + checkRecursionDepth(); + + m_state.numSteps++; + if (m_state.maxSteps > 0 && m_state.numSteps >= m_state.maxSteps) + { + m_state.trace.emplace_back("Interpreter execution step limit reached."); + BOOST_THROW_EXCEPTION(StepLimitReached()); + } +} + +void Interpreter::checkRecursionDepth() +{ + if (m_state.maxRecursionDepth > 0 && m_recursionDepth > m_state.maxRecursionDepth) + { + m_state.trace.emplace_back("Interpreter recursion depth exceeded"); + BOOST_THROW_EXCEPTION(RecursionDepthExceeded()); + } +} + +void ExpressionEvaluator::operator()(Literal const& _literal) +{ + incrementStep(); + setValue(_literal.value.value()); +} + +void ExpressionEvaluator::operator()(Identifier const& _identifier) +{ + solAssert(m_variables.count(_identifier.name), ""); + incrementStep(); + setValue(m_variables.at(_identifier.name)); +} + +void ExpressionEvaluator::operator()(FunctionCall const& _funCall) +{ + std::vector> const* literalArguments = nullptr; + if (BuiltinFunction const* builtin = m_dialect.builtin(_funCall.functionName.name)) + if (!builtin->literalArguments.empty()) + literalArguments = &builtin->literalArguments; + evaluateArgs(_funCall.arguments, literalArguments); + + if (EVMDialect const* dialect = dynamic_cast(&m_dialect)) + { + if (BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name)) + { + EVMInstructionInterpreter interpreter(dialect->evmVersion(), m_state, m_disableMemoryTrace); + + u256 const value = interpreter.evalBuiltin(*fun, _funCall.arguments, values()); + + if ( + !m_disableExternalCalls && + fun->instruction && + evmasm::isCallInstruction(*fun->instruction) + ) + runExternalCall(*fun->instruction); + + setValue(value); + return; + } + } + + Scope* scope = &m_scope; + for (; scope; scope = scope->parent) + if (scope->names.count(_funCall.functionName.name)) + break; + yulAssert(scope, ""); + + FunctionDefinition const* fun = scope->names.at(_funCall.functionName.name); + yulAssert(fun, "Function not found."); + yulAssert(m_values.size() == fun->parameters.size(), ""); + std::map variables; + for (size_t i = 0; i < fun->parameters.size(); ++i) + variables[fun->parameters.at(i).name] = m_values.at(i); + for (size_t i = 0; i < fun->returnVariables.size(); ++i) + variables[fun->returnVariables.at(i).name] = 0; + + m_state.controlFlowState = ControlFlowState::Default; + std::unique_ptr interpreter = makeInterpreterCopy(std::move(variables)); + (*interpreter)(fun->body); + m_state.controlFlowState = ControlFlowState::Default; + + m_values.clear(); + for (auto const& retVar: fun->returnVariables) + m_values.emplace_back(interpreter->valueOfVariable(retVar.name)); +} + +u256 ExpressionEvaluator::value() const +{ + solAssert(m_values.size() == 1, ""); + return m_values.front(); +} + +void ExpressionEvaluator::setValue(u256 _value) +{ + m_values.clear(); + m_values.emplace_back(std::move(_value)); +} + +void ExpressionEvaluator::evaluateArgs( + std::vector const& _expr, + std::vector> const* _literalArguments +) +{ + incrementStep(); + std::vector values; + size_t i = 0; + /// Function arguments are evaluated in reverse. + for (auto const& expr: _expr | ranges::views::reverse) + { + if (!_literalArguments || !_literalArguments->at(_expr.size() - i - 1)) + visit(expr); + else + { + Literal const& lit = std::get(expr); + if (lit.value.unlimited()) + { + yulAssert(lit.kind == LiteralKind::String); + m_values = {getValueForUnlimitedLiteral(lit)}; + } + else + m_values = {lit.value.value()}; + } + + values.push_back(value()); + ++i; + } + m_values = std::move(values); + std::reverse(m_values.begin(), m_values.end()); +} + +u256 ExpressionEvaluator::getValueForUnlimitedLiteral(Literal const&) +{ + return 0xdeadbeef; +} + +void ExpressionEvaluator::incrementStep() +{ + m_nestingLevel++; + if (m_state.maxExprNesting > 0 && m_nestingLevel > m_state.maxExprNesting) + { + m_state.trace.emplace_back("Maximum expression nesting level reached."); + BOOST_THROW_EXCEPTION(ExpressionNestingLimitReached()); + } +} + +void ExpressionEvaluator::runExternalCall(evmasm::Instruction _instruction) +{ + u256 memOutOffset = 0; + u256 memOutSize = 0; + u256 callvalue = 0; + u256 memInOffset = 0; + u256 memInSize = 0; + + // Setup memOut* values + if ( + _instruction == evmasm::Instruction::CALL || + _instruction == evmasm::Instruction::CALLCODE + ) + { + memOutOffset = values()[5]; + memOutSize = values()[6]; + callvalue = values()[2]; + memInOffset = values()[3]; + memInSize = values()[4]; + } + else if ( + _instruction == evmasm::Instruction::DELEGATECALL || + _instruction == evmasm::Instruction::STATICCALL + ) + { + memOutOffset = values()[4]; + memOutSize = values()[5]; + memInOffset = values()[2]; + memInSize = values()[3]; + } + else + yulAssert(false); + + // Don't execute external call if it isn't our own address + if (values()[1] != util::h160::Arith(m_state.address)) + return; + + Scope tmpScope; + InterpreterState tmpState; + tmpState.calldata = m_state.readMemory(memInOffset, memInSize); + tmpState.callvalue = callvalue; + tmpState.numInstance = m_state.numInstance + 1; + + yulAssert(tmpState.numInstance < 1024, "Detected more than 1024 recursive calls, aborting..."); + + // Create new interpreter for the called contract + std::unique_ptr newInterpreter = makeInterpreterNew(tmpState, tmpScope); + + Scope* abstractRootScope = &m_scope; + Scope* fileScope = nullptr; + Block const* ast = nullptr; + + // Find file scope + while (abstractRootScope->parent) + { + fileScope = abstractRootScope; + abstractRootScope = abstractRootScope->parent; + } + + // Get AST for file scope + for (auto&& [block, scope]: abstractRootScope->subScopes) + if (scope.get() == fileScope) + { + ast = block; + break; + } + + yulAssert(ast); + + try + { + (*newInterpreter)(*ast); + } + catch (ExplicitlyTerminatedWithReturn const&) + { + // Copy return data to our memory + copyZeroExtended( + m_state.memory, + newInterpreter->returnData(), + memOutOffset.convert_to(), + 0, + memOutSize.convert_to() + ); + m_state.returndata = newInterpreter->returnData(); + } +} diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h new file mode 100644 index 000000000000..926bb8cbaf8d --- /dev/null +++ b/libyul/tools/interpreter/Interpreter.h @@ -0,0 +1,336 @@ +/* + 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 . +*/ +// SPDX-License-Identifier: GPL-3.0 +/** + * Yul interpreter. + */ + +#pragma once + +#include +#include + +#include + +#include +#include + +#include + +#include + +namespace solidity::yul +{ +struct Dialect; +} + +namespace solidity::yul::tools::interpreter +{ + +class InterpreterTerminatedGeneric: public util::Exception +{ +}; + +class ExplicitlyTerminated: public InterpreterTerminatedGeneric +{ +}; + +class ExplicitlyTerminatedWithReturn: public ExplicitlyTerminated +{ +}; + +class StepLimitReached: public InterpreterTerminatedGeneric +{ +}; + +class TraceLimitReached: public InterpreterTerminatedGeneric +{ +}; + +class ExpressionNestingLimitReached: public InterpreterTerminatedGeneric +{ +}; + +class UnsupportedBuiltinFunctionEvaluated : public InterpreterTerminatedGeneric +{ +}; + +class RecursionDepthExceeded : public InterpreterTerminatedGeneric +{ +}; + +enum class ControlFlowState +{ + Default, + Continue, + Break, + Leave +}; + +struct InterpreterState +{ + bytes calldata; + bytes returndata; + std::map memory; + /// This is different than memory.size() because we ignore gas. + u256 msize; + std::map storage; + std::map transientStorage; + util::h160 address = util::h160("0x0000000000000000000000000000000011111111"); + u256 balance = 0x22222222; + u256 selfbalance = 0x22223333; + util::h160 origin = util::h160("0x0000000000000000000000000000000033333333"); + util::h160 caller = util::h160("0x0000000000000000000000000000000044444444"); + u256 callvalue = 0x55555555; + /// Deployed code + bytes code = util::asBytes("codecodecodecodecode"); + u256 gasprice = 0x66666666; + util::h160 coinbase = util::h160("0x0000000000000000000000000000000077777777"); + u256 timestamp = 0x88888888; + u256 blockNumber = 1024; + u256 difficulty = 0x9999999; + u256 prevrandao = (u256(1) << 64) + 1; + u256 gaslimit = 4000000; + u256 chainid = 0x01; + /// The minimum value of basefee: 7 wei. + u256 basefee = 0x07; + /// The minimum value of blobbasefee: 1 wei. + u256 blobbasefee = 0x01; + /// Log of changes / effects. Sholud be structured data in the future. + std::vector trace; + /// This is actually an input parameter that more or less limits the runtime. + size_t maxTraceSize = 0; + size_t maxSteps = 0; + size_t numSteps = 0; + size_t maxExprNesting = 0; + size_t maxRecursionDepth = 0; + ControlFlowState controlFlowState = ControlFlowState::Default; + + /// Number of the current state instance, used for recursion protection + size_t numInstance = 0; + + // Blob commitment hash version + util::FixedHash<1> const blobHashVersion = util::FixedHash<1>(1); + // Blob commitments + std::array const blobCommitments = {0x01, 0x02}; + + /// Prints execution trace and non-zero storage to @param _out. + /// Flag @param _disableMemoryTrace, if set, does not produce a memory dump. This + /// avoids false positives reports by the fuzzer when certain optimizer steps are + /// activated e.g., Redundant store eliminator, Equal store eliminator. + void dumpTraceAndState(std::ostream& _out, bool _disableMemoryTrace) const; + /// Prints non-zero storage to @param _out. + void dumpStorage(std::ostream& _out) const; + /// Prints non-zero transient storage to @param _out. + void dumpTransientStorage(std::ostream& _out) const; + + bytes readMemory(u256 const& _offset, u256 const& _size) + { + yulAssert(_size <= 0xffff, "Too large read."); + bytes data(size_t(_size), uint8_t(0)); + for (size_t i = 0; i < data.size(); ++i) + data[i] = memory[_offset + i]; + return data; + } +}; + +/** + * Scope structure built and maintained during execution. + */ +struct Scope +{ + /// Used for variables and functions. Value is nullptr for variables. + std::map names; + std::map> subScopes; + Scope* parent = nullptr; +}; + +/** + * Yul interpreter. + */ +class Interpreter: public ASTWalker +{ +public: + /// Executes the Yul interpreter. Flag @param _disableMemoryTracing if set ensures that + /// instructions that write to memory do not affect @param _state. This + /// avoids false positives reports by the fuzzer when certain optimizer steps are + /// activated e.g., Redundant store eliminator, Equal store eliminator. + static void run( + InterpreterState& _state, + Dialect const& _dialect, + Block const& _ast, + bool _disableExternalCalls, + bool _disableMemoryTracing + ); + + Interpreter( + InterpreterState& _state, + Dialect const& _dialect, + Scope& _scope, + bool _disableExternalCalls, + bool _disableMemoryTracing, + size_t _callerRecursionDepth, + std::map _variables = {} + ): + m_dialect(_dialect), + m_state(_state), + m_variables(std::move(_variables)), + m_scope(&_scope), + m_disableExternalCalls(_disableExternalCalls), + m_disableMemoryTrace(_disableMemoryTracing), + // Increment here so that this is the only place need to do so + m_recursionDepth(_callerRecursionDepth + 1) + { + } + + void operator()(ExpressionStatement const& _statement) override; + void operator()(Assignment const& _assignment) override; + void operator()(VariableDeclaration const& _varDecl) override; + void operator()(If const& _if) override; + void operator()(Switch const& _switch) override; + void operator()(FunctionDefinition const&) override; + void operator()(ForLoop const&) override; + void operator()(Break const&) override; + void operator()(Continue const&) override; + void operator()(Leave const&) override; + void operator()(Block const& _block) override; + + bytes returnData() const { return m_state.returndata; } + std::vector const& trace() const { return m_state.trace; } + + u256 valueOfVariable(YulName _name) const { return m_variables.at(_name); } + +protected: + /// Asserts that the expression evaluates to exactly one value and returns it. + virtual u256 evaluate(Expression const& _expression); + /// Evaluates the expression and returns its value. + virtual std::vector evaluateMulti(Expression const& _expression); + + void enterScope(Block const& _block); + void leaveScope(); + + /// Increment interpreter step count, throwing exception if step limit + /// is reached. + void incrementStep(); + + void checkRecursionDepth(); + + Dialect const& m_dialect; + InterpreterState& m_state; + /// Values of variables. + std::map m_variables; + Scope* m_scope; + /// If not set, external calls (e.g. using `call()`) to the same contract + /// are evaluated in a new parser instance. + bool m_disableExternalCalls; + bool m_disableMemoryTrace; + + size_t const m_recursionDepth; +}; + +/** + * Yul expression evaluator. + */ +class ExpressionEvaluator: public ASTWalker +{ +public: + ExpressionEvaluator( + InterpreterState& _state, + Dialect const& _dialect, + Scope& _scope, + std::map const& _variables, + bool _disableExternalCalls, + bool _disableMemoryTrace, + size_t _recursionDepth + ): + m_state(_state), + m_dialect(_dialect), + m_variables(_variables), + m_scope(_scope), + m_disableExternalCalls(_disableExternalCalls), + m_disableMemoryTrace(_disableMemoryTrace), + m_recursionDepth(_recursionDepth) + {} + + void operator()(Literal const&) override; + void operator()(Identifier const&) override; + void operator()(FunctionCall const& _funCall) override; + + /// Asserts that the expression has exactly one value and returns it. + u256 value() const; + /// Returns the list of values of the expression. + std::vector values() const { return m_values; } + +protected: + void runExternalCall(evmasm::Instruction _instruction); + virtual std::unique_ptr makeInterpreterCopy(std::map _variables = {}) const + { + return std::make_unique( + m_state, + m_dialect, + m_scope, + m_disableExternalCalls, + m_disableMemoryTrace, + m_recursionDepth, + std::move(_variables) + ); + } + virtual std::unique_ptr makeInterpreterNew(InterpreterState& _state, Scope& _scope) const + { + return std::make_unique( + _state, + m_dialect, + _scope, + m_disableExternalCalls, + m_disableMemoryTrace, + m_recursionDepth + ); + } + + void setValue(u256 _value); + + /// Evaluates the given expression from right to left and + /// stores it in m_value. + void evaluateArgs( + std::vector const& _expr, + std::vector> const* _literalArguments + ); + + virtual u256 getValueForUnlimitedLiteral(Literal const& _literal); + + /// Increment evaluation count, throwing exception if the + /// nesting level is beyond the upper bound configured in + /// the interpreter state. + void incrementStep(); + + InterpreterState& m_state; + Dialect const& m_dialect; + /// Values of variables. + std::map const& m_variables; + Scope& m_scope; + /// Current value of the expression + std::vector m_values; + /// Current expression nesting level + unsigned m_nestingLevel = 0; + bool m_disableExternalCalls; + /// Flag to disable memory tracing + bool m_disableMemoryTrace; + + size_t const m_recursionDepth; +}; + +} diff --git a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json index 4ef3c6df1873..3c48fefa6133 100644 --- a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json @@ -280,7 +280,9 @@ sub_0: assembly { immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":120:122 41 */ dup1 + /* \"C\":96:122 int constant constVar = 41 */ 0x29 + /* \"C\":120:122 41 */ add swap1 dup2 @@ -626,7 +628,9 @@ sub_0: assembly { immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":120:122 41 */ dup1 + /* \"C\":96:122 int constant constVar = 41 */ 0x29 + /* \"C\":120:122 41 */ add swap1 dup2 diff --git a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json index 8f0d5b5b5d6d..9c10ed2972d9 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json @@ -661,7 +661,7 @@ object \"C_54\" { let _1 := loadimmutable(\"8\") /// @src 0:322:341 \"constVar + immutVar\" let sum := /** @src 0:79:510 \"contract C...\" */ 0 - sum := add(/** @src 0:127:129 \"41\" */ 0x29, /** @src 0:79:510 \"contract C...\" */ _1) + sum := add(/** @src 0:96:129 \"int public constant constVar = 41\" */ 41, /** @src 0:79:510 \"contract C...\" */ _1) if and(1, slt(sum, _1)) { mstore(0, shl(224, 0x4e487b71)) @@ -740,7 +740,7 @@ object \"C_54\" { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } let memPos_3 := mload(64) - mstore(memPos_3, /** @src 0:127:129 \"41\" */ 0x29) + mstore(memPos_3, /** @ast-id 5 @src 0:96:129 \"int public constant constVar = 41\" */ 41) /// @src 0:79:510 \"contract C...\" return(memPos_3, 32) } @@ -1504,7 +1504,7 @@ object \"D_72\" { let _1 := loadimmutable(\"8\") /// @src 0:322:341 \"constVar + immutVar\" let sum := /** @src 1:91:181 \"contract D is C(3)...\" */ 0 - sum := add(/** @src 0:127:129 \"41\" */ 0x29, /** @src 1:91:181 \"contract D is C(3)...\" */ _1) + sum := add(/** @src 0:96:129 \"int public constant constVar = 41\" */ 41, /** @src 1:91:181 \"contract D is C(3)...\" */ _1) if and(1, slt(sum, _1)) { mstore(0, shl(224, 0x4e487b71)) @@ -1583,7 +1583,7 @@ object \"D_72\" { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } let memPos_3 := mload(64) - mstore(memPos_3, /** @src 0:127:129 \"41\" */ 0x29) + mstore(memPos_3, /** @ast-id 5 @src 0:96:129 \"int public constant constVar = 41\" */ 41) /// @src 1:91:181 \"contract D is C(3)...\" return(memPos_3, 32) } diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp index 0f94f309dce4..3d0c3a7c240a 100644 --- a/test/libyul/YulOptimizerTestCommon.cpp +++ b/test/libyul/YulOptimizerTestCommon.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -158,6 +159,12 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( ConditionalSimplifier::run(*m_context, block); return block; }}, + {"constantFunctionEvaluator", [&]() { + auto block = disambiguate(); + updateContext(block); + ConstantFunctionEvaluator::run(*m_context, block); + return block; + }}, {"expressionSplitter", [&]() { auto block = std::get(ASTCopier{}(m_object->code()->root())); updateContext(block); diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/all_arithmetic.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/all_arithmetic.yul new file mode 100644 index 000000000000..4f0757d1b995 --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/all_arithmetic.yul @@ -0,0 +1,3571 @@ +/* +# Test for all arithmetic operations +# This python script is used to generate the test +from itertools import product +import random + +random.seed(20240823) + +src = [] +src.append('{') +src.append(""" + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } +""") + +MX = 2**256 +correct = lambda num: int(num) % MX +u2s = lambda num: int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test(fn_name, calc, param_cnt, nums = None): + if nums is None: + nums = [0, 1, 2, MX - 1, MX - 2, random.randrange(MX), random.randrange(MX)] + param_set = list(product(nums, repeat=param_cnt)) + for i, p in enumerate(param_set): + res = correct(calc(p)) + src.append(f' function test_{fn_name}_{i}() {{ check({fn_name}({', '.join(str(i) for i in p)}), {res}) }}') + src.append('') + +gen_test('add', lambda p: p[0] + p[1], 2) +gen_test('mul', lambda p: p[0] * p[1], 2) +gen_test('sub', lambda p: p[0] - p[1], 2) +gen_test('div', lambda p: p[0] // p[1] if p[1] != 0 else 0, 2) +def sdiv(p): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res +def smod(p): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res +gen_test('sdiv', sdiv, 2) +gen_test('mod', lambda p: p[0] % p[1] if p[1] != 0 else 0, 2) +gen_test('smod', smod, 2) +gen_test('exp', lambda p: pow(p[0], p[1], MX), 2) +gen_test('not', lambda p: ~p[0], 1) +gen_test('lt', lambda p: p[0] < p[1], 2) +gen_test('gt', lambda p: p[0] > p[1], 2) +gen_test('slt', lambda p: u2s(p[0]) < u2s(p[1]), 2) +gen_test('sgt', lambda p: u2s(p[0]) > u2s(p[1]), 2) +gen_test('eq', lambda p: p[0] == p[1], 2) +gen_test('iszero', lambda p: p[0] == 0, 1) +gen_test('and', lambda p: p[0] & p[1], 2) +gen_test('or', lambda p: p[0] | p[1], 2) +gen_test('xor', lambda p: p[0] ^ p[1], 2) +gen_test('byte', lambda p: 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xff, 2, + nums = [random.randrange(MX), random.randrange(MX), random.randrange(32), random.randrange(32), 0]) +gen_test('shl', lambda p: p[1] << p[0] if p[0] < 32 else 0, 2) +gen_test('shr', lambda p: p[1] >> p[0], 2) +def sar(p): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= correct(-high_bit) << max(0, 255 - sh) + return val +gen_test('sar', sar, 2) +gen_test('addmod', lambda p: (p[0] + p[1]) % p[2] if p[2] != 0 else 0, 3, + nums = [random.randrange(0, MX) for i in range(3)] + [0]) +gen_test('mulmod', lambda p: (p[0] * p[1]) % p[2] if p[2] != 0 else 0, 3, + nums = [random.randrange(0, MX) for i in range(3)] + [0]) +def signextend(p): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (correct(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) +gen_test('signextend', signextend, 2) + +src.append('}') +print('\n'.join(src)) +*/ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + function test_add_0() { check(add(0, 0), 0) } + function test_add_1() { check(add(0, 1), 1) } + function test_add_2() { check(add(0, 2), 2) } + function test_add_3() { check(add(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_add_4() { check(add(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_add_5() { check(add(0, 22511778810690419408606032611692914343393218118973564305246125296861161142670), 22511778810690419408606032611692914343393218118973564305246125296861161142670) } + function test_add_6() { check(add(0, 19659681746644293860765529169101785554351274765820567770131372417486817992443), 19659681746644293860765529169101785554351274765820567770131372417486817992443) } + function test_add_7() { check(add(1, 0), 1) } + function test_add_8() { check(add(1, 1), 2) } + function test_add_9() { check(add(1, 2), 3) } + function test_add_10() { check(add(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_add_11() { check(add(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_add_12() { check(add(1, 22511778810690419408606032611692914343393218118973564305246125296861161142670), 22511778810690419408606032611692914343393218118973564305246125296861161142671) } + function test_add_13() { check(add(1, 19659681746644293860765529169101785554351274765820567770131372417486817992443), 19659681746644293860765529169101785554351274765820567770131372417486817992444) } + function test_add_14() { check(add(2, 0), 2) } + function test_add_15() { check(add(2, 1), 3) } + function test_add_16() { check(add(2, 2), 4) } + function test_add_17() { check(add(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_add_18() { check(add(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_add_19() { check(add(2, 22511778810690419408606032611692914343393218118973564305246125296861161142670), 22511778810690419408606032611692914343393218118973564305246125296861161142672) } + function test_add_20() { check(add(2, 19659681746644293860765529169101785554351274765820567770131372417486817992443), 19659681746644293860765529169101785554351274765820567770131372417486817992445) } + function test_add_21() { check(add(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_add_22() { check(add(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 0) } + function test_add_23() { check(add(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 1) } + function test_add_24() { check(add(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_add_25() { check(add(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639933) } + function test_add_26() { check(add(115792089237316195423570985008687907853269984665640564039457584007913129639935, 22511778810690419408606032611692914343393218118973564305246125296861161142670), 22511778810690419408606032611692914343393218118973564305246125296861161142669) } + function test_add_27() { check(add(115792089237316195423570985008687907853269984665640564039457584007913129639935, 19659681746644293860765529169101785554351274765820567770131372417486817992443), 19659681746644293860765529169101785554351274765820567770131372417486817992442) } + function test_add_28() { check(add(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_add_29() { check(add(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_add_30() { check(add(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 0) } + function test_add_31() { check(add(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639933) } + function test_add_32() { check(add(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639932) } + function test_add_33() { check(add(115792089237316195423570985008687907853269984665640564039457584007913129639934, 22511778810690419408606032611692914343393218118973564305246125296861161142670), 22511778810690419408606032611692914343393218118973564305246125296861161142668) } + function test_add_34() { check(add(115792089237316195423570985008687907853269984665640564039457584007913129639934, 19659681746644293860765529169101785554351274765820567770131372417486817992443), 19659681746644293860765529169101785554351274765820567770131372417486817992441) } + function test_add_35() { check(add(22511778810690419408606032611692914343393218118973564305246125296861161142670, 0), 22511778810690419408606032611692914343393218118973564305246125296861161142670) } + function test_add_36() { check(add(22511778810690419408606032611692914343393218118973564305246125296861161142670, 1), 22511778810690419408606032611692914343393218118973564305246125296861161142671) } + function test_add_37() { check(add(22511778810690419408606032611692914343393218118973564305246125296861161142670, 2), 22511778810690419408606032611692914343393218118973564305246125296861161142672) } + function test_add_38() { check(add(22511778810690419408606032611692914343393218118973564305246125296861161142670, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 22511778810690419408606032611692914343393218118973564305246125296861161142669) } + function test_add_39() { check(add(22511778810690419408606032611692914343393218118973564305246125296861161142670, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 22511778810690419408606032611692914343393218118973564305246125296861161142668) } + function test_add_40() { check(add(22511778810690419408606032611692914343393218118973564305246125296861161142670, 22511778810690419408606032611692914343393218118973564305246125296861161142670), 45023557621380838817212065223385828686786436237947128610492250593722322285340) } + function test_add_41() { check(add(22511778810690419408606032611692914343393218118973564305246125296861161142670, 19659681746644293860765529169101785554351274765820567770131372417486817992443), 42171460557334713269371561780794699897744492884794132075377497714347979135113) } + function test_add_42() { check(add(19659681746644293860765529169101785554351274765820567770131372417486817992443, 0), 19659681746644293860765529169101785554351274765820567770131372417486817992443) } + function test_add_43() { check(add(19659681746644293860765529169101785554351274765820567770131372417486817992443, 1), 19659681746644293860765529169101785554351274765820567770131372417486817992444) } + function test_add_44() { check(add(19659681746644293860765529169101785554351274765820567770131372417486817992443, 2), 19659681746644293860765529169101785554351274765820567770131372417486817992445) } + function test_add_45() { check(add(19659681746644293860765529169101785554351274765820567770131372417486817992443, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 19659681746644293860765529169101785554351274765820567770131372417486817992442) } + function test_add_46() { check(add(19659681746644293860765529169101785554351274765820567770131372417486817992443, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 19659681746644293860765529169101785554351274765820567770131372417486817992441) } + function test_add_47() { check(add(19659681746644293860765529169101785554351274765820567770131372417486817992443, 22511778810690419408606032611692914343393218118973564305246125296861161142670), 42171460557334713269371561780794699897744492884794132075377497714347979135113) } + function test_add_48() { check(add(19659681746644293860765529169101785554351274765820567770131372417486817992443, 19659681746644293860765529169101785554351274765820567770131372417486817992443), 39319363493288587721531058338203571108702549531641135540262744834973635984886) } + + function test_mul_0() { check(mul(0, 0), 0) } + function test_mul_1() { check(mul(0, 1), 0) } + function test_mul_2() { check(mul(0, 2), 0) } + function test_mul_3() { check(mul(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_mul_4() { check(mul(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_mul_5() { check(mul(0, 35257115525027604086735389276321862914110639864116864652044197398675076932980), 0) } + function test_mul_6() { check(mul(0, 98159365508182072155166613423532953313337829988475134546938896051283252249466), 0) } + function test_mul_7() { check(mul(1, 0), 0) } + function test_mul_8() { check(mul(1, 1), 1) } + function test_mul_9() { check(mul(1, 2), 2) } + function test_mul_10() { check(mul(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_mul_11() { check(mul(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_mul_12() { check(mul(1, 35257115525027604086735389276321862914110639864116864652044197398675076932980), 35257115525027604086735389276321862914110639864116864652044197398675076932980) } + function test_mul_13() { check(mul(1, 98159365508182072155166613423532953313337829988475134546938896051283252249466), 98159365508182072155166613423532953313337829988475134546938896051283252249466) } + function test_mul_14() { check(mul(2, 0), 0) } + function test_mul_15() { check(mul(2, 1), 2) } + function test_mul_16() { check(mul(2, 2), 4) } + function test_mul_17() { check(mul(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_mul_18() { check(mul(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639932) } + function test_mul_19() { check(mul(2, 35257115525027604086735389276321862914110639864116864652044197398675076932980), 70514231050055208173470778552643725828221279728233729304088394797350153865960) } + function test_mul_20() { check(mul(2, 98159365508182072155166613423532953313337829988475134546938896051283252249466), 80526641779047948886762241838377998773405675311309705054420208094653374858996) } + function test_mul_21() { check(mul(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 0) } + function test_mul_22() { check(mul(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_mul_23() { check(mul(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_mul_24() { check(mul(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_mul_25() { check(mul(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 2) } + function test_mul_26() { check(mul(115792089237316195423570985008687907853269984665640564039457584007913129639935, 35257115525027604086735389276321862914110639864116864652044197398675076932980), 80534973712288591336835595732366044939159344801523699387413386609238052706956) } + function test_mul_27() { check(mul(115792089237316195423570985008687907853269984665640564039457584007913129639935, 98159365508182072155166613423532953313337829988475134546938896051283252249466), 17632723729134123268404371585154954539932154677165429492518687956629877390470) } + function test_mul_28() { check(mul(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 0) } + function test_mul_29() { check(mul(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_mul_30() { check(mul(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 115792089237316195423570985008687907853269984665640564039457584007913129639932) } + function test_mul_31() { check(mul(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 2) } + function test_mul_32() { check(mul(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 4) } + function test_mul_33() { check(mul(115792089237316195423570985008687907853269984665640564039457584007913129639934, 35257115525027604086735389276321862914110639864116864652044197398675076932980), 45277858187260987250100206456044182025048704937406834735369189210562975773976) } + function test_mul_34() { check(mul(115792089237316195423570985008687907853269984665640564039457584007913129639934, 98159365508182072155166613423532953313337829988475134546938896051283252249466), 35265447458268246536808743170309909079864309354330858985037375913259754780940) } + function test_mul_35() { check(mul(35257115525027604086735389276321862914110639864116864652044197398675076932980, 0), 0) } + function test_mul_36() { check(mul(35257115525027604086735389276321862914110639864116864652044197398675076932980, 1), 35257115525027604086735389276321862914110639864116864652044197398675076932980) } + function test_mul_37() { check(mul(35257115525027604086735389276321862914110639864116864652044197398675076932980, 2), 70514231050055208173470778552643725828221279728233729304088394797350153865960) } + function test_mul_38() { check(mul(35257115525027604086735389276321862914110639864116864652044197398675076932980, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 80534973712288591336835595732366044939159344801523699387413386609238052706956) } + function test_mul_39() { check(mul(35257115525027604086735389276321862914110639864116864652044197398675076932980, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 45277858187260987250100206456044182025048704937406834735369189210562975773976) } + function test_mul_40() { check(mul(35257115525027604086735389276321862914110639864116864652044197398675076932980, 35257115525027604086735389276321862914110639864116864652044197398675076932980), 35676829315104958643211867670100128384171487943973514140263456863530508139664) } + function test_mul_41() { check(mul(35257115525027604086735389276321862914110639864116864652044197398675076932980, 98159365508182072155166613423532953313337829988475134546938896051283252249466), 36970967535082721992617999990656359956226150486086557968648561290405091325256) } + function test_mul_42() { check(mul(98159365508182072155166613423532953313337829988475134546938896051283252249466, 0), 0) } + function test_mul_43() { check(mul(98159365508182072155166613423532953313337829988475134546938896051283252249466, 1), 98159365508182072155166613423532953313337829988475134546938896051283252249466) } + function test_mul_44() { check(mul(98159365508182072155166613423532953313337829988475134546938896051283252249466, 2), 80526641779047948886762241838377998773405675311309705054420208094653374858996) } + function test_mul_45() { check(mul(98159365508182072155166613423532953313337829988475134546938896051283252249466, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 17632723729134123268404371585154954539932154677165429492518687956629877390470) } + function test_mul_46() { check(mul(98159365508182072155166613423532953313337829988475134546938896051283252249466, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 35265447458268246536808743170309909079864309354330858985037375913259754780940) } + function test_mul_47() { check(mul(98159365508182072155166613423532953313337829988475134546938896051283252249466, 35257115525027604086735389276321862914110639864116864652044197398675076932980), 36970967535082721992617999990656359956226150486086557968648561290405091325256) } + function test_mul_48() { check(mul(98159365508182072155166613423532953313337829988475134546938896051283252249466, 98159365508182072155166613423532953313337829988475134546938896051283252249466), 42576009428253106427251274893516922021547438050651452850975486664461846451748) } + + function test_sub_0() { check(sub(0, 0), 0) } + function test_sub_1() { check(sub(0, 1), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sub_2() { check(sub(0, 2), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_sub_3() { check(sub(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_sub_4() { check(sub(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 2) } + function test_sub_5() { check(sub(0, 69328707950187794991596647482969103428575694778568034480143632648886297542324), 46463381287128400431974337525718804424694289887072529559313951359026832097612) } + function test_sub_6() { check(sub(0, 24370086849439931369765199691008845142760221911163929331132986329031492688662), 91422002387876264053805785317679062710509762754476634708324597678881636951274) } + function test_sub_7() { check(sub(1, 0), 1) } + function test_sub_8() { check(sub(1, 1), 0) } + function test_sub_9() { check(sub(1, 2), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sub_10() { check(sub(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 2) } + function test_sub_11() { check(sub(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 3) } + function test_sub_12() { check(sub(1, 69328707950187794991596647482969103428575694778568034480143632648886297542324), 46463381287128400431974337525718804424694289887072529559313951359026832097613) } + function test_sub_13() { check(sub(1, 24370086849439931369765199691008845142760221911163929331132986329031492688662), 91422002387876264053805785317679062710509762754476634708324597678881636951275) } + function test_sub_14() { check(sub(2, 0), 2) } + function test_sub_15() { check(sub(2, 1), 1) } + function test_sub_16() { check(sub(2, 2), 0) } + function test_sub_17() { check(sub(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 3) } + function test_sub_18() { check(sub(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 4) } + function test_sub_19() { check(sub(2, 69328707950187794991596647482969103428575694778568034480143632648886297542324), 46463381287128400431974337525718804424694289887072529559313951359026832097614) } + function test_sub_20() { check(sub(2, 24370086849439931369765199691008845142760221911163929331132986329031492688662), 91422002387876264053805785317679062710509762754476634708324597678881636951276) } + function test_sub_21() { check(sub(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sub_22() { check(sub(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_sub_23() { check(sub(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 115792089237316195423570985008687907853269984665640564039457584007913129639933) } + function test_sub_24() { check(sub(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_sub_25() { check(sub(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_sub_26() { check(sub(115792089237316195423570985008687907853269984665640564039457584007913129639935, 69328707950187794991596647482969103428575694778568034480143632648886297542324), 46463381287128400431974337525718804424694289887072529559313951359026832097611) } + function test_sub_27() { check(sub(115792089237316195423570985008687907853269984665640564039457584007913129639935, 24370086849439931369765199691008845142760221911163929331132986329031492688662), 91422002387876264053805785317679062710509762754476634708324597678881636951273) } + function test_sub_28() { check(sub(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_sub_29() { check(sub(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 115792089237316195423570985008687907853269984665640564039457584007913129639933) } + function test_sub_30() { check(sub(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 115792089237316195423570985008687907853269984665640564039457584007913129639932) } + function test_sub_31() { check(sub(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sub_32() { check(sub(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_sub_33() { check(sub(115792089237316195423570985008687907853269984665640564039457584007913129639934, 69328707950187794991596647482969103428575694778568034480143632648886297542324), 46463381287128400431974337525718804424694289887072529559313951359026832097610) } + function test_sub_34() { check(sub(115792089237316195423570985008687907853269984665640564039457584007913129639934, 24370086849439931369765199691008845142760221911163929331132986329031492688662), 91422002387876264053805785317679062710509762754476634708324597678881636951272) } + function test_sub_35() { check(sub(69328707950187794991596647482969103428575694778568034480143632648886297542324, 0), 69328707950187794991596647482969103428575694778568034480143632648886297542324) } + function test_sub_36() { check(sub(69328707950187794991596647482969103428575694778568034480143632648886297542324, 1), 69328707950187794991596647482969103428575694778568034480143632648886297542323) } + function test_sub_37() { check(sub(69328707950187794991596647482969103428575694778568034480143632648886297542324, 2), 69328707950187794991596647482969103428575694778568034480143632648886297542322) } + function test_sub_38() { check(sub(69328707950187794991596647482969103428575694778568034480143632648886297542324, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 69328707950187794991596647482969103428575694778568034480143632648886297542325) } + function test_sub_39() { check(sub(69328707950187794991596647482969103428575694778568034480143632648886297542324, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 69328707950187794991596647482969103428575694778568034480143632648886297542326) } + function test_sub_40() { check(sub(69328707950187794991596647482969103428575694778568034480143632648886297542324, 69328707950187794991596647482969103428575694778568034480143632648886297542324), 0) } + function test_sub_41() { check(sub(69328707950187794991596647482969103428575694778568034480143632648886297542324, 24370086849439931369765199691008845142760221911163929331132986329031492688662), 44958621100747863621831447791960258285815472867404105149010646319854804853662) } + function test_sub_42() { check(sub(24370086849439931369765199691008845142760221911163929331132986329031492688662, 0), 24370086849439931369765199691008845142760221911163929331132986329031492688662) } + function test_sub_43() { check(sub(24370086849439931369765199691008845142760221911163929331132986329031492688662, 1), 24370086849439931369765199691008845142760221911163929331132986329031492688661) } + function test_sub_44() { check(sub(24370086849439931369765199691008845142760221911163929331132986329031492688662, 2), 24370086849439931369765199691008845142760221911163929331132986329031492688660) } + function test_sub_45() { check(sub(24370086849439931369765199691008845142760221911163929331132986329031492688662, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 24370086849439931369765199691008845142760221911163929331132986329031492688663) } + function test_sub_46() { check(sub(24370086849439931369765199691008845142760221911163929331132986329031492688662, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 24370086849439931369765199691008845142760221911163929331132986329031492688664) } + function test_sub_47() { check(sub(24370086849439931369765199691008845142760221911163929331132986329031492688662, 69328707950187794991596647482969103428575694778568034480143632648886297542324), 70833468136568331801739537216727649567454511798236458890446937688058324786274) } + function test_sub_48() { check(sub(24370086849439931369765199691008845142760221911163929331132986329031492688662, 24370086849439931369765199691008845142760221911163929331132986329031492688662), 0) } + + function test_div_0() { check(div(0, 0), 0) } + function test_div_1() { check(div(0, 1), 0) } + function test_div_2() { check(div(0, 2), 0) } + function test_div_3() { check(div(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_div_4() { check(div(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_div_5() { check(div(0, 21527130834558241424046083922382403006195840439861643608969621269005030453628), 0) } + function test_div_6() { check(div(0, 5908159024281513356662484898389320596115702548129829256513866158551418012202), 0) } + function test_div_7() { check(div(1, 0), 0) } + function test_div_8() { check(div(1, 1), 1) } + function test_div_9() { check(div(1, 2), 0) } + function test_div_10() { check(div(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_div_11() { check(div(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_div_12() { check(div(1, 21527130834558241424046083922382403006195840439861643608969621269005030453628), 0) } + function test_div_13() { check(div(1, 5908159024281513356662484898389320596115702548129829256513866158551418012202), 0) } + function test_div_14() { check(div(2, 0), 0) } + function test_div_15() { check(div(2, 1), 2) } + function test_div_16() { check(div(2, 2), 1) } + function test_div_17() { check(div(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_div_18() { check(div(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_div_19() { check(div(2, 21527130834558241424046083922382403006195840439861643608969621269005030453628), 0) } + function test_div_20() { check(div(2, 5908159024281513356662484898389320596115702548129829256513866158551418012202), 0) } + function test_div_21() { check(div(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 0) } + function test_div_22() { check(div(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_div_23() { check(div(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 57896044618658097711785492504343953926634992332820282019728792003956564819967) } + function test_div_24() { check(div(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_div_25() { check(div(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_div_26() { check(div(115792089237316195423570985008687907853269984665640564039457584007913129639935, 21527130834558241424046083922382403006195840439861643608969621269005030453628), 5) } + function test_div_27() { check(div(115792089237316195423570985008687907853269984665640564039457584007913129639935, 5908159024281513356662484898389320596115702548129829256513866158551418012202), 19) } + function test_div_28() { check(div(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 0) } + function test_div_29() { check(div(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_div_30() { check(div(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 57896044618658097711785492504343953926634992332820282019728792003956564819967) } + function test_div_31() { check(div(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_div_32() { check(div(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_div_33() { check(div(115792089237316195423570985008687907853269984665640564039457584007913129639934, 21527130834558241424046083922382403006195840439861643608969621269005030453628), 5) } + function test_div_34() { check(div(115792089237316195423570985008687907853269984665640564039457584007913129639934, 5908159024281513356662484898389320596115702548129829256513866158551418012202), 19) } + function test_div_35() { check(div(21527130834558241424046083922382403006195840439861643608969621269005030453628, 0), 0) } + function test_div_36() { check(div(21527130834558241424046083922382403006195840439861643608969621269005030453628, 1), 21527130834558241424046083922382403006195840439861643608969621269005030453628) } + function test_div_37() { check(div(21527130834558241424046083922382403006195840439861643608969621269005030453628, 2), 10763565417279120712023041961191201503097920219930821804484810634502515226814) } + function test_div_38() { check(div(21527130834558241424046083922382403006195840439861643608969621269005030453628, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_div_39() { check(div(21527130834558241424046083922382403006195840439861643608969621269005030453628, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_div_40() { check(div(21527130834558241424046083922382403006195840439861643608969621269005030453628, 21527130834558241424046083922382403006195840439861643608969621269005030453628), 1) } + function test_div_41() { check(div(21527130834558241424046083922382403006195840439861643608969621269005030453628, 5908159024281513356662484898389320596115702548129829256513866158551418012202), 3) } + function test_div_42() { check(div(5908159024281513356662484898389320596115702548129829256513866158551418012202, 0), 0) } + function test_div_43() { check(div(5908159024281513356662484898389320596115702548129829256513866158551418012202, 1), 5908159024281513356662484898389320596115702548129829256513866158551418012202) } + function test_div_44() { check(div(5908159024281513356662484898389320596115702548129829256513866158551418012202, 2), 2954079512140756678331242449194660298057851274064914628256933079275709006101) } + function test_div_45() { check(div(5908159024281513356662484898389320596115702548129829256513866158551418012202, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_div_46() { check(div(5908159024281513356662484898389320596115702548129829256513866158551418012202, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_div_47() { check(div(5908159024281513356662484898389320596115702548129829256513866158551418012202, 21527130834558241424046083922382403006195840439861643608969621269005030453628), 0) } + function test_div_48() { check(div(5908159024281513356662484898389320596115702548129829256513866158551418012202, 5908159024281513356662484898389320596115702548129829256513866158551418012202), 1) } + + function test_sdiv_0() { check(sdiv(0, 0), 0) } + function test_sdiv_1() { check(sdiv(0, 1), 0) } + function test_sdiv_2() { check(sdiv(0, 2), 0) } + function test_sdiv_3() { check(sdiv(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_sdiv_4() { check(sdiv(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_sdiv_5() { check(sdiv(0, 69742936075047218892091269223170546483868182867646801161738300130733179999778), 0) } + function test_sdiv_6() { check(sdiv(0, 41067838941032209417710089540241488427289292959688760797683786248366907217449), 0) } + function test_sdiv_7() { check(sdiv(1, 0), 0) } + function test_sdiv_8() { check(sdiv(1, 1), 1) } + function test_sdiv_9() { check(sdiv(1, 2), 0) } + function test_sdiv_10() { check(sdiv(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sdiv_11() { check(sdiv(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_sdiv_12() { check(sdiv(1, 69742936075047218892091269223170546483868182867646801161738300130733179999778), 0) } + function test_sdiv_13() { check(sdiv(1, 41067838941032209417710089540241488427289292959688760797683786248366907217449), 0) } + function test_sdiv_14() { check(sdiv(2, 0), 0) } + function test_sdiv_15() { check(sdiv(2, 1), 2) } + function test_sdiv_16() { check(sdiv(2, 2), 1) } + function test_sdiv_17() { check(sdiv(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_sdiv_18() { check(sdiv(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sdiv_19() { check(sdiv(2, 69742936075047218892091269223170546483868182867646801161738300130733179999778), 0) } + function test_sdiv_20() { check(sdiv(2, 41067838941032209417710089540241488427289292959688760797683786248366907217449), 0) } + function test_sdiv_21() { check(sdiv(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 0) } + function test_sdiv_22() { check(sdiv(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sdiv_23() { check(sdiv(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 0) } + function test_sdiv_24() { check(sdiv(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_sdiv_25() { check(sdiv(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_sdiv_26() { check(sdiv(115792089237316195423570985008687907853269984665640564039457584007913129639935, 69742936075047218892091269223170546483868182867646801161738300130733179999778), 0) } + function test_sdiv_27() { check(sdiv(115792089237316195423570985008687907853269984665640564039457584007913129639935, 41067838941032209417710089540241488427289292959688760797683786248366907217449), 0) } + function test_sdiv_28() { check(sdiv(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 0) } + function test_sdiv_29() { check(sdiv(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_sdiv_30() { check(sdiv(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sdiv_31() { check(sdiv(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 2) } + function test_sdiv_32() { check(sdiv(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_sdiv_33() { check(sdiv(115792089237316195423570985008687907853269984665640564039457584007913129639934, 69742936075047218892091269223170546483868182867646801161738300130733179999778), 0) } + function test_sdiv_34() { check(sdiv(115792089237316195423570985008687907853269984665640564039457584007913129639934, 41067838941032209417710089540241488427289292959688760797683786248366907217449), 0) } + function test_sdiv_35() { check(sdiv(69742936075047218892091269223170546483868182867646801161738300130733179999778, 0), 0) } + function test_sdiv_36() { check(sdiv(69742936075047218892091269223170546483868182867646801161738300130733179999778, 1), 69742936075047218892091269223170546483868182867646801161738300130733179999778) } + function test_sdiv_37() { check(sdiv(69742936075047218892091269223170546483868182867646801161738300130733179999778, 2), 92767512656181707157831127115929227168569083766643682600597942069323154819857) } + function test_sdiv_38() { check(sdiv(69742936075047218892091269223170546483868182867646801161738300130733179999778, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 46049153162268976531479715785517361369401801797993762877719283877179949640158) } + function test_sdiv_39() { check(sdiv(69742936075047218892091269223170546483868182867646801161738300130733179999778, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 23024576581134488265739857892758680684700900898996881438859641938589974820079) } + function test_sdiv_40() { check(sdiv(69742936075047218892091269223170546483868182867646801161738300130733179999778, 69742936075047218892091269223170546483868182867646801161738300130733179999778), 1) } + function test_sdiv_41() { check(sdiv(69742936075047218892091269223170546483868182867646801161738300130733179999778, 41067838941032209417710089540241488427289292959688760797683786248366907217449), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sdiv_42() { check(sdiv(41067838941032209417710089540241488427289292959688760797683786248366907217449, 0), 0) } + function test_sdiv_43() { check(sdiv(41067838941032209417710089540241488427289292959688760797683786248366907217449, 1), 41067838941032209417710089540241488427289292959688760797683786248366907217449) } + function test_sdiv_44() { check(sdiv(41067838941032209417710089540241488427289292959688760797683786248366907217449, 2), 20533919470516104708855044770120744213644646479844380398841893124183453608724) } + function test_sdiv_45() { check(sdiv(41067838941032209417710089540241488427289292959688760797683786248366907217449, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 74724250296283986005860895468446419425980691705951803241773797759546222422487) } + function test_sdiv_46() { check(sdiv(41067838941032209417710089540241488427289292959688760797683786248366907217449, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 95258169766800090714715940238567163639625338185796183640615690883729676031212) } + function test_sdiv_47() { check(sdiv(41067838941032209417710089540241488427289292959688760797683786248366907217449, 69742936075047218892091269223170546483868182867646801161738300130733179999778), 0) } + function test_sdiv_48() { check(sdiv(41067838941032209417710089540241488427289292959688760797683786248366907217449, 41067838941032209417710089540241488427289292959688760797683786248366907217449), 1) } + + function test_mod_0() { check(mod(0, 0), 0) } + function test_mod_1() { check(mod(0, 1), 0) } + function test_mod_2() { check(mod(0, 2), 0) } + function test_mod_3() { check(mod(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_mod_4() { check(mod(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_mod_5() { check(mod(0, 36825269129346002702140440696966949448053643031398351299125125567470047536997), 0) } + function test_mod_6() { check(mod(0, 115339544251917008337689406227421125961210063695271575420353325410755443010793), 0) } + function test_mod_7() { check(mod(1, 0), 0) } + function test_mod_8() { check(mod(1, 1), 0) } + function test_mod_9() { check(mod(1, 2), 1) } + function test_mod_10() { check(mod(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_mod_11() { check(mod(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_mod_12() { check(mod(1, 36825269129346002702140440696966949448053643031398351299125125567470047536997), 1) } + function test_mod_13() { check(mod(1, 115339544251917008337689406227421125961210063695271575420353325410755443010793), 1) } + function test_mod_14() { check(mod(2, 0), 0) } + function test_mod_15() { check(mod(2, 1), 0) } + function test_mod_16() { check(mod(2, 2), 0) } + function test_mod_17() { check(mod(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 2) } + function test_mod_18() { check(mod(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 2) } + function test_mod_19() { check(mod(2, 36825269129346002702140440696966949448053643031398351299125125567470047536997), 2) } + function test_mod_20() { check(mod(2, 115339544251917008337689406227421125961210063695271575420353325410755443010793), 2) } + function test_mod_21() { check(mod(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 0) } + function test_mod_22() { check(mod(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 0) } + function test_mod_23() { check(mod(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 1) } + function test_mod_24() { check(mod(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_mod_25() { check(mod(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_mod_26() { check(mod(115792089237316195423570985008687907853269984665640564039457584007913129639935, 36825269129346002702140440696966949448053643031398351299125125567470047536997), 5316281849278187317149662917787059509109055571445510142082207305502987028944) } + function test_mod_27() { check(mod(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115339544251917008337689406227421125961210063695271575420353325410755443010793), 452544985399187085881578781266781892059920970368988619104258597157686629142) } + function test_mod_28() { check(mod(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 0) } + function test_mod_29() { check(mod(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 0) } + function test_mod_30() { check(mod(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 0) } + function test_mod_31() { check(mod(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_mod_32() { check(mod(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_mod_33() { check(mod(115792089237316195423570985008687907853269984665640564039457584007913129639934, 36825269129346002702140440696966949448053643031398351299125125567470047536997), 5316281849278187317149662917787059509109055571445510142082207305502987028943) } + function test_mod_34() { check(mod(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115339544251917008337689406227421125961210063695271575420353325410755443010793), 452544985399187085881578781266781892059920970368988619104258597157686629141) } + function test_mod_35() { check(mod(36825269129346002702140440696966949448053643031398351299125125567470047536997, 0), 0) } + function test_mod_36() { check(mod(36825269129346002702140440696966949448053643031398351299125125567470047536997, 1), 0) } + function test_mod_37() { check(mod(36825269129346002702140440696966949448053643031398351299125125567470047536997, 2), 1) } + function test_mod_38() { check(mod(36825269129346002702140440696966949448053643031398351299125125567470047536997, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 36825269129346002702140440696966949448053643031398351299125125567470047536997) } + function test_mod_39() { check(mod(36825269129346002702140440696966949448053643031398351299125125567470047536997, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 36825269129346002702140440696966949448053643031398351299125125567470047536997) } + function test_mod_40() { check(mod(36825269129346002702140440696966949448053643031398351299125125567470047536997, 36825269129346002702140440696966949448053643031398351299125125567470047536997), 0) } + function test_mod_41() { check(mod(36825269129346002702140440696966949448053643031398351299125125567470047536997, 115339544251917008337689406227421125961210063695271575420353325410755443010793), 36825269129346002702140440696966949448053643031398351299125125567470047536997) } + function test_mod_42() { check(mod(115339544251917008337689406227421125961210063695271575420353325410755443010793, 0), 0) } + function test_mod_43() { check(mod(115339544251917008337689406227421125961210063695271575420353325410755443010793, 1), 0) } + function test_mod_44() { check(mod(115339544251917008337689406227421125961210063695271575420353325410755443010793, 2), 1) } + function test_mod_45() { check(mod(115339544251917008337689406227421125961210063695271575420353325410755443010793, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115339544251917008337689406227421125961210063695271575420353325410755443010793) } + function test_mod_46() { check(mod(115339544251917008337689406227421125961210063695271575420353325410755443010793, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115339544251917008337689406227421125961210063695271575420353325410755443010793) } + function test_mod_47() { check(mod(115339544251917008337689406227421125961210063695271575420353325410755443010793, 36825269129346002702140440696966949448053643031398351299125125567470047536997), 4863736863879000231268084136520277617049134601076521522977948708345300399802) } + function test_mod_48() { check(mod(115339544251917008337689406227421125961210063695271575420353325410755443010793, 115339544251917008337689406227421125961210063695271575420353325410755443010793), 0) } + + function test_smod_0() { check(smod(0, 0), 0) } + function test_smod_1() { check(smod(0, 1), 0) } + function test_smod_2() { check(smod(0, 2), 0) } + function test_smod_3() { check(smod(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_smod_4() { check(smod(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_smod_5() { check(smod(0, 64228277382660959385678659397297888838796724718273788882560561403552036615880), 0) } + function test_smod_6() { check(smod(0, 11231023412369386481209658464817842415216735901307809866909217453912553412854), 0) } + function test_smod_7() { check(smod(1, 0), 0) } + function test_smod_8() { check(smod(1, 1), 0) } + function test_smod_9() { check(smod(1, 2), 1) } + function test_smod_10() { check(smod(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_smod_11() { check(smod(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_smod_12() { check(smod(1, 64228277382660959385678659397297888838796724718273788882560561403552036615880), 1) } + function test_smod_13() { check(smod(1, 11231023412369386481209658464817842415216735901307809866909217453912553412854), 1) } + function test_smod_14() { check(smod(2, 0), 0) } + function test_smod_15() { check(smod(2, 1), 0) } + function test_smod_16() { check(smod(2, 2), 0) } + function test_smod_17() { check(smod(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_smod_18() { check(smod(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_smod_19() { check(smod(2, 64228277382660959385678659397297888838796724718273788882560561403552036615880), 2) } + function test_smod_20() { check(smod(2, 11231023412369386481209658464817842415216735901307809866909217453912553412854), 2) } + function test_smod_21() { check(smod(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 0) } + function test_smod_22() { check(smod(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 0) } + function test_smod_23() { check(smod(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_smod_24() { check(smod(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_smod_25() { check(smod(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_smod_26() { check(smod(115792089237316195423570985008687907853269984665640564039457584007913129639935, 64228277382660959385678659397297888838796724718273788882560561403552036615880), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_smod_27() { check(smod(115792089237316195423570985008687907853269984665640564039457584007913129639935, 11231023412369386481209658464817842415216735901307809866909217453912553412854), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_smod_28() { check(smod(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 0) } + function test_smod_29() { check(smod(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 0) } + function test_smod_30() { check(smod(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 0) } + function test_smod_31() { check(smod(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_smod_32() { check(smod(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_smod_33() { check(smod(115792089237316195423570985008687907853269984665640564039457584007913129639934, 64228277382660959385678659397297888838796724718273788882560561403552036615880), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_smod_34() { check(smod(115792089237316195423570985008687907853269984665640564039457584007913129639934, 11231023412369386481209658464817842415216735901307809866909217453912553412854), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_smod_35() { check(smod(64228277382660959385678659397297888838796724718273788882560561403552036615880, 0), 0) } + function test_smod_36() { check(smod(64228277382660959385678659397297888838796724718273788882560561403552036615880, 1), 0) } + function test_smod_37() { check(smod(64228277382660959385678659397297888838796724718273788882560561403552036615880, 2), 0) } + function test_smod_38() { check(smod(64228277382660959385678659397297888838796724718273788882560561403552036615880, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_smod_39() { check(smod(64228277382660959385678659397297888838796724718273788882560561403552036615880, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_smod_40() { check(smod(64228277382660959385678659397297888838796724718273788882560561403552036615880, 64228277382660959385678659397297888838796724718273788882560561403552036615880), 0) } + function test_smod_41() { check(smod(64228277382660959385678659397297888838796724718273788882560561403552036615880, 11231023412369386481209658464817842415216735901307809866909217453912553412854), 109152371032138505310517293256569258499663668323505028350197431219202250267296) } + function test_smod_42() { check(smod(11231023412369386481209658464817842415216735901307809866909217453912553412854, 0), 0) } + function test_smod_43() { check(smod(11231023412369386481209658464817842415216735901307809866909217453912553412854, 1), 0) } + function test_smod_44() { check(smod(11231023412369386481209658464817842415216735901307809866909217453912553412854, 2), 0) } + function test_smod_45() { check(smod(11231023412369386481209658464817842415216735901307809866909217453912553412854, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_smod_46() { check(smod(11231023412369386481209658464817842415216735901307809866909217453912553412854, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_smod_47() { check(smod(11231023412369386481209658464817842415216735901307809866909217453912553412854, 64228277382660959385678659397297888838796724718273788882560561403552036615880), 11231023412369386481209658464817842415216735901307809866909217453912553412854) } + function test_smod_48() { check(smod(11231023412369386481209658464817842415216735901307809866909217453912553412854, 11231023412369386481209658464817842415216735901307809866909217453912553412854), 0) } + + function test_exp_0() { check(exp(0, 0), 1) } + function test_exp_1() { check(exp(0, 1), 0) } + function test_exp_2() { check(exp(0, 2), 0) } + function test_exp_3() { check(exp(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_exp_4() { check(exp(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_exp_5() { check(exp(0, 115606902495168972315160449655162341994866798924771584142720835885133537129445), 0) } + function test_exp_6() { check(exp(0, 19016261866151635774443021074930362432861748244973906639398305101420816084945), 0) } + function test_exp_7() { check(exp(1, 0), 1) } + function test_exp_8() { check(exp(1, 1), 1) } + function test_exp_9() { check(exp(1, 2), 1) } + function test_exp_10() { check(exp(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_exp_11() { check(exp(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_exp_12() { check(exp(1, 115606902495168972315160449655162341994866798924771584142720835885133537129445), 1) } + function test_exp_13() { check(exp(1, 19016261866151635774443021074930362432861748244973906639398305101420816084945), 1) } + function test_exp_14() { check(exp(2, 0), 1) } + function test_exp_15() { check(exp(2, 1), 2) } + function test_exp_16() { check(exp(2, 2), 4) } + function test_exp_17() { check(exp(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_exp_18() { check(exp(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_exp_19() { check(exp(2, 115606902495168972315160449655162341994866798924771584142720835885133537129445), 0) } + function test_exp_20() { check(exp(2, 19016261866151635774443021074930362432861748244973906639398305101420816084945), 0) } + function test_exp_21() { check(exp(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 1) } + function test_exp_22() { check(exp(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_exp_23() { check(exp(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 1) } + function test_exp_24() { check(exp(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_exp_25() { check(exp(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_exp_26() { check(exp(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115606902495168972315160449655162341994866798924771584142720835885133537129445), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_exp_27() { check(exp(115792089237316195423570985008687907853269984665640564039457584007913129639935, 19016261866151635774443021074930362432861748244973906639398305101420816084945), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_exp_28() { check(exp(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 1) } + function test_exp_29() { check(exp(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_exp_30() { check(exp(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 4) } + function test_exp_31() { check(exp(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_exp_32() { check(exp(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_exp_33() { check(exp(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115606902495168972315160449655162341994866798924771584142720835885133537129445), 0) } + function test_exp_34() { check(exp(115792089237316195423570985008687907853269984665640564039457584007913129639934, 19016261866151635774443021074930362432861748244973906639398305101420816084945), 0) } + function test_exp_35() { check(exp(115606902495168972315160449655162341994866798924771584142720835885133537129445, 0), 1) } + function test_exp_36() { check(exp(115606902495168972315160449655162341994866798924771584142720835885133537129445, 1), 115606902495168972315160449655162341994866798924771584142720835885133537129445) } + function test_exp_37() { check(exp(115606902495168972315160449655162341994866798924771584142720835885133537129445, 2), 23719124936793778787876450117902569082795971420513865216479393835795806554841) } + function test_exp_38() { check(exp(115606902495168972315160449655162341994866798924771584142720835885133537129445, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 40077435397855390836825829047757859765238414361240355516876051624770643710445) } + function test_exp_39() { check(exp(115606902495168972315160449655162341994866798924771584142720835885133537129445, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 108018297088060445130926345359121830451934077009303250000327948703101226046825) } + function test_exp_40() { check(exp(115606902495168972315160449655162341994866798924771584142720835885133537129445, 115606902495168972315160449655162341994866798924771584142720835885133537129445), 97150176448040565727269074697933552528659003146295560980491637979805214122005) } + function test_exp_41() { check(exp(115606902495168972315160449655162341994866798924771584142720835885133537129445, 19016261866151635774443021074930362432861748244973906639398305101420816084945), 63358729398289627527967434598672713318067733667214043023762601771700435621285) } + function test_exp_42() { check(exp(19016261866151635774443021074930362432861748244973906639398305101420816084945, 0), 1) } + function test_exp_43() { check(exp(19016261866151635774443021074930362432861748244973906639398305101420816084945, 1), 19016261866151635774443021074930362432861748244973906639398305101420816084945) } + function test_exp_44() { check(exp(19016261866151635774443021074930362432861748244973906639398305101420816084945, 2), 74629681937752970613802439118038709119917259182873429909121362607996709464225) } + function test_exp_45() { check(exp(19016261866151635774443021074930362432861748244973906639398305101420816084945, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 30875495003004957983394972392970070081260406891337042524514781601031749044529) } + function test_exp_46() { check(exp(19016261866151635774443021074930362432861748244973906639398305101420816084945, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 7245849415207858963256606107610157872497234520555544843931569622001395596129) } + function test_exp_47() { check(exp(19016261866151635774443021074930362432861748244973906639398305101420816084945, 115606902495168972315160449655162341994866798924771584142720835885133537129445), 68328571329938115399471929321299300586050922973827035291387941781230319771409) } + function test_exp_48() { check(exp(19016261866151635774443021074930362432861748244973906639398305101420816084945, 19016261866151635774443021074930362432861748244973906639398305101420816084945), 89263219627053286008899524636370743314879091745423913331931537459307182940369) } + + function test_not_0() { check(not(0), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_not_1() { check(not(1), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_not_2() { check(not(2), 115792089237316195423570985008687907853269984665640564039457584007913129639933) } + function test_not_3() { check(not(115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_not_4() { check(not(115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_not_5() { check(not(5922964590783609873462582049084778189530164370652172856804360227125864711206), 109869124646532585550108402959603129663739820294988391182653223780787264928729) } + function test_not_6() { check(not(37453707075031683597309133012068767151672171590489110276720091032418434326653), 78338382162284511826261851996619140701597813075151453762737492975494695313282) } + + function test_lt_0() { check(lt(0, 0), 0) } + function test_lt_1() { check(lt(0, 1), 1) } + function test_lt_2() { check(lt(0, 2), 1) } + function test_lt_3() { check(lt(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_lt_4() { check(lt(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_lt_5() { check(lt(0, 110099802025650408331279406388138829088765583113642367910599120993463250367070), 1) } + function test_lt_6() { check(lt(0, 6989250744444949917814004474653212484134937610735153631554990646243336399660), 1) } + function test_lt_7() { check(lt(1, 0), 0) } + function test_lt_8() { check(lt(1, 1), 0) } + function test_lt_9() { check(lt(1, 2), 1) } + function test_lt_10() { check(lt(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_lt_11() { check(lt(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_lt_12() { check(lt(1, 110099802025650408331279406388138829088765583113642367910599120993463250367070), 1) } + function test_lt_13() { check(lt(1, 6989250744444949917814004474653212484134937610735153631554990646243336399660), 1) } + function test_lt_14() { check(lt(2, 0), 0) } + function test_lt_15() { check(lt(2, 1), 0) } + function test_lt_16() { check(lt(2, 2), 0) } + function test_lt_17() { check(lt(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_lt_18() { check(lt(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_lt_19() { check(lt(2, 110099802025650408331279406388138829088765583113642367910599120993463250367070), 1) } + function test_lt_20() { check(lt(2, 6989250744444949917814004474653212484134937610735153631554990646243336399660), 1) } + function test_lt_21() { check(lt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 0) } + function test_lt_22() { check(lt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 0) } + function test_lt_23() { check(lt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 0) } + function test_lt_24() { check(lt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_lt_25() { check(lt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_lt_26() { check(lt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 110099802025650408331279406388138829088765583113642367910599120993463250367070), 0) } + function test_lt_27() { check(lt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 6989250744444949917814004474653212484134937610735153631554990646243336399660), 0) } + function test_lt_28() { check(lt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 0) } + function test_lt_29() { check(lt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 0) } + function test_lt_30() { check(lt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 0) } + function test_lt_31() { check(lt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_lt_32() { check(lt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_lt_33() { check(lt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 110099802025650408331279406388138829088765583113642367910599120993463250367070), 0) } + function test_lt_34() { check(lt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 6989250744444949917814004474653212484134937610735153631554990646243336399660), 0) } + function test_lt_35() { check(lt(110099802025650408331279406388138829088765583113642367910599120993463250367070, 0), 0) } + function test_lt_36() { check(lt(110099802025650408331279406388138829088765583113642367910599120993463250367070, 1), 0) } + function test_lt_37() { check(lt(110099802025650408331279406388138829088765583113642367910599120993463250367070, 2), 0) } + function test_lt_38() { check(lt(110099802025650408331279406388138829088765583113642367910599120993463250367070, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_lt_39() { check(lt(110099802025650408331279406388138829088765583113642367910599120993463250367070, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_lt_40() { check(lt(110099802025650408331279406388138829088765583113642367910599120993463250367070, 110099802025650408331279406388138829088765583113642367910599120993463250367070), 0) } + function test_lt_41() { check(lt(110099802025650408331279406388138829088765583113642367910599120993463250367070, 6989250744444949917814004474653212484134937610735153631554990646243336399660), 0) } + function test_lt_42() { check(lt(6989250744444949917814004474653212484134937610735153631554990646243336399660, 0), 0) } + function test_lt_43() { check(lt(6989250744444949917814004474653212484134937610735153631554990646243336399660, 1), 0) } + function test_lt_44() { check(lt(6989250744444949917814004474653212484134937610735153631554990646243336399660, 2), 0) } + function test_lt_45() { check(lt(6989250744444949917814004474653212484134937610735153631554990646243336399660, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_lt_46() { check(lt(6989250744444949917814004474653212484134937610735153631554990646243336399660, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_lt_47() { check(lt(6989250744444949917814004474653212484134937610735153631554990646243336399660, 110099802025650408331279406388138829088765583113642367910599120993463250367070), 1) } + function test_lt_48() { check(lt(6989250744444949917814004474653212484134937610735153631554990646243336399660, 6989250744444949917814004474653212484134937610735153631554990646243336399660), 0) } + + function test_gt_0() { check(gt(0, 0), 0) } + function test_gt_1() { check(gt(0, 1), 0) } + function test_gt_2() { check(gt(0, 2), 0) } + function test_gt_3() { check(gt(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_gt_4() { check(gt(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_gt_5() { check(gt(0, 72753833581632480403581180800177515552830775683493556930395600007729054862025), 0) } + function test_gt_6() { check(gt(0, 35494539573573499949677027375126255854449863281693517184786462304148614611354), 0) } + function test_gt_7() { check(gt(1, 0), 1) } + function test_gt_8() { check(gt(1, 1), 0) } + function test_gt_9() { check(gt(1, 2), 0) } + function test_gt_10() { check(gt(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_gt_11() { check(gt(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_gt_12() { check(gt(1, 72753833581632480403581180800177515552830775683493556930395600007729054862025), 0) } + function test_gt_13() { check(gt(1, 35494539573573499949677027375126255854449863281693517184786462304148614611354), 0) } + function test_gt_14() { check(gt(2, 0), 1) } + function test_gt_15() { check(gt(2, 1), 1) } + function test_gt_16() { check(gt(2, 2), 0) } + function test_gt_17() { check(gt(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_gt_18() { check(gt(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_gt_19() { check(gt(2, 72753833581632480403581180800177515552830775683493556930395600007729054862025), 0) } + function test_gt_20() { check(gt(2, 35494539573573499949677027375126255854449863281693517184786462304148614611354), 0) } + function test_gt_21() { check(gt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 1) } + function test_gt_22() { check(gt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 1) } + function test_gt_23() { check(gt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 1) } + function test_gt_24() { check(gt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_gt_25() { check(gt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_gt_26() { check(gt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 72753833581632480403581180800177515552830775683493556930395600007729054862025), 1) } + function test_gt_27() { check(gt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 35494539573573499949677027375126255854449863281693517184786462304148614611354), 1) } + function test_gt_28() { check(gt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 1) } + function test_gt_29() { check(gt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 1) } + function test_gt_30() { check(gt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 1) } + function test_gt_31() { check(gt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_gt_32() { check(gt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_gt_33() { check(gt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 72753833581632480403581180800177515552830775683493556930395600007729054862025), 1) } + function test_gt_34() { check(gt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 35494539573573499949677027375126255854449863281693517184786462304148614611354), 1) } + function test_gt_35() { check(gt(72753833581632480403581180800177515552830775683493556930395600007729054862025, 0), 1) } + function test_gt_36() { check(gt(72753833581632480403581180800177515552830775683493556930395600007729054862025, 1), 1) } + function test_gt_37() { check(gt(72753833581632480403581180800177515552830775683493556930395600007729054862025, 2), 1) } + function test_gt_38() { check(gt(72753833581632480403581180800177515552830775683493556930395600007729054862025, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_gt_39() { check(gt(72753833581632480403581180800177515552830775683493556930395600007729054862025, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_gt_40() { check(gt(72753833581632480403581180800177515552830775683493556930395600007729054862025, 72753833581632480403581180800177515552830775683493556930395600007729054862025), 0) } + function test_gt_41() { check(gt(72753833581632480403581180800177515552830775683493556930395600007729054862025, 35494539573573499949677027375126255854449863281693517184786462304148614611354), 1) } + function test_gt_42() { check(gt(35494539573573499949677027375126255854449863281693517184786462304148614611354, 0), 1) } + function test_gt_43() { check(gt(35494539573573499949677027375126255854449863281693517184786462304148614611354, 1), 1) } + function test_gt_44() { check(gt(35494539573573499949677027375126255854449863281693517184786462304148614611354, 2), 1) } + function test_gt_45() { check(gt(35494539573573499949677027375126255854449863281693517184786462304148614611354, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_gt_46() { check(gt(35494539573573499949677027375126255854449863281693517184786462304148614611354, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_gt_47() { check(gt(35494539573573499949677027375126255854449863281693517184786462304148614611354, 72753833581632480403581180800177515552830775683493556930395600007729054862025), 0) } + function test_gt_48() { check(gt(35494539573573499949677027375126255854449863281693517184786462304148614611354, 35494539573573499949677027375126255854449863281693517184786462304148614611354), 0) } + + function test_slt_0() { check(slt(0, 0), 0) } + function test_slt_1() { check(slt(0, 1), 1) } + function test_slt_2() { check(slt(0, 2), 1) } + function test_slt_3() { check(slt(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_slt_4() { check(slt(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_slt_5() { check(slt(0, 68017881531202612655098452160630207043010425238896656775011886183092720945596), 0) } + function test_slt_6() { check(slt(0, 13258081525883010947558584854410285822447126715354520153946626756711423178387), 1) } + function test_slt_7() { check(slt(1, 0), 0) } + function test_slt_8() { check(slt(1, 1), 0) } + function test_slt_9() { check(slt(1, 2), 1) } + function test_slt_10() { check(slt(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_slt_11() { check(slt(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_slt_12() { check(slt(1, 68017881531202612655098452160630207043010425238896656775011886183092720945596), 0) } + function test_slt_13() { check(slt(1, 13258081525883010947558584854410285822447126715354520153946626756711423178387), 1) } + function test_slt_14() { check(slt(2, 0), 0) } + function test_slt_15() { check(slt(2, 1), 0) } + function test_slt_16() { check(slt(2, 2), 0) } + function test_slt_17() { check(slt(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_slt_18() { check(slt(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_slt_19() { check(slt(2, 68017881531202612655098452160630207043010425238896656775011886183092720945596), 0) } + function test_slt_20() { check(slt(2, 13258081525883010947558584854410285822447126715354520153946626756711423178387), 1) } + function test_slt_21() { check(slt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 1) } + function test_slt_22() { check(slt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 1) } + function test_slt_23() { check(slt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 1) } + function test_slt_24() { check(slt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_slt_25() { check(slt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_slt_26() { check(slt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 68017881531202612655098452160630207043010425238896656775011886183092720945596), 0) } + function test_slt_27() { check(slt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 13258081525883010947558584854410285822447126715354520153946626756711423178387), 1) } + function test_slt_28() { check(slt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 1) } + function test_slt_29() { check(slt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 1) } + function test_slt_30() { check(slt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 1) } + function test_slt_31() { check(slt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_slt_32() { check(slt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_slt_33() { check(slt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 68017881531202612655098452160630207043010425238896656775011886183092720945596), 0) } + function test_slt_34() { check(slt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 13258081525883010947558584854410285822447126715354520153946626756711423178387), 1) } + function test_slt_35() { check(slt(68017881531202612655098452160630207043010425238896656775011886183092720945596, 0), 1) } + function test_slt_36() { check(slt(68017881531202612655098452160630207043010425238896656775011886183092720945596, 1), 1) } + function test_slt_37() { check(slt(68017881531202612655098452160630207043010425238896656775011886183092720945596, 2), 1) } + function test_slt_38() { check(slt(68017881531202612655098452160630207043010425238896656775011886183092720945596, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_slt_39() { check(slt(68017881531202612655098452160630207043010425238896656775011886183092720945596, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_slt_40() { check(slt(68017881531202612655098452160630207043010425238896656775011886183092720945596, 68017881531202612655098452160630207043010425238896656775011886183092720945596), 0) } + function test_slt_41() { check(slt(68017881531202612655098452160630207043010425238896656775011886183092720945596, 13258081525883010947558584854410285822447126715354520153946626756711423178387), 1) } + function test_slt_42() { check(slt(13258081525883010947558584854410285822447126715354520153946626756711423178387, 0), 0) } + function test_slt_43() { check(slt(13258081525883010947558584854410285822447126715354520153946626756711423178387, 1), 0) } + function test_slt_44() { check(slt(13258081525883010947558584854410285822447126715354520153946626756711423178387, 2), 0) } + function test_slt_45() { check(slt(13258081525883010947558584854410285822447126715354520153946626756711423178387, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_slt_46() { check(slt(13258081525883010947558584854410285822447126715354520153946626756711423178387, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_slt_47() { check(slt(13258081525883010947558584854410285822447126715354520153946626756711423178387, 68017881531202612655098452160630207043010425238896656775011886183092720945596), 0) } + function test_slt_48() { check(slt(13258081525883010947558584854410285822447126715354520153946626756711423178387, 13258081525883010947558584854410285822447126715354520153946626756711423178387), 0) } + + function test_sgt_0() { check(sgt(0, 0), 0) } + function test_sgt_1() { check(sgt(0, 1), 0) } + function test_sgt_2() { check(sgt(0, 2), 0) } + function test_sgt_3() { check(sgt(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_sgt_4() { check(sgt(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_sgt_5() { check(sgt(0, 84035909357050252967004801141438404926957547641310423814578084074734573169278), 1) } + function test_sgt_6() { check(sgt(0, 103576254108133286169029693563110491732386143024483320278410864238899725331915), 1) } + function test_sgt_7() { check(sgt(1, 0), 1) } + function test_sgt_8() { check(sgt(1, 1), 0) } + function test_sgt_9() { check(sgt(1, 2), 0) } + function test_sgt_10() { check(sgt(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_sgt_11() { check(sgt(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_sgt_12() { check(sgt(1, 84035909357050252967004801141438404926957547641310423814578084074734573169278), 1) } + function test_sgt_13() { check(sgt(1, 103576254108133286169029693563110491732386143024483320278410864238899725331915), 1) } + function test_sgt_14() { check(sgt(2, 0), 1) } + function test_sgt_15() { check(sgt(2, 1), 1) } + function test_sgt_16() { check(sgt(2, 2), 0) } + function test_sgt_17() { check(sgt(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_sgt_18() { check(sgt(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_sgt_19() { check(sgt(2, 84035909357050252967004801141438404926957547641310423814578084074734573169278), 1) } + function test_sgt_20() { check(sgt(2, 103576254108133286169029693563110491732386143024483320278410864238899725331915), 1) } + function test_sgt_21() { check(sgt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 0) } + function test_sgt_22() { check(sgt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 0) } + function test_sgt_23() { check(sgt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 0) } + function test_sgt_24() { check(sgt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_sgt_25() { check(sgt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_sgt_26() { check(sgt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 84035909357050252967004801141438404926957547641310423814578084074734573169278), 1) } + function test_sgt_27() { check(sgt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 103576254108133286169029693563110491732386143024483320278410864238899725331915), 1) } + function test_sgt_28() { check(sgt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 0) } + function test_sgt_29() { check(sgt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 0) } + function test_sgt_30() { check(sgt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 0) } + function test_sgt_31() { check(sgt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_sgt_32() { check(sgt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_sgt_33() { check(sgt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 84035909357050252967004801141438404926957547641310423814578084074734573169278), 1) } + function test_sgt_34() { check(sgt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 103576254108133286169029693563110491732386143024483320278410864238899725331915), 1) } + function test_sgt_35() { check(sgt(84035909357050252967004801141438404926957547641310423814578084074734573169278, 0), 0) } + function test_sgt_36() { check(sgt(84035909357050252967004801141438404926957547641310423814578084074734573169278, 1), 0) } + function test_sgt_37() { check(sgt(84035909357050252967004801141438404926957547641310423814578084074734573169278, 2), 0) } + function test_sgt_38() { check(sgt(84035909357050252967004801141438404926957547641310423814578084074734573169278, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_sgt_39() { check(sgt(84035909357050252967004801141438404926957547641310423814578084074734573169278, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_sgt_40() { check(sgt(84035909357050252967004801141438404926957547641310423814578084074734573169278, 84035909357050252967004801141438404926957547641310423814578084074734573169278), 0) } + function test_sgt_41() { check(sgt(84035909357050252967004801141438404926957547641310423814578084074734573169278, 103576254108133286169029693563110491732386143024483320278410864238899725331915), 0) } + function test_sgt_42() { check(sgt(103576254108133286169029693563110491732386143024483320278410864238899725331915, 0), 0) } + function test_sgt_43() { check(sgt(103576254108133286169029693563110491732386143024483320278410864238899725331915, 1), 0) } + function test_sgt_44() { check(sgt(103576254108133286169029693563110491732386143024483320278410864238899725331915, 2), 0) } + function test_sgt_45() { check(sgt(103576254108133286169029693563110491732386143024483320278410864238899725331915, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_sgt_46() { check(sgt(103576254108133286169029693563110491732386143024483320278410864238899725331915, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_sgt_47() { check(sgt(103576254108133286169029693563110491732386143024483320278410864238899725331915, 84035909357050252967004801141438404926957547641310423814578084074734573169278), 1) } + function test_sgt_48() { check(sgt(103576254108133286169029693563110491732386143024483320278410864238899725331915, 103576254108133286169029693563110491732386143024483320278410864238899725331915), 0) } + + function test_eq_0() { check(eq(0, 0), 1) } + function test_eq_1() { check(eq(0, 1), 0) } + function test_eq_2() { check(eq(0, 2), 0) } + function test_eq_3() { check(eq(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_eq_4() { check(eq(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_eq_5() { check(eq(0, 97133802217059873572115247499120430778873647836906735131740627443945036049230), 0) } + function test_eq_6() { check(eq(0, 103127332497177868134427090381050163513970449586554649944836964578763488208973), 0) } + function test_eq_7() { check(eq(1, 0), 0) } + function test_eq_8() { check(eq(1, 1), 1) } + function test_eq_9() { check(eq(1, 2), 0) } + function test_eq_10() { check(eq(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_eq_11() { check(eq(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_eq_12() { check(eq(1, 97133802217059873572115247499120430778873647836906735131740627443945036049230), 0) } + function test_eq_13() { check(eq(1, 103127332497177868134427090381050163513970449586554649944836964578763488208973), 0) } + function test_eq_14() { check(eq(2, 0), 0) } + function test_eq_15() { check(eq(2, 1), 0) } + function test_eq_16() { check(eq(2, 2), 1) } + function test_eq_17() { check(eq(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_eq_18() { check(eq(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_eq_19() { check(eq(2, 97133802217059873572115247499120430778873647836906735131740627443945036049230), 0) } + function test_eq_20() { check(eq(2, 103127332497177868134427090381050163513970449586554649944836964578763488208973), 0) } + function test_eq_21() { check(eq(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 0) } + function test_eq_22() { check(eq(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 0) } + function test_eq_23() { check(eq(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 0) } + function test_eq_24() { check(eq(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_eq_25() { check(eq(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_eq_26() { check(eq(115792089237316195423570985008687907853269984665640564039457584007913129639935, 97133802217059873572115247499120430778873647836906735131740627443945036049230), 0) } + function test_eq_27() { check(eq(115792089237316195423570985008687907853269984665640564039457584007913129639935, 103127332497177868134427090381050163513970449586554649944836964578763488208973), 0) } + function test_eq_28() { check(eq(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 0) } + function test_eq_29() { check(eq(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 0) } + function test_eq_30() { check(eq(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 0) } + function test_eq_31() { check(eq(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_eq_32() { check(eq(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_eq_33() { check(eq(115792089237316195423570985008687907853269984665640564039457584007913129639934, 97133802217059873572115247499120430778873647836906735131740627443945036049230), 0) } + function test_eq_34() { check(eq(115792089237316195423570985008687907853269984665640564039457584007913129639934, 103127332497177868134427090381050163513970449586554649944836964578763488208973), 0) } + function test_eq_35() { check(eq(97133802217059873572115247499120430778873647836906735131740627443945036049230, 0), 0) } + function test_eq_36() { check(eq(97133802217059873572115247499120430778873647836906735131740627443945036049230, 1), 0) } + function test_eq_37() { check(eq(97133802217059873572115247499120430778873647836906735131740627443945036049230, 2), 0) } + function test_eq_38() { check(eq(97133802217059873572115247499120430778873647836906735131740627443945036049230, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_eq_39() { check(eq(97133802217059873572115247499120430778873647836906735131740627443945036049230, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_eq_40() { check(eq(97133802217059873572115247499120430778873647836906735131740627443945036049230, 97133802217059873572115247499120430778873647836906735131740627443945036049230), 1) } + function test_eq_41() { check(eq(97133802217059873572115247499120430778873647836906735131740627443945036049230, 103127332497177868134427090381050163513970449586554649944836964578763488208973), 0) } + function test_eq_42() { check(eq(103127332497177868134427090381050163513970449586554649944836964578763488208973, 0), 0) } + function test_eq_43() { check(eq(103127332497177868134427090381050163513970449586554649944836964578763488208973, 1), 0) } + function test_eq_44() { check(eq(103127332497177868134427090381050163513970449586554649944836964578763488208973, 2), 0) } + function test_eq_45() { check(eq(103127332497177868134427090381050163513970449586554649944836964578763488208973, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_eq_46() { check(eq(103127332497177868134427090381050163513970449586554649944836964578763488208973, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_eq_47() { check(eq(103127332497177868134427090381050163513970449586554649944836964578763488208973, 97133802217059873572115247499120430778873647836906735131740627443945036049230), 0) } + function test_eq_48() { check(eq(103127332497177868134427090381050163513970449586554649944836964578763488208973, 103127332497177868134427090381050163513970449586554649944836964578763488208973), 1) } + + function test_iszero_0() { check(iszero(0), 1) } + function test_iszero_1() { check(iszero(1), 0) } + function test_iszero_2() { check(iszero(2), 0) } + function test_iszero_3() { check(iszero(115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_iszero_4() { check(iszero(115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_iszero_5() { check(iszero(78747297409364612785885845379455161720601848466564928756860453014835669881157), 0) } + function test_iszero_6() { check(iszero(9557482626947878892720236566563598074546921018893965976656816169955093186136), 0) } + + function test_and_0() { check(and(0, 0), 0) } + function test_and_1() { check(and(0, 1), 0) } + function test_and_2() { check(and(0, 2), 0) } + function test_and_3() { check(and(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_and_4() { check(and(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_and_5() { check(and(0, 19250563356642585679821982809780683800151980259572704592519096096056450665275), 0) } + function test_and_6() { check(and(0, 46417999922850358461056893659186219261610420503262663932694263891945069455012), 0) } + function test_and_7() { check(and(1, 0), 0) } + function test_and_8() { check(and(1, 1), 1) } + function test_and_9() { check(and(1, 2), 0) } + function test_and_10() { check(and(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_and_11() { check(and(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_and_12() { check(and(1, 19250563356642585679821982809780683800151980259572704592519096096056450665275), 1) } + function test_and_13() { check(and(1, 46417999922850358461056893659186219261610420503262663932694263891945069455012), 0) } + function test_and_14() { check(and(2, 0), 0) } + function test_and_15() { check(and(2, 1), 0) } + function test_and_16() { check(and(2, 2), 2) } + function test_and_17() { check(and(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 2) } + function test_and_18() { check(and(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 2) } + function test_and_19() { check(and(2, 19250563356642585679821982809780683800151980259572704592519096096056450665275), 2) } + function test_and_20() { check(and(2, 46417999922850358461056893659186219261610420503262663932694263891945069455012), 0) } + function test_and_21() { check(and(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 0) } + function test_and_22() { check(and(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 1) } + function test_and_23() { check(and(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 2) } + function test_and_24() { check(and(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_and_25() { check(and(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_and_26() { check(and(115792089237316195423570985008687907853269984665640564039457584007913129639935, 19250563356642585679821982809780683800151980259572704592519096096056450665275), 19250563356642585679821982809780683800151980259572704592519096096056450665275) } + function test_and_27() { check(and(115792089237316195423570985008687907853269984665640564039457584007913129639935, 46417999922850358461056893659186219261610420503262663932694263891945069455012), 46417999922850358461056893659186219261610420503262663932694263891945069455012) } + function test_and_28() { check(and(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 0) } + function test_and_29() { check(and(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 0) } + function test_and_30() { check(and(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 2) } + function test_and_31() { check(and(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_and_32() { check(and(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_and_33() { check(and(115792089237316195423570985008687907853269984665640564039457584007913129639934, 19250563356642585679821982809780683800151980259572704592519096096056450665275), 19250563356642585679821982809780683800151980259572704592519096096056450665274) } + function test_and_34() { check(and(115792089237316195423570985008687907853269984665640564039457584007913129639934, 46417999922850358461056893659186219261610420503262663932694263891945069455012), 46417999922850358461056893659186219261610420503262663932694263891945069455012) } + function test_and_35() { check(and(19250563356642585679821982809780683800151980259572704592519096096056450665275, 0), 0) } + function test_and_36() { check(and(19250563356642585679821982809780683800151980259572704592519096096056450665275, 1), 1) } + function test_and_37() { check(and(19250563356642585679821982809780683800151980259572704592519096096056450665275, 2), 2) } + function test_and_38() { check(and(19250563356642585679821982809780683800151980259572704592519096096056450665275, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 19250563356642585679821982809780683800151980259572704592519096096056450665275) } + function test_and_39() { check(and(19250563356642585679821982809780683800151980259572704592519096096056450665275, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 19250563356642585679821982809780683800151980259572704592519096096056450665274) } + function test_and_40() { check(and(19250563356642585679821982809780683800151980259572704592519096096056450665275, 19250563356642585679821982809780683800151980259572704592519096096056450665275), 19250563356642585679821982809780683800151980259572704592519096096056450665275) } + function test_and_41() { check(and(19250563356642585679821982809780683800151980259572704592519096096056450665275, 46417999922850358461056893659186219261610420503262663932694263891945069455012), 15631572267631210243224111594511664554898671681708678689198934479333455725088) } + function test_and_42() { check(and(46417999922850358461056893659186219261610420503262663932694263891945069455012, 0), 0) } + function test_and_43() { check(and(46417999922850358461056893659186219261610420503262663932694263891945069455012, 1), 0) } + function test_and_44() { check(and(46417999922850358461056893659186219261610420503262663932694263891945069455012, 2), 0) } + function test_and_45() { check(and(46417999922850358461056893659186219261610420503262663932694263891945069455012, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 46417999922850358461056893659186219261610420503262663932694263891945069455012) } + function test_and_46() { check(and(46417999922850358461056893659186219261610420503262663932694263891945069455012, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 46417999922850358461056893659186219261610420503262663932694263891945069455012) } + function test_and_47() { check(and(46417999922850358461056893659186219261610420503262663932694263891945069455012, 19250563356642585679821982809780683800151980259572704592519096096056450665275), 15631572267631210243224111594511664554898671681708678689198934479333455725088) } + function test_and_48() { check(and(46417999922850358461056893659186219261610420503262663932694263891945069455012, 46417999922850358461056893659186219261610420503262663932694263891945069455012), 46417999922850358461056893659186219261610420503262663932694263891945069455012) } + + function test_or_0() { check(or(0, 0), 0) } + function test_or_1() { check(or(0, 1), 1) } + function test_or_2() { check(or(0, 2), 2) } + function test_or_3() { check(or(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_4() { check(or(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_or_5() { check(or(0, 56958862471241653073072976553386602741495522157520644114395302660506026208404), 56958862471241653073072976553386602741495522157520644114395302660506026208404) } + function test_or_6() { check(or(0, 41540679175160398463199353554771824285248731067717774369911027068229334053563), 41540679175160398463199353554771824285248731067717774369911027068229334053563) } + function test_or_7() { check(or(1, 0), 1) } + function test_or_8() { check(or(1, 1), 1) } + function test_or_9() { check(or(1, 2), 3) } + function test_or_10() { check(or(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_11() { check(or(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_12() { check(or(1, 56958862471241653073072976553386602741495522157520644114395302660506026208404), 56958862471241653073072976553386602741495522157520644114395302660506026208405) } + function test_or_13() { check(or(1, 41540679175160398463199353554771824285248731067717774369911027068229334053563), 41540679175160398463199353554771824285248731067717774369911027068229334053563) } + function test_or_14() { check(or(2, 0), 2) } + function test_or_15() { check(or(2, 1), 3) } + function test_or_16() { check(or(2, 2), 2) } + function test_or_17() { check(or(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_18() { check(or(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_or_19() { check(or(2, 56958862471241653073072976553386602741495522157520644114395302660506026208404), 56958862471241653073072976553386602741495522157520644114395302660506026208406) } + function test_or_20() { check(or(2, 41540679175160398463199353554771824285248731067717774369911027068229334053563), 41540679175160398463199353554771824285248731067717774369911027068229334053563) } + function test_or_21() { check(or(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_22() { check(or(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_23() { check(or(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_24() { check(or(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_25() { check(or(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_26() { check(or(115792089237316195423570985008687907853269984665640564039457584007913129639935, 56958862471241653073072976553386602741495522157520644114395302660506026208404), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_27() { check(or(115792089237316195423570985008687907853269984665640564039457584007913129639935, 41540679175160398463199353554771824285248731067717774369911027068229334053563), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_28() { check(or(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_or_29() { check(or(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_30() { check(or(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_or_31() { check(or(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_32() { check(or(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_or_33() { check(or(115792089237316195423570985008687907853269984665640564039457584007913129639934, 56958862471241653073072976553386602741495522157520644114395302660506026208404), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_or_34() { check(or(115792089237316195423570985008687907853269984665640564039457584007913129639934, 41540679175160398463199353554771824285248731067717774369911027068229334053563), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_35() { check(or(56958862471241653073072976553386602741495522157520644114395302660506026208404, 0), 56958862471241653073072976553386602741495522157520644114395302660506026208404) } + function test_or_36() { check(or(56958862471241653073072976553386602741495522157520644114395302660506026208404, 1), 56958862471241653073072976553386602741495522157520644114395302660506026208405) } + function test_or_37() { check(or(56958862471241653073072976553386602741495522157520644114395302660506026208404, 2), 56958862471241653073072976553386602741495522157520644114395302660506026208406) } + function test_or_38() { check(or(56958862471241653073072976553386602741495522157520644114395302660506026208404, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_39() { check(or(56958862471241653073072976553386602741495522157520644114395302660506026208404, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_or_40() { check(or(56958862471241653073072976553386602741495522157520644114395302660506026208404, 56958862471241653073072976553386602741495522157520644114395302660506026208404), 56958862471241653073072976553386602741495522157520644114395302660506026208404) } + function test_or_41() { check(or(56958862471241653073072976553386602741495522157520644114395302660506026208404, 41540679175160398463199353554771824285248731067717774369911027068229334053563), 57895513161191823138089177244917758114200981566710351315321107400068061200063) } + function test_or_42() { check(or(41540679175160398463199353554771824285248731067717774369911027068229334053563, 0), 41540679175160398463199353554771824285248731067717774369911027068229334053563) } + function test_or_43() { check(or(41540679175160398463199353554771824285248731067717774369911027068229334053563, 1), 41540679175160398463199353554771824285248731067717774369911027068229334053563) } + function test_or_44() { check(or(41540679175160398463199353554771824285248731067717774369911027068229334053563, 2), 41540679175160398463199353554771824285248731067717774369911027068229334053563) } + function test_or_45() { check(or(41540679175160398463199353554771824285248731067717774369911027068229334053563, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_46() { check(or(41540679175160398463199353554771824285248731067717774369911027068229334053563, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_or_47() { check(or(41540679175160398463199353554771824285248731067717774369911027068229334053563, 56958862471241653073072976553386602741495522157520644114395302660506026208404), 57895513161191823138089177244917758114200981566710351315321107400068061200063) } + function test_or_48() { check(or(41540679175160398463199353554771824285248731067717774369911027068229334053563, 41540679175160398463199353554771824285248731067717774369911027068229334053563), 41540679175160398463199353554771824285248731067717774369911027068229334053563) } + + function test_xor_0() { check(xor(0, 0), 0) } + function test_xor_1() { check(xor(0, 1), 1) } + function test_xor_2() { check(xor(0, 2), 2) } + function test_xor_3() { check(xor(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_xor_4() { check(xor(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_xor_5() { check(xor(0, 93879730722178485205967128194645854796186255569129730504744197411393305498348), 93879730722178485205967128194645854796186255569129730504744197411393305498348) } + function test_xor_6() { check(xor(0, 14232531272672338704119765390482207930099023516624419694095745480866891788086), 14232531272672338704119765390482207930099023516624419694095745480866891788086) } + function test_xor_7() { check(xor(1, 0), 1) } + function test_xor_8() { check(xor(1, 1), 0) } + function test_xor_9() { check(xor(1, 2), 3) } + function test_xor_10() { check(xor(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_xor_11() { check(xor(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_xor_12() { check(xor(1, 93879730722178485205967128194645854796186255569129730504744197411393305498348), 93879730722178485205967128194645854796186255569129730504744197411393305498349) } + function test_xor_13() { check(xor(1, 14232531272672338704119765390482207930099023516624419694095745480866891788086), 14232531272672338704119765390482207930099023516624419694095745480866891788087) } + function test_xor_14() { check(xor(2, 0), 2) } + function test_xor_15() { check(xor(2, 1), 3) } + function test_xor_16() { check(xor(2, 2), 0) } + function test_xor_17() { check(xor(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639933) } + function test_xor_18() { check(xor(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639932) } + function test_xor_19() { check(xor(2, 93879730722178485205967128194645854796186255569129730504744197411393305498348), 93879730722178485205967128194645854796186255569129730504744197411393305498350) } + function test_xor_20() { check(xor(2, 14232531272672338704119765390482207930099023516624419694095745480866891788086), 14232531272672338704119765390482207930099023516624419694095745480866891788084) } + function test_xor_21() { check(xor(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_xor_22() { check(xor(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_xor_23() { check(xor(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 115792089237316195423570985008687907853269984665640564039457584007913129639933) } + function test_xor_24() { check(xor(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_xor_25() { check(xor(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 1) } + function test_xor_26() { check(xor(115792089237316195423570985008687907853269984665640564039457584007913129639935, 93879730722178485205967128194645854796186255569129730504744197411393305498348), 21912358515137710217603856814042053057083729096510833534713386596519824141587) } + function test_xor_27() { check(xor(115792089237316195423570985008687907853269984665640564039457584007913129639935, 14232531272672338704119765390482207930099023516624419694095745480866891788086), 101559557964643856719451219618205699923170961149016144345361838527046237851849) } + function test_xor_28() { check(xor(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_xor_29() { check(xor(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_xor_30() { check(xor(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 115792089237316195423570985008687907853269984665640564039457584007913129639932) } + function test_xor_31() { check(xor(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 1) } + function test_xor_32() { check(xor(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_xor_33() { check(xor(115792089237316195423570985008687907853269984665640564039457584007913129639934, 93879730722178485205967128194645854796186255569129730504744197411393305498348), 21912358515137710217603856814042053057083729096510833534713386596519824141586) } + function test_xor_34() { check(xor(115792089237316195423570985008687907853269984665640564039457584007913129639934, 14232531272672338704119765390482207930099023516624419694095745480866891788086), 101559557964643856719451219618205699923170961149016144345361838527046237851848) } + function test_xor_35() { check(xor(93879730722178485205967128194645854796186255569129730504744197411393305498348, 0), 93879730722178485205967128194645854796186255569129730504744197411393305498348) } + function test_xor_36() { check(xor(93879730722178485205967128194645854796186255569129730504744197411393305498348, 1), 93879730722178485205967128194645854796186255569129730504744197411393305498349) } + function test_xor_37() { check(xor(93879730722178485205967128194645854796186255569129730504744197411393305498348, 2), 93879730722178485205967128194645854796186255569129730504744197411393305498350) } + function test_xor_38() { check(xor(93879730722178485205967128194645854796186255569129730504744197411393305498348, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 21912358515137710217603856814042053057083729096510833534713386596519824141587) } + function test_xor_39() { check(xor(93879730722178485205967128194645854796186255569129730504744197411393305498348, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 21912358515137710217603856814042053057083729096510833534713386596519824141586) } + function test_xor_40() { check(xor(93879730722178485205967128194645854796186255569129730504744197411393305498348, 93879730722178485205967128194645854796186255569129730504744197411393305498348), 0) } + function test_xor_41() { check(xor(93879730722178485205967128194645854796186255569129730504744197411393305498348, 14232531272672338704119765390482207930099023516624419694095745480866891788086), 94521629507852507853109237600535852707402170726003012251761205963601127259610) } + function test_xor_42() { check(xor(14232531272672338704119765390482207930099023516624419694095745480866891788086, 0), 14232531272672338704119765390482207930099023516624419694095745480866891788086) } + function test_xor_43() { check(xor(14232531272672338704119765390482207930099023516624419694095745480866891788086, 1), 14232531272672338704119765390482207930099023516624419694095745480866891788087) } + function test_xor_44() { check(xor(14232531272672338704119765390482207930099023516624419694095745480866891788086, 2), 14232531272672338704119765390482207930099023516624419694095745480866891788084) } + function test_xor_45() { check(xor(14232531272672338704119765390482207930099023516624419694095745480866891788086, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 101559557964643856719451219618205699923170961149016144345361838527046237851849) } + function test_xor_46() { check(xor(14232531272672338704119765390482207930099023516624419694095745480866891788086, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 101559557964643856719451219618205699923170961149016144345361838527046237851848) } + function test_xor_47() { check(xor(14232531272672338704119765390482207930099023516624419694095745480866891788086, 93879730722178485205967128194645854796186255569129730504744197411393305498348), 94521629507852507853109237600535852707402170726003012251761205963601127259610) } + function test_xor_48() { check(xor(14232531272672338704119765390482207930099023516624419694095745480866891788086, 14232531272672338704119765390482207930099023516624419694095745480866891788086), 0) } + + function test_byte_0() { check(byte(68800988322768072237345063627670221053112791386522147760437104509587064083236, 68800988322768072237345063627670221053112791386522147760437104509587064083236), 0) } + function test_byte_1() { check(byte(68800988322768072237345063627670221053112791386522147760437104509587064083236, 87594912600945758326410424914523594146731054887000169625869931741457929600180), 0) } + function test_byte_2() { check(byte(68800988322768072237345063627670221053112791386522147760437104509587064083236, 30), 0) } + function test_byte_3() { check(byte(68800988322768072237345063627670221053112791386522147760437104509587064083236, 26), 0) } + function test_byte_4() { check(byte(68800988322768072237345063627670221053112791386522147760437104509587064083236, 0), 0) } + function test_byte_5() { check(byte(87594912600945758326410424914523594146731054887000169625869931741457929600180, 68800988322768072237345063627670221053112791386522147760437104509587064083236), 0) } + function test_byte_6() { check(byte(87594912600945758326410424914523594146731054887000169625869931741457929600180, 87594912600945758326410424914523594146731054887000169625869931741457929600180), 0) } + function test_byte_7() { check(byte(87594912600945758326410424914523594146731054887000169625869931741457929600180, 30), 0) } + function test_byte_8() { check(byte(87594912600945758326410424914523594146731054887000169625869931741457929600180, 26), 0) } + function test_byte_9() { check(byte(87594912600945758326410424914523594146731054887000169625869931741457929600180, 0), 0) } + function test_byte_10() { check(byte(30, 68800988322768072237345063627670221053112791386522147760437104509587064083236), 211) } + function test_byte_11() { check(byte(30, 87594912600945758326410424914523594146731054887000169625869931741457929600180), 252) } + function test_byte_12() { check(byte(30, 30), 0) } + function test_byte_13() { check(byte(30, 26), 0) } + function test_byte_14() { check(byte(30, 0), 0) } + function test_byte_15() { check(byte(26, 68800988322768072237345063627670221053112791386522147760437104509587064083236), 82) } + function test_byte_16() { check(byte(26, 87594912600945758326410424914523594146731054887000169625869931741457929600180), 233) } + function test_byte_17() { check(byte(26, 30), 0) } + function test_byte_18() { check(byte(26, 26), 0) } + function test_byte_19() { check(byte(26, 0), 0) } + function test_byte_20() { check(byte(0, 68800988322768072237345063627670221053112791386522147760437104509587064083236), 152) } + function test_byte_21() { check(byte(0, 87594912600945758326410424914523594146731054887000169625869931741457929600180), 193) } + function test_byte_22() { check(byte(0, 30), 0) } + function test_byte_23() { check(byte(0, 26), 0) } + function test_byte_24() { check(byte(0, 0), 0) } + + function test_shl_0() { check(shl(0, 0), 0) } + function test_shl_1() { check(shl(0, 1), 1) } + function test_shl_2() { check(shl(0, 2), 2) } + function test_shl_3() { check(shl(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_shl_4() { check(shl(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_shl_5() { check(shl(0, 44264216052681650963313079231923757121479731937092683747356446748236073468430), 44264216052681650963313079231923757121479731937092683747356446748236073468430) } + function test_shl_6() { check(shl(0, 31375775438714370564795450075197198747006289363524780583775597123749079718168), 31375775438714370564795450075197198747006289363524780583775597123749079718168) } + function test_shl_7() { check(shl(1, 0), 0) } + function test_shl_8() { check(shl(1, 1), 2) } + function test_shl_9() { check(shl(1, 2), 4) } + function test_shl_10() { check(shl(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_shl_11() { check(shl(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639932) } + function test_shl_12() { check(shl(1, 44264216052681650963313079231923757121479731937092683747356446748236073468430), 88528432105363301926626158463847514242959463874185367494712893496472146936860) } + function test_shl_13() { check(shl(1, 31375775438714370564795450075197198747006289363524780583775597123749079718168), 62751550877428741129590900150394397494012578727049561167551194247498159436336) } + function test_shl_14() { check(shl(2, 0), 0) } + function test_shl_15() { check(shl(2, 1), 4) } + function test_shl_16() { check(shl(2, 2), 8) } + function test_shl_17() { check(shl(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639932) } + function test_shl_18() { check(shl(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639928) } + function test_shl_19() { check(shl(2, 44264216052681650963313079231923757121479731937092683747356446748236073468430), 61264774973410408429681331919007120632648943082730170949968202985031164233784) } + function test_shl_20() { check(shl(2, 31375775438714370564795450075197198747006289363524780583775597123749079718168), 9711012517541286835610815292100887134755172788458558295644804487083189232736) } + function test_shl_21() { check(shl(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 0) } + function test_shl_22() { check(shl(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 0) } + function test_shl_23() { check(shl(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 0) } + function test_shl_24() { check(shl(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_shl_25() { check(shl(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_shl_26() { check(shl(115792089237316195423570985008687907853269984665640564039457584007913129639935, 44264216052681650963313079231923757121479731937092683747356446748236073468430), 0) } + function test_shl_27() { check(shl(115792089237316195423570985008687907853269984665640564039457584007913129639935, 31375775438714370564795450075197198747006289363524780583775597123749079718168), 0) } + function test_shl_28() { check(shl(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 0) } + function test_shl_29() { check(shl(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 0) } + function test_shl_30() { check(shl(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 0) } + function test_shl_31() { check(shl(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_shl_32() { check(shl(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_shl_33() { check(shl(115792089237316195423570985008687907853269984665640564039457584007913129639934, 44264216052681650963313079231923757121479731937092683747356446748236073468430), 0) } + function test_shl_34() { check(shl(115792089237316195423570985008687907853269984665640564039457584007913129639934, 31375775438714370564795450075197198747006289363524780583775597123749079718168), 0) } + function test_shl_35() { check(shl(44264216052681650963313079231923757121479731937092683747356446748236073468430, 0), 0) } + function test_shl_36() { check(shl(44264216052681650963313079231923757121479731937092683747356446748236073468430, 1), 0) } + function test_shl_37() { check(shl(44264216052681650963313079231923757121479731937092683747356446748236073468430, 2), 0) } + function test_shl_38() { check(shl(44264216052681650963313079231923757121479731937092683747356446748236073468430, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_shl_39() { check(shl(44264216052681650963313079231923757121479731937092683747356446748236073468430, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_shl_40() { check(shl(44264216052681650963313079231923757121479731937092683747356446748236073468430, 44264216052681650963313079231923757121479731937092683747356446748236073468430), 0) } + function test_shl_41() { check(shl(44264216052681650963313079231923757121479731937092683747356446748236073468430, 31375775438714370564795450075197198747006289363524780583775597123749079718168), 0) } + function test_shl_42() { check(shl(31375775438714370564795450075197198747006289363524780583775597123749079718168, 0), 0) } + function test_shl_43() { check(shl(31375775438714370564795450075197198747006289363524780583775597123749079718168, 1), 0) } + function test_shl_44() { check(shl(31375775438714370564795450075197198747006289363524780583775597123749079718168, 2), 0) } + function test_shl_45() { check(shl(31375775438714370564795450075197198747006289363524780583775597123749079718168, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_shl_46() { check(shl(31375775438714370564795450075197198747006289363524780583775597123749079718168, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_shl_47() { check(shl(31375775438714370564795450075197198747006289363524780583775597123749079718168, 44264216052681650963313079231923757121479731937092683747356446748236073468430), 0) } + function test_shl_48() { check(shl(31375775438714370564795450075197198747006289363524780583775597123749079718168, 31375775438714370564795450075197198747006289363524780583775597123749079718168), 0) } + + function test_shr_0() { check(shr(0, 0), 0) } + function test_shr_1() { check(shr(0, 1), 1) } + function test_shr_2() { check(shr(0, 2), 2) } + function test_shr_3() { check(shr(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_shr_4() { check(shr(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_shr_5() { check(shr(0, 37274857428727835743259556673680271738176590670119373800342835673791532889898), 37274857428727835743259556673680271738176590670119373800342835673791532889898) } + function test_shr_6() { check(shr(0, 62702957303074580081337476767887907527881951999783234736971020740941246311273), 62702957303074580081337476767887907527881951999783234736971020740941246311273) } + function test_shr_7() { check(shr(1, 0), 0) } + function test_shr_8() { check(shr(1, 1), 0) } + function test_shr_9() { check(shr(1, 2), 1) } + function test_shr_10() { check(shr(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 57896044618658097711785492504343953926634992332820282019728792003956564819967) } + function test_shr_11() { check(shr(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 57896044618658097711785492504343953926634992332820282019728792003956564819967) } + function test_shr_12() { check(shr(1, 37274857428727835743259556673680271738176590670119373800342835673791532889898), 18637428714363917871629778336840135869088295335059686900171417836895766444949) } + function test_shr_13() { check(shr(1, 62702957303074580081337476767887907527881951999783234736971020740941246311273), 31351478651537290040668738383943953763940975999891617368485510370470623155636) } + function test_shr_14() { check(shr(2, 0), 0) } + function test_shr_15() { check(shr(2, 1), 0) } + function test_shr_16() { check(shr(2, 2), 0) } + function test_shr_17() { check(shr(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 28948022309329048855892746252171976963317496166410141009864396001978282409983) } + function test_shr_18() { check(shr(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 28948022309329048855892746252171976963317496166410141009864396001978282409983) } + function test_shr_19() { check(shr(2, 37274857428727835743259556673680271738176590670119373800342835673791532889898), 9318714357181958935814889168420067934544147667529843450085708918447883222474) } + function test_shr_20() { check(shr(2, 62702957303074580081337476767887907527881951999783234736971020740941246311273), 15675739325768645020334369191971976881970487999945808684242755185235311577818) } + function test_shr_21() { check(shr(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 0) } + function test_shr_22() { check(shr(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 0) } + function test_shr_23() { check(shr(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 0) } + function test_shr_24() { check(shr(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_shr_25() { check(shr(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_shr_26() { check(shr(115792089237316195423570985008687907853269984665640564039457584007913129639935, 37274857428727835743259556673680271738176590670119373800342835673791532889898), 0) } + function test_shr_27() { check(shr(115792089237316195423570985008687907853269984665640564039457584007913129639935, 62702957303074580081337476767887907527881951999783234736971020740941246311273), 0) } + function test_shr_28() { check(shr(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 0) } + function test_shr_29() { check(shr(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 0) } + function test_shr_30() { check(shr(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 0) } + function test_shr_31() { check(shr(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_shr_32() { check(shr(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_shr_33() { check(shr(115792089237316195423570985008687907853269984665640564039457584007913129639934, 37274857428727835743259556673680271738176590670119373800342835673791532889898), 0) } + function test_shr_34() { check(shr(115792089237316195423570985008687907853269984665640564039457584007913129639934, 62702957303074580081337476767887907527881951999783234736971020740941246311273), 0) } + function test_shr_35() { check(shr(37274857428727835743259556673680271738176590670119373800342835673791532889898, 0), 0) } + function test_shr_36() { check(shr(37274857428727835743259556673680271738176590670119373800342835673791532889898, 1), 0) } + function test_shr_37() { check(shr(37274857428727835743259556673680271738176590670119373800342835673791532889898, 2), 0) } + function test_shr_38() { check(shr(37274857428727835743259556673680271738176590670119373800342835673791532889898, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_shr_39() { check(shr(37274857428727835743259556673680271738176590670119373800342835673791532889898, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_shr_40() { check(shr(37274857428727835743259556673680271738176590670119373800342835673791532889898, 37274857428727835743259556673680271738176590670119373800342835673791532889898), 0) } + function test_shr_41() { check(shr(37274857428727835743259556673680271738176590670119373800342835673791532889898, 62702957303074580081337476767887907527881951999783234736971020740941246311273), 0) } + function test_shr_42() { check(shr(62702957303074580081337476767887907527881951999783234736971020740941246311273, 0), 0) } + function test_shr_43() { check(shr(62702957303074580081337476767887907527881951999783234736971020740941246311273, 1), 0) } + function test_shr_44() { check(shr(62702957303074580081337476767887907527881951999783234736971020740941246311273, 2), 0) } + function test_shr_45() { check(shr(62702957303074580081337476767887907527881951999783234736971020740941246311273, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 0) } + function test_shr_46() { check(shr(62702957303074580081337476767887907527881951999783234736971020740941246311273, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 0) } + function test_shr_47() { check(shr(62702957303074580081337476767887907527881951999783234736971020740941246311273, 37274857428727835743259556673680271738176590670119373800342835673791532889898), 0) } + function test_shr_48() { check(shr(62702957303074580081337476767887907527881951999783234736971020740941246311273, 62702957303074580081337476767887907527881951999783234736971020740941246311273), 0) } + + function test_sar_0() { check(sar(0, 0), 0) } + function test_sar_1() { check(sar(0, 1), 1) } + function test_sar_2() { check(sar(0, 2), 2) } + function test_sar_3() { check(sar(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_4() { check(sar(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_sar_5() { check(sar(0, 82661433933280756441503497801869500397196377459062817609058635274434912526612), 82661433933280756441503497801869500397196377459062817609058635274434912526612) } + function test_sar_6() { check(sar(0, 14420977034312971726267164976326299024771581485143405760981081574949684199148), 14420977034312971726267164976326299024771581485143405760981081574949684199148) } + function test_sar_7() { check(sar(1, 0), 0) } + function test_sar_8() { check(sar(1, 1), 0) } + function test_sar_9() { check(sar(1, 2), 1) } + function test_sar_10() { check(sar(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_11() { check(sar(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_12() { check(sar(1, 82661433933280756441503497801869500397196377459062817609058635274434912526612), 99226761585298475932537241405278704125233181062351690824258109641174021083274) } + function test_sar_13() { check(sar(1, 14420977034312971726267164976326299024771581485143405760981081574949684199148), 7210488517156485863133582488163149512385790742571702880490540787474842099574) } + function test_sar_14() { check(sar(2, 0), 0) } + function test_sar_15() { check(sar(2, 1), 0) } + function test_sar_16() { check(sar(2, 2), 0) } + function test_sar_17() { check(sar(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_18() { check(sar(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_19() { check(sar(2, 82661433933280756441503497801869500397196377459062817609058635274434912526612), 107509425411307335678054113206983305989251582863996127431857846824543575361605) } + function test_sar_20() { check(sar(2, 14420977034312971726267164976326299024771581485143405760981081574949684199148), 3605244258578242931566791244081574756192895371285851440245270393737421049787) } + function test_sar_21() { check(sar(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 0) } + function test_sar_22() { check(sar(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 0) } + function test_sar_23() { check(sar(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 0) } + function test_sar_24() { check(sar(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_25() { check(sar(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_26() { check(sar(115792089237316195423570985008687907853269984665640564039457584007913129639935, 82661433933280756441503497801869500397196377459062817609058635274434912526612), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_27() { check(sar(115792089237316195423570985008687907853269984665640564039457584007913129639935, 14420977034312971726267164976326299024771581485143405760981081574949684199148), 0) } + function test_sar_28() { check(sar(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 0) } + function test_sar_29() { check(sar(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 0) } + function test_sar_30() { check(sar(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 0) } + function test_sar_31() { check(sar(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_32() { check(sar(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_33() { check(sar(115792089237316195423570985008687907853269984665640564039457584007913129639934, 82661433933280756441503497801869500397196377459062817609058635274434912526612), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_34() { check(sar(115792089237316195423570985008687907853269984665640564039457584007913129639934, 14420977034312971726267164976326299024771581485143405760981081574949684199148), 0) } + function test_sar_35() { check(sar(82661433933280756441503497801869500397196377459062817609058635274434912526612, 0), 0) } + function test_sar_36() { check(sar(82661433933280756441503497801869500397196377459062817609058635274434912526612, 1), 0) } + function test_sar_37() { check(sar(82661433933280756441503497801869500397196377459062817609058635274434912526612, 2), 0) } + function test_sar_38() { check(sar(82661433933280756441503497801869500397196377459062817609058635274434912526612, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_39() { check(sar(82661433933280756441503497801869500397196377459062817609058635274434912526612, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_40() { check(sar(82661433933280756441503497801869500397196377459062817609058635274434912526612, 82661433933280756441503497801869500397196377459062817609058635274434912526612), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_41() { check(sar(82661433933280756441503497801869500397196377459062817609058635274434912526612, 14420977034312971726267164976326299024771581485143405760981081574949684199148), 0) } + function test_sar_42() { check(sar(14420977034312971726267164976326299024771581485143405760981081574949684199148, 0), 0) } + function test_sar_43() { check(sar(14420977034312971726267164976326299024771581485143405760981081574949684199148, 1), 0) } + function test_sar_44() { check(sar(14420977034312971726267164976326299024771581485143405760981081574949684199148, 2), 0) } + function test_sar_45() { check(sar(14420977034312971726267164976326299024771581485143405760981081574949684199148, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_46() { check(sar(14420977034312971726267164976326299024771581485143405760981081574949684199148, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_47() { check(sar(14420977034312971726267164976326299024771581485143405760981081574949684199148, 82661433933280756441503497801869500397196377459062817609058635274434912526612), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_sar_48() { check(sar(14420977034312971726267164976326299024771581485143405760981081574949684199148, 14420977034312971726267164976326299024771581485143405760981081574949684199148), 0) } + + function test_addmod_0() { check(addmod(88709093666761768322564984656295553746011307663165894036591546278821690745871, 88709093666761768322564984656295553746011307663165894036591546278821690745871, 88709093666761768322564984656295553746011307663165894036591546278821690745871), 0) } + function test_addmod_1() { check(addmod(88709093666761768322564984656295553746011307663165894036591546278821690745871, 88709093666761768322564984656295553746011307663165894036591546278821690745871, 44451158447482934193996014548064287383821425448259097478837643329632131616606), 44064711991074734063141925668398245340558338981554495636670162568746986641924) } + function test_addmod_2() { check(addmod(88709093666761768322564984656295553746011307663165894036591546278821690745871, 88709093666761768322564984656295553746011307663165894036591546278821690745871, 42863450589038489214016709032700434464104295972354769815646893631418872280022), 5964384977369579789063133181789369635605431436912708810595518031967892371654) } + function test_addmod_3() { check(addmod(88709093666761768322564984656295553746011307663165894036591546278821690745871, 88709093666761768322564984656295553746011307663165894036591546278821690745871, 0), 0) } + function test_addmod_4() { check(addmod(88709093666761768322564984656295553746011307663165894036591546278821690745871, 44451158447482934193996014548064287383821425448259097478837643329632131616606, 88709093666761768322564984656295553746011307663165894036591546278821690745871), 44451158447482934193996014548064287383821425448259097478837643329632131616606) } + function test_addmod_5() { check(addmod(88709093666761768322564984656295553746011307663165894036591546278821690745871, 44451158447482934193996014548064287383821425448259097478837643329632131616606, 44451158447482934193996014548064287383821425448259097478837643329632131616606), 44257935219278834128568970108231266362189882214906796557753902949189559129265) } + function test_addmod_6() { check(addmod(88709093666761768322564984656295553746011307663165894036591546278821690745871, 44451158447482934193996014548064287383821425448259097478837643329632131616606, 42863450589038489214016709032700434464104295972354769815646893631418872280022), 4569900347129234874510872106258537737519845194360682068488508714197205522411) } + function test_addmod_7() { check(addmod(88709093666761768322564984656295553746011307663165894036591546278821690745871, 44451158447482934193996014548064287383821425448259097478837643329632131616606, 0), 0) } + function test_addmod_8() { check(addmod(88709093666761768322564984656295553746011307663165894036591546278821690745871, 42863450589038489214016709032700434464104295972354769815646893631418872280022, 88709093666761768322564984656295553746011307663165894036591546278821690745871), 42863450589038489214016709032700434464104295972354769815646893631418872280022) } + function test_addmod_9() { check(addmod(88709093666761768322564984656295553746011307663165894036591546278821690745871, 42863450589038489214016709032700434464104295972354769815646893631418872280022, 44451158447482934193996014548064287383821425448259097478837643329632131616606), 42670227360834389148589664592867413442472752739002468894563153250976299792681) } + function test_addmod_10() { check(addmod(88709093666761768322564984656295553746011307663165894036591546278821690745871, 42863450589038489214016709032700434464104295972354769815646893631418872280022, 42863450589038489214016709032700434464104295972354769815646893631418872280022), 2982192488684789894531566590894684817802715718456354405297759015983946185827) } + function test_addmod_11() { check(addmod(88709093666761768322564984656295553746011307663165894036591546278821690745871, 42863450589038489214016709032700434464104295972354769815646893631418872280022, 0), 0) } + function test_addmod_12() { check(addmod(88709093666761768322564984656295553746011307663165894036591546278821690745871, 0, 88709093666761768322564984656295553746011307663165894036591546278821690745871), 0) } + function test_addmod_13() { check(addmod(88709093666761768322564984656295553746011307663165894036591546278821690745871, 0, 44451158447482934193996014548064287383821425448259097478837643329632131616606), 44257935219278834128568970108231266362189882214906796557753902949189559129265) } + function test_addmod_14() { check(addmod(88709093666761768322564984656295553746011307663165894036591546278821690745871, 0, 42863450589038489214016709032700434464104295972354769815646893631418872280022), 2982192488684789894531566590894684817802715718456354405297759015983946185827) } + function test_addmod_15() { check(addmod(88709093666761768322564984656295553746011307663165894036591546278821690745871, 0, 0), 0) } + function test_addmod_16() { check(addmod(44451158447482934193996014548064287383821425448259097478837643329632131616606, 88709093666761768322564984656295553746011307663165894036591546278821690745871, 88709093666761768322564984656295553746011307663165894036591546278821690745871), 44451158447482934193996014548064287383821425448259097478837643329632131616606) } + function test_addmod_17() { check(addmod(44451158447482934193996014548064287383821425448259097478837643329632131616606, 88709093666761768322564984656295553746011307663165894036591546278821690745871, 44451158447482934193996014548064287383821425448259097478837643329632131616606), 44257935219278834128568970108231266362189882214906796557753902949189559129265) } + function test_addmod_18() { check(addmod(44451158447482934193996014548064287383821425448259097478837643329632131616606, 88709093666761768322564984656295553746011307663165894036591546278821690745871, 42863450589038489214016709032700434464104295972354769815646893631418872280022), 4569900347129234874510872106258537737519845194360682068488508714197205522411) } + function test_addmod_19() { check(addmod(44451158447482934193996014548064287383821425448259097478837643329632131616606, 88709093666761768322564984656295553746011307663165894036591546278821690745871, 0), 0) } + function test_addmod_20() { check(addmod(44451158447482934193996014548064287383821425448259097478837643329632131616606, 44451158447482934193996014548064287383821425448259097478837643329632131616606, 88709093666761768322564984656295553746011307663165894036591546278821690745871), 193223228204100065427044439833021021631543233352300921083740380442572487341) } + function test_addmod_21() { check(addmod(44451158447482934193996014548064287383821425448259097478837643329632131616606, 44451158447482934193996014548064287383821425448259097478837643329632131616606, 44451158447482934193996014548064287383821425448259097478837643329632131616606), 0) } + function test_addmod_22() { check(addmod(44451158447482934193996014548064287383821425448259097478837643329632131616606, 44451158447482934193996014548064287383821425448259097478837643329632131616606, 42863450589038489214016709032700434464104295972354769815646893631418872280022), 3175415716888889959958611030727705839434258951808655326381499396426518673168) } + function test_addmod_23() { check(addmod(44451158447482934193996014548064287383821425448259097478837643329632131616606, 44451158447482934193996014548064287383821425448259097478837643329632131616606, 0), 0) } + function test_addmod_24() { check(addmod(44451158447482934193996014548064287383821425448259097478837643329632131616606, 42863450589038489214016709032700434464104295972354769815646893631418872280022, 88709093666761768322564984656295553746011307663165894036591546278821690745871), 87314609036521423408012723580764721847925721420613867294484536961051003896628) } + function test_addmod_25() { check(addmod(44451158447482934193996014548064287383821425448259097478837643329632131616606, 42863450589038489214016709032700434464104295972354769815646893631418872280022, 44451158447482934193996014548064287383821425448259097478837643329632131616606), 42863450589038489214016709032700434464104295972354769815646893631418872280022) } + function test_addmod_26() { check(addmod(44451158447482934193996014548064287383821425448259097478837643329632131616606, 42863450589038489214016709032700434464104295972354769815646893631418872280022, 42863450589038489214016709032700434464104295972354769815646893631418872280022), 1587707858444444979979305515363852919717129475904327663190749698213259336584) } + function test_addmod_27() { check(addmod(44451158447482934193996014548064287383821425448259097478837643329632131616606, 42863450589038489214016709032700434464104295972354769815646893631418872280022, 0), 0) } + function test_addmod_28() { check(addmod(44451158447482934193996014548064287383821425448259097478837643329632131616606, 0, 88709093666761768322564984656295553746011307663165894036591546278821690745871), 44451158447482934193996014548064287383821425448259097478837643329632131616606) } + function test_addmod_29() { check(addmod(44451158447482934193996014548064287383821425448259097478837643329632131616606, 0, 44451158447482934193996014548064287383821425448259097478837643329632131616606), 0) } + function test_addmod_30() { check(addmod(44451158447482934193996014548064287383821425448259097478837643329632131616606, 0, 42863450589038489214016709032700434464104295972354769815646893631418872280022), 1587707858444444979979305515363852919717129475904327663190749698213259336584) } + function test_addmod_31() { check(addmod(44451158447482934193996014548064287383821425448259097478837643329632131616606, 0, 0), 0) } + function test_addmod_32() { check(addmod(42863450589038489214016709032700434464104295972354769815646893631418872280022, 88709093666761768322564984656295553746011307663165894036591546278821690745871, 88709093666761768322564984656295553746011307663165894036591546278821690745871), 42863450589038489214016709032700434464104295972354769815646893631418872280022) } + function test_addmod_33() { check(addmod(42863450589038489214016709032700434464104295972354769815646893631418872280022, 88709093666761768322564984656295553746011307663165894036591546278821690745871, 44451158447482934193996014548064287383821425448259097478837643329632131616606), 42670227360834389148589664592867413442472752739002468894563153250976299792681) } + function test_addmod_34() { check(addmod(42863450589038489214016709032700434464104295972354769815646893631418872280022, 88709093666761768322564984656295553746011307663165894036591546278821690745871, 42863450589038489214016709032700434464104295972354769815646893631418872280022), 2982192488684789894531566590894684817802715718456354405297759015983946185827) } + function test_addmod_35() { check(addmod(42863450589038489214016709032700434464104295972354769815646893631418872280022, 88709093666761768322564984656295553746011307663165894036591546278821690745871, 0), 0) } + function test_addmod_36() { check(addmod(42863450589038489214016709032700434464104295972354769815646893631418872280022, 44451158447482934193996014548064287383821425448259097478837643329632131616606, 88709093666761768322564984656295553746011307663165894036591546278821690745871), 87314609036521423408012723580764721847925721420613867294484536961051003896628) } + function test_addmod_37() { check(addmod(42863450589038489214016709032700434464104295972354769815646893631418872280022, 44451158447482934193996014548064287383821425448259097478837643329632131616606, 44451158447482934193996014548064287383821425448259097478837643329632131616606), 42863450589038489214016709032700434464104295972354769815646893631418872280022) } + function test_addmod_38() { check(addmod(42863450589038489214016709032700434464104295972354769815646893631418872280022, 44451158447482934193996014548064287383821425448259097478837643329632131616606, 42863450589038489214016709032700434464104295972354769815646893631418872280022), 1587707858444444979979305515363852919717129475904327663190749698213259336584) } + function test_addmod_39() { check(addmod(42863450589038489214016709032700434464104295972354769815646893631418872280022, 44451158447482934193996014548064287383821425448259097478837643329632131616606, 0), 0) } + function test_addmod_40() { check(addmod(42863450589038489214016709032700434464104295972354769815646893631418872280022, 42863450589038489214016709032700434464104295972354769815646893631418872280022, 88709093666761768322564984656295553746011307663165894036591546278821690745871), 85726901178076978428033418065400868928208591944709539631293787262837744560044) } + function test_addmod_41() { check(addmod(42863450589038489214016709032700434464104295972354769815646893631418872280022, 42863450589038489214016709032700434464104295972354769815646893631418872280022, 44451158447482934193996014548064287383821425448259097478837643329632131616606), 41275742730594044234037403517336581544387166496450442152456143933205612943438) } + function test_addmod_42() { check(addmod(42863450589038489214016709032700434464104295972354769815646893631418872280022, 42863450589038489214016709032700434464104295972354769815646893631418872280022, 42863450589038489214016709032700434464104295972354769815646893631418872280022), 0) } + function test_addmod_43() { check(addmod(42863450589038489214016709032700434464104295972354769815646893631418872280022, 42863450589038489214016709032700434464104295972354769815646893631418872280022, 0), 0) } + function test_addmod_44() { check(addmod(42863450589038489214016709032700434464104295972354769815646893631418872280022, 0, 88709093666761768322564984656295553746011307663165894036591546278821690745871), 42863450589038489214016709032700434464104295972354769815646893631418872280022) } + function test_addmod_45() { check(addmod(42863450589038489214016709032700434464104295972354769815646893631418872280022, 0, 44451158447482934193996014548064287383821425448259097478837643329632131616606), 42863450589038489214016709032700434464104295972354769815646893631418872280022) } + function test_addmod_46() { check(addmod(42863450589038489214016709032700434464104295972354769815646893631418872280022, 0, 42863450589038489214016709032700434464104295972354769815646893631418872280022), 0) } + function test_addmod_47() { check(addmod(42863450589038489214016709032700434464104295972354769815646893631418872280022, 0, 0), 0) } + function test_addmod_48() { check(addmod(0, 88709093666761768322564984656295553746011307663165894036591546278821690745871, 88709093666761768322564984656295553746011307663165894036591546278821690745871), 0) } + function test_addmod_49() { check(addmod(0, 88709093666761768322564984656295553746011307663165894036591546278821690745871, 44451158447482934193996014548064287383821425448259097478837643329632131616606), 44257935219278834128568970108231266362189882214906796557753902949189559129265) } + function test_addmod_50() { check(addmod(0, 88709093666761768322564984656295553746011307663165894036591546278821690745871, 42863450589038489214016709032700434464104295972354769815646893631418872280022), 2982192488684789894531566590894684817802715718456354405297759015983946185827) } + function test_addmod_51() { check(addmod(0, 88709093666761768322564984656295553746011307663165894036591546278821690745871, 0), 0) } + function test_addmod_52() { check(addmod(0, 44451158447482934193996014548064287383821425448259097478837643329632131616606, 88709093666761768322564984656295553746011307663165894036591546278821690745871), 44451158447482934193996014548064287383821425448259097478837643329632131616606) } + function test_addmod_53() { check(addmod(0, 44451158447482934193996014548064287383821425448259097478837643329632131616606, 44451158447482934193996014548064287383821425448259097478837643329632131616606), 0) } + function test_addmod_54() { check(addmod(0, 44451158447482934193996014548064287383821425448259097478837643329632131616606, 42863450589038489214016709032700434464104295972354769815646893631418872280022), 1587707858444444979979305515363852919717129475904327663190749698213259336584) } + function test_addmod_55() { check(addmod(0, 44451158447482934193996014548064287383821425448259097478837643329632131616606, 0), 0) } + function test_addmod_56() { check(addmod(0, 42863450589038489214016709032700434464104295972354769815646893631418872280022, 88709093666761768322564984656295553746011307663165894036591546278821690745871), 42863450589038489214016709032700434464104295972354769815646893631418872280022) } + function test_addmod_57() { check(addmod(0, 42863450589038489214016709032700434464104295972354769815646893631418872280022, 44451158447482934193996014548064287383821425448259097478837643329632131616606), 42863450589038489214016709032700434464104295972354769815646893631418872280022) } + function test_addmod_58() { check(addmod(0, 42863450589038489214016709032700434464104295972354769815646893631418872280022, 42863450589038489214016709032700434464104295972354769815646893631418872280022), 0) } + function test_addmod_59() { check(addmod(0, 42863450589038489214016709032700434464104295972354769815646893631418872280022, 0), 0) } + function test_addmod_60() { check(addmod(0, 0, 88709093666761768322564984656295553746011307663165894036591546278821690745871), 0) } + function test_addmod_61() { check(addmod(0, 0, 44451158447482934193996014548064287383821425448259097478837643329632131616606), 0) } + function test_addmod_62() { check(addmod(0, 0, 42863450589038489214016709032700434464104295972354769815646893631418872280022), 0) } + function test_addmod_63() { check(addmod(0, 0, 0), 0) } + + function test_mulmod_0() { check(mulmod(16276669522384486338889180648183030066755182847217443080768578804831749401628, 16276669522384486338889180648183030066755182847217443080768578804831749401628, 16276669522384486338889180648183030066755182847217443080768578804831749401628), 0) } + function test_mulmod_1() { check(mulmod(16276669522384486338889180648183030066755182847217443080768578804831749401628, 16276669522384486338889180648183030066755182847217443080768578804831749401628, 61255369845337909531357383249661018806600642830892900657424556972616011860017), 23176262005655255446619359110129527035459439612185431273098370546916359809784) } + function test_mulmod_2() { check(mulmod(16276669522384486338889180648183030066755182847217443080768578804831749401628, 16276669522384486338889180648183030066755182847217443080768578804831749401628, 67592269495322012340487158052845183801991789236173000628299730722890671725711), 3064413551412437379643402604175968711223346206174540482441154607878557113688) } + function test_mulmod_3() { check(mulmod(16276669522384486338889180648183030066755182847217443080768578804831749401628, 16276669522384486338889180648183030066755182847217443080768578804831749401628, 0), 0) } + function test_mulmod_4() { check(mulmod(16276669522384486338889180648183030066755182847217443080768578804831749401628, 61255369845337909531357383249661018806600642830892900657424556972616011860017, 16276669522384486338889180648183030066755182847217443080768578804831749401628), 0) } + function test_mulmod_5() { check(mulmod(16276669522384486338889180648183030066755182847217443080768578804831749401628, 61255369845337909531357383249661018806600642830892900657424556972616011860017, 61255369845337909531357383249661018806600642830892900657424556972616011860017), 0) } + function test_mulmod_6() { check(mulmod(16276669522384486338889180648183030066755182847217443080768578804831749401628, 61255369845337909531357383249661018806600642830892900657424556972616011860017, 67592269495322012340487158052845183801991789236173000628299730722890671725711), 26273319191600029136698077734670861513821018779504641911485538517341065862878) } + function test_mulmod_7() { check(mulmod(16276669522384486338889180648183030066755182847217443080768578804831749401628, 61255369845337909531357383249661018806600642830892900657424556972616011860017, 0), 0) } + function test_mulmod_8() { check(mulmod(16276669522384486338889180648183030066755182847217443080768578804831749401628, 67592269495322012340487158052845183801991789236173000628299730722890671725711, 16276669522384486338889180648183030066755182847217443080768578804831749401628), 0) } + function test_mulmod_9() { check(mulmod(16276669522384486338889180648183030066755182847217443080768578804831749401628, 67592269495322012340487158052845183801991789236173000628299730722890671725711, 61255369845337909531357383249661018806600642830892900657424556972616011860017), 14157633310473631021856837273480583446391162130909985860868842352910678494940) } + function test_mulmod_10() { check(mulmod(16276669522384486338889180648183030066755182847217443080768578804831749401628, 67592269495322012340487158052845183801991789236173000628299730722890671725711, 67592269495322012340487158052845183801991789236173000628299730722890671725711), 0) } + function test_mulmod_11() { check(mulmod(16276669522384486338889180648183030066755182847217443080768578804831749401628, 67592269495322012340487158052845183801991789236173000628299730722890671725711, 0), 0) } + function test_mulmod_12() { check(mulmod(16276669522384486338889180648183030066755182847217443080768578804831749401628, 0, 16276669522384486338889180648183030066755182847217443080768578804831749401628), 0) } + function test_mulmod_13() { check(mulmod(16276669522384486338889180648183030066755182847217443080768578804831749401628, 0, 61255369845337909531357383249661018806600642830892900657424556972616011860017), 0) } + function test_mulmod_14() { check(mulmod(16276669522384486338889180648183030066755182847217443080768578804831749401628, 0, 67592269495322012340487158052845183801991789236173000628299730722890671725711), 0) } + function test_mulmod_15() { check(mulmod(16276669522384486338889180648183030066755182847217443080768578804831749401628, 0, 0), 0) } + function test_mulmod_16() { check(mulmod(61255369845337909531357383249661018806600642830892900657424556972616011860017, 16276669522384486338889180648183030066755182847217443080768578804831749401628, 16276669522384486338889180648183030066755182847217443080768578804831749401628), 0) } + function test_mulmod_17() { check(mulmod(61255369845337909531357383249661018806600642830892900657424556972616011860017, 16276669522384486338889180648183030066755182847217443080768578804831749401628, 61255369845337909531357383249661018806600642830892900657424556972616011860017), 0) } + function test_mulmod_18() { check(mulmod(61255369845337909531357383249661018806600642830892900657424556972616011860017, 16276669522384486338889180648183030066755182847217443080768578804831749401628, 67592269495322012340487158052845183801991789236173000628299730722890671725711), 26273319191600029136698077734670861513821018779504641911485538517341065862878) } + function test_mulmod_19() { check(mulmod(61255369845337909531357383249661018806600642830892900657424556972616011860017, 16276669522384486338889180648183030066755182847217443080768578804831749401628, 0), 0) } + function test_mulmod_20() { check(mulmod(61255369845337909531357383249661018806600642830892900657424556972616011860017, 61255369845337909531357383249661018806600642830892900657424556972616011860017, 16276669522384486338889180648183030066755182847217443080768578804831749401628), 10264553014886949099456832205662211287802170691660629981149545306256743595357) } + function test_mulmod_21() { check(mulmod(61255369845337909531357383249661018806600642830892900657424556972616011860017, 61255369845337909531357383249661018806600642830892900657424556972616011860017, 61255369845337909531357383249661018806600642830892900657424556972616011860017), 0) } + function test_mulmod_22() { check(mulmod(61255369845337909531357383249661018806600642830892900657424556972616011860017, 61255369845337909531357383249661018806600642830892900657424556972616011860017, 67592269495322012340487158052845183801991789236173000628299730722890671725711), 40376042472371261823328543819007916619907748689918933898580231748226231028508) } + function test_mulmod_23() { check(mulmod(61255369845337909531357383249661018806600642830892900657424556972616011860017, 61255369845337909531357383249661018806600642830892900657424556972616011860017, 0), 0) } + function test_mulmod_24() { check(mulmod(61255369845337909531357383249661018806600642830892900657424556972616011860017, 67592269495322012340487158052845183801991789236173000628299730722890671725711, 16276669522384486338889180648183030066755182847217443080768578804831749401628), 121166042667900601775491320570584362863069218419613427774684657728630002551) } + function test_mulmod_25() { check(mulmod(61255369845337909531357383249661018806600642830892900657424556972616011860017, 67592269495322012340487158052845183801991789236173000628299730722890671725711, 61255369845337909531357383249661018806600642830892900657424556972616011860017), 0) } + function test_mulmod_26() { check(mulmod(61255369845337909531357383249661018806600642830892900657424556972616011860017, 67592269495322012340487158052845183801991789236173000628299730722890671725711, 67592269495322012340487158052845183801991789236173000628299730722890671725711), 0) } + function test_mulmod_27() { check(mulmod(61255369845337909531357383249661018806600642830892900657424556972616011860017, 67592269495322012340487158052845183801991789236173000628299730722890671725711, 0), 0) } + function test_mulmod_28() { check(mulmod(61255369845337909531357383249661018806600642830892900657424556972616011860017, 0, 16276669522384486338889180648183030066755182847217443080768578804831749401628), 0) } + function test_mulmod_29() { check(mulmod(61255369845337909531357383249661018806600642830892900657424556972616011860017, 0, 61255369845337909531357383249661018806600642830892900657424556972616011860017), 0) } + function test_mulmod_30() { check(mulmod(61255369845337909531357383249661018806600642830892900657424556972616011860017, 0, 67592269495322012340487158052845183801991789236173000628299730722890671725711), 0) } + function test_mulmod_31() { check(mulmod(61255369845337909531357383249661018806600642830892900657424556972616011860017, 0, 0), 0) } + function test_mulmod_32() { check(mulmod(67592269495322012340487158052845183801991789236173000628299730722890671725711, 16276669522384486338889180648183030066755182847217443080768578804831749401628, 16276669522384486338889180648183030066755182847217443080768578804831749401628), 0) } + function test_mulmod_33() { check(mulmod(67592269495322012340487158052845183801991789236173000628299730722890671725711, 16276669522384486338889180648183030066755182847217443080768578804831749401628, 61255369845337909531357383249661018806600642830892900657424556972616011860017), 14157633310473631021856837273480583446391162130909985860868842352910678494940) } + function test_mulmod_34() { check(mulmod(67592269495322012340487158052845183801991789236173000628299730722890671725711, 16276669522384486338889180648183030066755182847217443080768578804831749401628, 67592269495322012340487158052845183801991789236173000628299730722890671725711), 0) } + function test_mulmod_35() { check(mulmod(67592269495322012340487158052845183801991789236173000628299730722890671725711, 16276669522384486338889180648183030066755182847217443080768578804831749401628, 0), 0) } + function test_mulmod_36() { check(mulmod(67592269495322012340487158052845183801991789236173000628299730722890671725711, 61255369845337909531357383249661018806600642830892900657424556972616011860017, 16276669522384486338889180648183030066755182847217443080768578804831749401628), 121166042667900601775491320570584362863069218419613427774684657728630002551) } + function test_mulmod_37() { check(mulmod(67592269495322012340487158052845183801991789236173000628299730722890671725711, 61255369845337909531357383249661018806600642830892900657424556972616011860017, 61255369845337909531357383249661018806600642830892900657424556972616011860017), 0) } + function test_mulmod_38() { check(mulmod(67592269495322012340487158052845183801991789236173000628299730722890671725711, 61255369845337909531357383249661018806600642830892900657424556972616011860017, 67592269495322012340487158052845183801991789236173000628299730722890671725711), 0) } + function test_mulmod_39() { check(mulmod(67592269495322012340487158052845183801991789236173000628299730722890671725711, 61255369845337909531357383249661018806600642830892900657424556972616011860017, 0), 0) } + function test_mulmod_40() { check(mulmod(67592269495322012340487158052845183801991789236173000628299730722890671725711, 67592269495322012340487158052845183801991789236173000628299730722890671725711, 16276669522384486338889180648183030066755182847217443080768578804831749401628), 11598696862827562854335940060986693325168146814706863022727054740069022270965) } + function test_mulmod_41() { check(mulmod(67592269495322012340487158052845183801991789236173000628299730722890671725711, 67592269495322012340487158052845183801991789236173000628299730722890671725711, 61255369845337909531357383249661018806600642830892900657424556972616011860017), 59313540545305335696306027808474459684036927815722086527493987744136766311788) } + function test_mulmod_42() { check(mulmod(67592269495322012340487158052845183801991789236173000628299730722890671725711, 67592269495322012340487158052845183801991789236173000628299730722890671725711, 67592269495322012340487158052845183801991789236173000628299730722890671725711), 0) } + function test_mulmod_43() { check(mulmod(67592269495322012340487158052845183801991789236173000628299730722890671725711, 67592269495322012340487158052845183801991789236173000628299730722890671725711, 0), 0) } + function test_mulmod_44() { check(mulmod(67592269495322012340487158052845183801991789236173000628299730722890671725711, 0, 16276669522384486338889180648183030066755182847217443080768578804831749401628), 0) } + function test_mulmod_45() { check(mulmod(67592269495322012340487158052845183801991789236173000628299730722890671725711, 0, 61255369845337909531357383249661018806600642830892900657424556972616011860017), 0) } + function test_mulmod_46() { check(mulmod(67592269495322012340487158052845183801991789236173000628299730722890671725711, 0, 67592269495322012340487158052845183801991789236173000628299730722890671725711), 0) } + function test_mulmod_47() { check(mulmod(67592269495322012340487158052845183801991789236173000628299730722890671725711, 0, 0), 0) } + function test_mulmod_48() { check(mulmod(0, 16276669522384486338889180648183030066755182847217443080768578804831749401628, 16276669522384486338889180648183030066755182847217443080768578804831749401628), 0) } + function test_mulmod_49() { check(mulmod(0, 16276669522384486338889180648183030066755182847217443080768578804831749401628, 61255369845337909531357383249661018806600642830892900657424556972616011860017), 0) } + function test_mulmod_50() { check(mulmod(0, 16276669522384486338889180648183030066755182847217443080768578804831749401628, 67592269495322012340487158052845183801991789236173000628299730722890671725711), 0) } + function test_mulmod_51() { check(mulmod(0, 16276669522384486338889180648183030066755182847217443080768578804831749401628, 0), 0) } + function test_mulmod_52() { check(mulmod(0, 61255369845337909531357383249661018806600642830892900657424556972616011860017, 16276669522384486338889180648183030066755182847217443080768578804831749401628), 0) } + function test_mulmod_53() { check(mulmod(0, 61255369845337909531357383249661018806600642830892900657424556972616011860017, 61255369845337909531357383249661018806600642830892900657424556972616011860017), 0) } + function test_mulmod_54() { check(mulmod(0, 61255369845337909531357383249661018806600642830892900657424556972616011860017, 67592269495322012340487158052845183801991789236173000628299730722890671725711), 0) } + function test_mulmod_55() { check(mulmod(0, 61255369845337909531357383249661018806600642830892900657424556972616011860017, 0), 0) } + function test_mulmod_56() { check(mulmod(0, 67592269495322012340487158052845183801991789236173000628299730722890671725711, 16276669522384486338889180648183030066755182847217443080768578804831749401628), 0) } + function test_mulmod_57() { check(mulmod(0, 67592269495322012340487158052845183801991789236173000628299730722890671725711, 61255369845337909531357383249661018806600642830892900657424556972616011860017), 0) } + function test_mulmod_58() { check(mulmod(0, 67592269495322012340487158052845183801991789236173000628299730722890671725711, 67592269495322012340487158052845183801991789236173000628299730722890671725711), 0) } + function test_mulmod_59() { check(mulmod(0, 67592269495322012340487158052845183801991789236173000628299730722890671725711, 0), 0) } + function test_mulmod_60() { check(mulmod(0, 0, 16276669522384486338889180648183030066755182847217443080768578804831749401628), 0) } + function test_mulmod_61() { check(mulmod(0, 0, 61255369845337909531357383249661018806600642830892900657424556972616011860017), 0) } + function test_mulmod_62() { check(mulmod(0, 0, 67592269495322012340487158052845183801991789236173000628299730722890671725711), 0) } + function test_mulmod_63() { check(mulmod(0, 0, 0), 0) } + + function test_signextend_0() { check(signextend(0, 0), 0) } + function test_signextend_1() { check(signextend(0, 1), 1) } + function test_signextend_2() { check(signextend(0, 2), 2) } + function test_signextend_3() { check(signextend(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_signextend_4() { check(signextend(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_signextend_5() { check(signextend(0, 45226673911494330638004017861787702005823510899832444576649689288606038125012), 115792089237316195423570985008687907853269984665640564039457584007913129639892) } + function test_signextend_6() { check(signextend(0, 104679649160658165931730490444266492838683600858729223011136025312331610417801), 115792089237316195423570985008687907853269984665640564039457584007913129639817) } + function test_signextend_7() { check(signextend(1, 0), 0) } + function test_signextend_8() { check(signextend(1, 1), 1) } + function test_signextend_9() { check(signextend(1, 2), 2) } + function test_signextend_10() { check(signextend(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_signextend_11() { check(signextend(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_signextend_12() { check(signextend(1, 45226673911494330638004017861787702005823510899832444576649689288606038125012), 27092) } + function test_signextend_13() { check(signextend(1, 104679649160658165931730490444266492838683600858729223011136025312331610417801), 27273) } + function test_signextend_14() { check(signextend(2, 0), 0) } + function test_signextend_15() { check(signextend(2, 1), 1) } + function test_signextend_16() { check(signextend(2, 2), 2) } + function test_signextend_17() { check(signextend(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_signextend_18() { check(signextend(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_signextend_19() { check(signextend(2, 45226673911494330638004017861787702005823510899832444576649689288606038125012), 2386388) } + function test_signextend_20() { check(signextend(2, 104679649160658165931730490444266492838683600858729223011136025312331610417801), 1272457) } + function test_signextend_21() { check(signextend(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0), 0) } + function test_signextend_22() { check(signextend(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1), 1) } + function test_signextend_23() { check(signextend(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2), 2) } + function test_signextend_24() { check(signextend(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_signextend_25() { check(signextend(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_signextend_26() { check(signextend(115792089237316195423570985008687907853269984665640564039457584007913129639935, 45226673911494330638004017861787702005823510899832444576649689288606038125012), 45226673911494330638004017861787702005823510899832444576649689288606038125012) } + function test_signextend_27() { check(signextend(115792089237316195423570985008687907853269984665640564039457584007913129639935, 104679649160658165931730490444266492838683600858729223011136025312331610417801), 104679649160658165931730490444266492838683600858729223011136025312331610417801) } + function test_signextend_28() { check(signextend(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0), 0) } + function test_signextend_29() { check(signextend(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1), 1) } + function test_signextend_30() { check(signextend(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2), 2) } + function test_signextend_31() { check(signextend(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_signextend_32() { check(signextend(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_signextend_33() { check(signextend(115792089237316195423570985008687907853269984665640564039457584007913129639934, 45226673911494330638004017861787702005823510899832444576649689288606038125012), 45226673911494330638004017861787702005823510899832444576649689288606038125012) } + function test_signextend_34() { check(signextend(115792089237316195423570985008687907853269984665640564039457584007913129639934, 104679649160658165931730490444266492838683600858729223011136025312331610417801), 104679649160658165931730490444266492838683600858729223011136025312331610417801) } + function test_signextend_35() { check(signextend(45226673911494330638004017861787702005823510899832444576649689288606038125012, 0), 0) } + function test_signextend_36() { check(signextend(45226673911494330638004017861787702005823510899832444576649689288606038125012, 1), 1) } + function test_signextend_37() { check(signextend(45226673911494330638004017861787702005823510899832444576649689288606038125012, 2), 2) } + function test_signextend_38() { check(signextend(45226673911494330638004017861787702005823510899832444576649689288606038125012, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_signextend_39() { check(signextend(45226673911494330638004017861787702005823510899832444576649689288606038125012, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_signextend_40() { check(signextend(45226673911494330638004017861787702005823510899832444576649689288606038125012, 45226673911494330638004017861787702005823510899832444576649689288606038125012), 45226673911494330638004017861787702005823510899832444576649689288606038125012) } + function test_signextend_41() { check(signextend(45226673911494330638004017861787702005823510899832444576649689288606038125012, 104679649160658165931730490444266492838683600858729223011136025312331610417801), 104679649160658165931730490444266492838683600858729223011136025312331610417801) } + function test_signextend_42() { check(signextend(104679649160658165931730490444266492838683600858729223011136025312331610417801, 0), 0) } + function test_signextend_43() { check(signextend(104679649160658165931730490444266492838683600858729223011136025312331610417801, 1), 1) } + function test_signextend_44() { check(signextend(104679649160658165931730490444266492838683600858729223011136025312331610417801, 2), 2) } + function test_signextend_45() { check(signextend(104679649160658165931730490444266492838683600858729223011136025312331610417801, 115792089237316195423570985008687907853269984665640564039457584007913129639935), 115792089237316195423570985008687907853269984665640564039457584007913129639935) } + function test_signextend_46() { check(signextend(104679649160658165931730490444266492838683600858729223011136025312331610417801, 115792089237316195423570985008687907853269984665640564039457584007913129639934), 115792089237316195423570985008687907853269984665640564039457584007913129639934) } + function test_signextend_47() { check(signextend(104679649160658165931730490444266492838683600858729223011136025312331610417801, 45226673911494330638004017861787702005823510899832444576649689288606038125012), 45226673911494330638004017861787702005823510899832444576649689288606038125012) } + function test_signextend_48() { check(signextend(104679649160658165931730490444266492838683600858729223011136025312331610417801, 104679649160658165931730490444266492838683600858729223011136025312331610417801), 104679649160658165931730490444266492838683600858729223011136025312331610417801) } + +} +// ---- +// step: constantFunctionEvaluator +// +// { +// function check(a, b) +// { +// if iszero(eq(a, b)) { revert(0, 0) } +// } +// function test_add_0() +// { } +// function test_add_1() +// { } +// function test_add_2() +// { } +// function test_add_3() +// { } +// function test_add_4() +// { } +// function test_add_5() +// { } +// function test_add_6() +// { } +// function test_add_7() +// { } +// function test_add_8() +// { } +// function test_add_9() +// { } +// function test_add_10() +// { } +// function test_add_11() +// { } +// function test_add_12() +// { } +// function test_add_13() +// { } +// function test_add_14() +// { } +// function test_add_15() +// { } +// function test_add_16() +// { } +// function test_add_17() +// { } +// function test_add_18() +// { } +// function test_add_19() +// { } +// function test_add_20() +// { } +// function test_add_21() +// { } +// function test_add_22() +// { } +// function test_add_23() +// { } +// function test_add_24() +// { } +// function test_add_25() +// { } +// function test_add_26() +// { } +// function test_add_27() +// { } +// function test_add_28() +// { } +// function test_add_29() +// { } +// function test_add_30() +// { } +// function test_add_31() +// { } +// function test_add_32() +// { } +// function test_add_33() +// { } +// function test_add_34() +// { } +// function test_add_35() +// { } +// function test_add_36() +// { } +// function test_add_37() +// { } +// function test_add_38() +// { } +// function test_add_39() +// { } +// function test_add_40() +// { } +// function test_add_41() +// { } +// function test_add_42() +// { } +// function test_add_43() +// { } +// function test_add_44() +// { } +// function test_add_45() +// { } +// function test_add_46() +// { } +// function test_add_47() +// { } +// function test_add_48() +// { } +// function test_mul_0() +// { } +// function test_mul_1() +// { } +// function test_mul_2() +// { } +// function test_mul_3() +// { } +// function test_mul_4() +// { } +// function test_mul_5() +// { } +// function test_mul_6() +// { } +// function test_mul_7() +// { } +// function test_mul_8() +// { } +// function test_mul_9() +// { } +// function test_mul_10() +// { } +// function test_mul_11() +// { } +// function test_mul_12() +// { } +// function test_mul_13() +// { } +// function test_mul_14() +// { } +// function test_mul_15() +// { } +// function test_mul_16() +// { } +// function test_mul_17() +// { } +// function test_mul_18() +// { } +// function test_mul_19() +// { } +// function test_mul_20() +// { } +// function test_mul_21() +// { } +// function test_mul_22() +// { } +// function test_mul_23() +// { } +// function test_mul_24() +// { } +// function test_mul_25() +// { } +// function test_mul_26() +// { } +// function test_mul_27() +// { } +// function test_mul_28() +// { } +// function test_mul_29() +// { } +// function test_mul_30() +// { } +// function test_mul_31() +// { } +// function test_mul_32() +// { } +// function test_mul_33() +// { } +// function test_mul_34() +// { } +// function test_mul_35() +// { } +// function test_mul_36() +// { } +// function test_mul_37() +// { } +// function test_mul_38() +// { } +// function test_mul_39() +// { } +// function test_mul_40() +// { } +// function test_mul_41() +// { } +// function test_mul_42() +// { } +// function test_mul_43() +// { } +// function test_mul_44() +// { } +// function test_mul_45() +// { } +// function test_mul_46() +// { } +// function test_mul_47() +// { } +// function test_mul_48() +// { } +// function test_sub_0() +// { } +// function test_sub_1() +// { } +// function test_sub_2() +// { } +// function test_sub_3() +// { } +// function test_sub_4() +// { } +// function test_sub_5() +// { } +// function test_sub_6() +// { } +// function test_sub_7() +// { } +// function test_sub_8() +// { } +// function test_sub_9() +// { } +// function test_sub_10() +// { } +// function test_sub_11() +// { } +// function test_sub_12() +// { } +// function test_sub_13() +// { } +// function test_sub_14() +// { } +// function test_sub_15() +// { } +// function test_sub_16() +// { } +// function test_sub_17() +// { } +// function test_sub_18() +// { } +// function test_sub_19() +// { } +// function test_sub_20() +// { } +// function test_sub_21() +// { } +// function test_sub_22() +// { } +// function test_sub_23() +// { } +// function test_sub_24() +// { } +// function test_sub_25() +// { } +// function test_sub_26() +// { } +// function test_sub_27() +// { } +// function test_sub_28() +// { } +// function test_sub_29() +// { } +// function test_sub_30() +// { } +// function test_sub_31() +// { } +// function test_sub_32() +// { } +// function test_sub_33() +// { } +// function test_sub_34() +// { } +// function test_sub_35() +// { } +// function test_sub_36() +// { } +// function test_sub_37() +// { } +// function test_sub_38() +// { } +// function test_sub_39() +// { } +// function test_sub_40() +// { } +// function test_sub_41() +// { } +// function test_sub_42() +// { } +// function test_sub_43() +// { } +// function test_sub_44() +// { } +// function test_sub_45() +// { } +// function test_sub_46() +// { } +// function test_sub_47() +// { } +// function test_sub_48() +// { } +// function test_div_0() +// { } +// function test_div_1() +// { } +// function test_div_2() +// { } +// function test_div_3() +// { } +// function test_div_4() +// { } +// function test_div_5() +// { } +// function test_div_6() +// { } +// function test_div_7() +// { } +// function test_div_8() +// { } +// function test_div_9() +// { } +// function test_div_10() +// { } +// function test_div_11() +// { } +// function test_div_12() +// { } +// function test_div_13() +// { } +// function test_div_14() +// { } +// function test_div_15() +// { } +// function test_div_16() +// { } +// function test_div_17() +// { } +// function test_div_18() +// { } +// function test_div_19() +// { } +// function test_div_20() +// { } +// function test_div_21() +// { } +// function test_div_22() +// { } +// function test_div_23() +// { } +// function test_div_24() +// { } +// function test_div_25() +// { } +// function test_div_26() +// { } +// function test_div_27() +// { } +// function test_div_28() +// { } +// function test_div_29() +// { } +// function test_div_30() +// { } +// function test_div_31() +// { } +// function test_div_32() +// { } +// function test_div_33() +// { } +// function test_div_34() +// { } +// function test_div_35() +// { } +// function test_div_36() +// { } +// function test_div_37() +// { } +// function test_div_38() +// { } +// function test_div_39() +// { } +// function test_div_40() +// { } +// function test_div_41() +// { } +// function test_div_42() +// { } +// function test_div_43() +// { } +// function test_div_44() +// { } +// function test_div_45() +// { } +// function test_div_46() +// { } +// function test_div_47() +// { } +// function test_div_48() +// { } +// function test_sdiv_0() +// { } +// function test_sdiv_1() +// { } +// function test_sdiv_2() +// { } +// function test_sdiv_3() +// { } +// function test_sdiv_4() +// { } +// function test_sdiv_5() +// { } +// function test_sdiv_6() +// { } +// function test_sdiv_7() +// { } +// function test_sdiv_8() +// { } +// function test_sdiv_9() +// { } +// function test_sdiv_10() +// { } +// function test_sdiv_11() +// { } +// function test_sdiv_12() +// { } +// function test_sdiv_13() +// { } +// function test_sdiv_14() +// { } +// function test_sdiv_15() +// { } +// function test_sdiv_16() +// { } +// function test_sdiv_17() +// { } +// function test_sdiv_18() +// { } +// function test_sdiv_19() +// { } +// function test_sdiv_20() +// { } +// function test_sdiv_21() +// { } +// function test_sdiv_22() +// { } +// function test_sdiv_23() +// { } +// function test_sdiv_24() +// { } +// function test_sdiv_25() +// { } +// function test_sdiv_26() +// { } +// function test_sdiv_27() +// { } +// function test_sdiv_28() +// { } +// function test_sdiv_29() +// { } +// function test_sdiv_30() +// { } +// function test_sdiv_31() +// { } +// function test_sdiv_32() +// { } +// function test_sdiv_33() +// { } +// function test_sdiv_34() +// { } +// function test_sdiv_35() +// { } +// function test_sdiv_36() +// { } +// function test_sdiv_37() +// { } +// function test_sdiv_38() +// { } +// function test_sdiv_39() +// { } +// function test_sdiv_40() +// { } +// function test_sdiv_41() +// { } +// function test_sdiv_42() +// { } +// function test_sdiv_43() +// { } +// function test_sdiv_44() +// { } +// function test_sdiv_45() +// { } +// function test_sdiv_46() +// { } +// function test_sdiv_47() +// { } +// function test_sdiv_48() +// { } +// function test_mod_0() +// { } +// function test_mod_1() +// { } +// function test_mod_2() +// { } +// function test_mod_3() +// { } +// function test_mod_4() +// { } +// function test_mod_5() +// { } +// function test_mod_6() +// { } +// function test_mod_7() +// { } +// function test_mod_8() +// { } +// function test_mod_9() +// { } +// function test_mod_10() +// { } +// function test_mod_11() +// { } +// function test_mod_12() +// { } +// function test_mod_13() +// { } +// function test_mod_14() +// { } +// function test_mod_15() +// { } +// function test_mod_16() +// { } +// function test_mod_17() +// { } +// function test_mod_18() +// { } +// function test_mod_19() +// { } +// function test_mod_20() +// { } +// function test_mod_21() +// { } +// function test_mod_22() +// { } +// function test_mod_23() +// { } +// function test_mod_24() +// { } +// function test_mod_25() +// { } +// function test_mod_26() +// { } +// function test_mod_27() +// { } +// function test_mod_28() +// { } +// function test_mod_29() +// { } +// function test_mod_30() +// { } +// function test_mod_31() +// { } +// function test_mod_32() +// { } +// function test_mod_33() +// { } +// function test_mod_34() +// { } +// function test_mod_35() +// { } +// function test_mod_36() +// { } +// function test_mod_37() +// { } +// function test_mod_38() +// { } +// function test_mod_39() +// { } +// function test_mod_40() +// { } +// function test_mod_41() +// { } +// function test_mod_42() +// { } +// function test_mod_43() +// { } +// function test_mod_44() +// { } +// function test_mod_45() +// { } +// function test_mod_46() +// { } +// function test_mod_47() +// { } +// function test_mod_48() +// { } +// function test_smod_0() +// { } +// function test_smod_1() +// { } +// function test_smod_2() +// { } +// function test_smod_3() +// { } +// function test_smod_4() +// { } +// function test_smod_5() +// { } +// function test_smod_6() +// { } +// function test_smod_7() +// { } +// function test_smod_8() +// { } +// function test_smod_9() +// { } +// function test_smod_10() +// { } +// function test_smod_11() +// { } +// function test_smod_12() +// { } +// function test_smod_13() +// { } +// function test_smod_14() +// { } +// function test_smod_15() +// { } +// function test_smod_16() +// { } +// function test_smod_17() +// { } +// function test_smod_18() +// { } +// function test_smod_19() +// { } +// function test_smod_20() +// { } +// function test_smod_21() +// { } +// function test_smod_22() +// { } +// function test_smod_23() +// { } +// function test_smod_24() +// { } +// function test_smod_25() +// { } +// function test_smod_26() +// { } +// function test_smod_27() +// { } +// function test_smod_28() +// { } +// function test_smod_29() +// { } +// function test_smod_30() +// { } +// function test_smod_31() +// { } +// function test_smod_32() +// { } +// function test_smod_33() +// { } +// function test_smod_34() +// { } +// function test_smod_35() +// { } +// function test_smod_36() +// { } +// function test_smod_37() +// { } +// function test_smod_38() +// { } +// function test_smod_39() +// { } +// function test_smod_40() +// { } +// function test_smod_41() +// { } +// function test_smod_42() +// { } +// function test_smod_43() +// { } +// function test_smod_44() +// { } +// function test_smod_45() +// { } +// function test_smod_46() +// { } +// function test_smod_47() +// { } +// function test_smod_48() +// { } +// function test_exp_0() +// { } +// function test_exp_1() +// { } +// function test_exp_2() +// { } +// function test_exp_3() +// { } +// function test_exp_4() +// { } +// function test_exp_5() +// { } +// function test_exp_6() +// { } +// function test_exp_7() +// { } +// function test_exp_8() +// { } +// function test_exp_9() +// { } +// function test_exp_10() +// { } +// function test_exp_11() +// { } +// function test_exp_12() +// { } +// function test_exp_13() +// { } +// function test_exp_14() +// { } +// function test_exp_15() +// { } +// function test_exp_16() +// { } +// function test_exp_17() +// { } +// function test_exp_18() +// { } +// function test_exp_19() +// { } +// function test_exp_20() +// { } +// function test_exp_21() +// { } +// function test_exp_22() +// { } +// function test_exp_23() +// { } +// function test_exp_24() +// { } +// function test_exp_25() +// { } +// function test_exp_26() +// { } +// function test_exp_27() +// { } +// function test_exp_28() +// { } +// function test_exp_29() +// { } +// function test_exp_30() +// { } +// function test_exp_31() +// { } +// function test_exp_32() +// { } +// function test_exp_33() +// { } +// function test_exp_34() +// { } +// function test_exp_35() +// { } +// function test_exp_36() +// { } +// function test_exp_37() +// { } +// function test_exp_38() +// { } +// function test_exp_39() +// { } +// function test_exp_40() +// { } +// function test_exp_41() +// { } +// function test_exp_42() +// { } +// function test_exp_43() +// { } +// function test_exp_44() +// { } +// function test_exp_45() +// { } +// function test_exp_46() +// { } +// function test_exp_47() +// { } +// function test_exp_48() +// { } +// function test_not_0() +// { } +// function test_not_1() +// { } +// function test_not_2() +// { } +// function test_not_3() +// { } +// function test_not_4() +// { } +// function test_not_5() +// { } +// function test_not_6() +// { } +// function test_lt_0() +// { } +// function test_lt_1() +// { } +// function test_lt_2() +// { } +// function test_lt_3() +// { } +// function test_lt_4() +// { } +// function test_lt_5() +// { } +// function test_lt_6() +// { } +// function test_lt_7() +// { } +// function test_lt_8() +// { } +// function test_lt_9() +// { } +// function test_lt_10() +// { } +// function test_lt_11() +// { } +// function test_lt_12() +// { } +// function test_lt_13() +// { } +// function test_lt_14() +// { } +// function test_lt_15() +// { } +// function test_lt_16() +// { } +// function test_lt_17() +// { } +// function test_lt_18() +// { } +// function test_lt_19() +// { } +// function test_lt_20() +// { } +// function test_lt_21() +// { } +// function test_lt_22() +// { } +// function test_lt_23() +// { } +// function test_lt_24() +// { } +// function test_lt_25() +// { } +// function test_lt_26() +// { } +// function test_lt_27() +// { } +// function test_lt_28() +// { } +// function test_lt_29() +// { } +// function test_lt_30() +// { } +// function test_lt_31() +// { } +// function test_lt_32() +// { } +// function test_lt_33() +// { } +// function test_lt_34() +// { } +// function test_lt_35() +// { } +// function test_lt_36() +// { } +// function test_lt_37() +// { } +// function test_lt_38() +// { } +// function test_lt_39() +// { } +// function test_lt_40() +// { } +// function test_lt_41() +// { } +// function test_lt_42() +// { } +// function test_lt_43() +// { } +// function test_lt_44() +// { } +// function test_lt_45() +// { } +// function test_lt_46() +// { } +// function test_lt_47() +// { } +// function test_lt_48() +// { } +// function test_gt_0() +// { } +// function test_gt_1() +// { } +// function test_gt_2() +// { } +// function test_gt_3() +// { } +// function test_gt_4() +// { } +// function test_gt_5() +// { } +// function test_gt_6() +// { } +// function test_gt_7() +// { } +// function test_gt_8() +// { } +// function test_gt_9() +// { } +// function test_gt_10() +// { } +// function test_gt_11() +// { } +// function test_gt_12() +// { } +// function test_gt_13() +// { } +// function test_gt_14() +// { } +// function test_gt_15() +// { } +// function test_gt_16() +// { } +// function test_gt_17() +// { } +// function test_gt_18() +// { } +// function test_gt_19() +// { } +// function test_gt_20() +// { } +// function test_gt_21() +// { } +// function test_gt_22() +// { } +// function test_gt_23() +// { } +// function test_gt_24() +// { } +// function test_gt_25() +// { } +// function test_gt_26() +// { } +// function test_gt_27() +// { } +// function test_gt_28() +// { } +// function test_gt_29() +// { } +// function test_gt_30() +// { } +// function test_gt_31() +// { } +// function test_gt_32() +// { } +// function test_gt_33() +// { } +// function test_gt_34() +// { } +// function test_gt_35() +// { } +// function test_gt_36() +// { } +// function test_gt_37() +// { } +// function test_gt_38() +// { } +// function test_gt_39() +// { } +// function test_gt_40() +// { } +// function test_gt_41() +// { } +// function test_gt_42() +// { } +// function test_gt_43() +// { } +// function test_gt_44() +// { } +// function test_gt_45() +// { } +// function test_gt_46() +// { } +// function test_gt_47() +// { } +// function test_gt_48() +// { } +// function test_slt_0() +// { } +// function test_slt_1() +// { } +// function test_slt_2() +// { } +// function test_slt_3() +// { } +// function test_slt_4() +// { } +// function test_slt_5() +// { } +// function test_slt_6() +// { } +// function test_slt_7() +// { } +// function test_slt_8() +// { } +// function test_slt_9() +// { } +// function test_slt_10() +// { } +// function test_slt_11() +// { } +// function test_slt_12() +// { } +// function test_slt_13() +// { } +// function test_slt_14() +// { } +// function test_slt_15() +// { } +// function test_slt_16() +// { } +// function test_slt_17() +// { } +// function test_slt_18() +// { } +// function test_slt_19() +// { } +// function test_slt_20() +// { } +// function test_slt_21() +// { } +// function test_slt_22() +// { } +// function test_slt_23() +// { } +// function test_slt_24() +// { } +// function test_slt_25() +// { } +// function test_slt_26() +// { } +// function test_slt_27() +// { } +// function test_slt_28() +// { } +// function test_slt_29() +// { } +// function test_slt_30() +// { } +// function test_slt_31() +// { } +// function test_slt_32() +// { } +// function test_slt_33() +// { } +// function test_slt_34() +// { } +// function test_slt_35() +// { } +// function test_slt_36() +// { } +// function test_slt_37() +// { } +// function test_slt_38() +// { } +// function test_slt_39() +// { } +// function test_slt_40() +// { } +// function test_slt_41() +// { } +// function test_slt_42() +// { } +// function test_slt_43() +// { } +// function test_slt_44() +// { } +// function test_slt_45() +// { } +// function test_slt_46() +// { } +// function test_slt_47() +// { } +// function test_slt_48() +// { } +// function test_sgt_0() +// { } +// function test_sgt_1() +// { } +// function test_sgt_2() +// { } +// function test_sgt_3() +// { } +// function test_sgt_4() +// { } +// function test_sgt_5() +// { } +// function test_sgt_6() +// { } +// function test_sgt_7() +// { } +// function test_sgt_8() +// { } +// function test_sgt_9() +// { } +// function test_sgt_10() +// { } +// function test_sgt_11() +// { } +// function test_sgt_12() +// { } +// function test_sgt_13() +// { } +// function test_sgt_14() +// { } +// function test_sgt_15() +// { } +// function test_sgt_16() +// { } +// function test_sgt_17() +// { } +// function test_sgt_18() +// { } +// function test_sgt_19() +// { } +// function test_sgt_20() +// { } +// function test_sgt_21() +// { } +// function test_sgt_22() +// { } +// function test_sgt_23() +// { } +// function test_sgt_24() +// { } +// function test_sgt_25() +// { } +// function test_sgt_26() +// { } +// function test_sgt_27() +// { } +// function test_sgt_28() +// { } +// function test_sgt_29() +// { } +// function test_sgt_30() +// { } +// function test_sgt_31() +// { } +// function test_sgt_32() +// { } +// function test_sgt_33() +// { } +// function test_sgt_34() +// { } +// function test_sgt_35() +// { } +// function test_sgt_36() +// { } +// function test_sgt_37() +// { } +// function test_sgt_38() +// { } +// function test_sgt_39() +// { } +// function test_sgt_40() +// { } +// function test_sgt_41() +// { } +// function test_sgt_42() +// { } +// function test_sgt_43() +// { } +// function test_sgt_44() +// { } +// function test_sgt_45() +// { } +// function test_sgt_46() +// { } +// function test_sgt_47() +// { } +// function test_sgt_48() +// { } +// function test_eq_0() +// { } +// function test_eq_1() +// { } +// function test_eq_2() +// { } +// function test_eq_3() +// { } +// function test_eq_4() +// { } +// function test_eq_5() +// { } +// function test_eq_6() +// { } +// function test_eq_7() +// { } +// function test_eq_8() +// { } +// function test_eq_9() +// { } +// function test_eq_10() +// { } +// function test_eq_11() +// { } +// function test_eq_12() +// { } +// function test_eq_13() +// { } +// function test_eq_14() +// { } +// function test_eq_15() +// { } +// function test_eq_16() +// { } +// function test_eq_17() +// { } +// function test_eq_18() +// { } +// function test_eq_19() +// { } +// function test_eq_20() +// { } +// function test_eq_21() +// { } +// function test_eq_22() +// { } +// function test_eq_23() +// { } +// function test_eq_24() +// { } +// function test_eq_25() +// { } +// function test_eq_26() +// { } +// function test_eq_27() +// { } +// function test_eq_28() +// { } +// function test_eq_29() +// { } +// function test_eq_30() +// { } +// function test_eq_31() +// { } +// function test_eq_32() +// { } +// function test_eq_33() +// { } +// function test_eq_34() +// { } +// function test_eq_35() +// { } +// function test_eq_36() +// { } +// function test_eq_37() +// { } +// function test_eq_38() +// { } +// function test_eq_39() +// { } +// function test_eq_40() +// { } +// function test_eq_41() +// { } +// function test_eq_42() +// { } +// function test_eq_43() +// { } +// function test_eq_44() +// { } +// function test_eq_45() +// { } +// function test_eq_46() +// { } +// function test_eq_47() +// { } +// function test_eq_48() +// { } +// function test_iszero_0() +// { } +// function test_iszero_1() +// { } +// function test_iszero_2() +// { } +// function test_iszero_3() +// { } +// function test_iszero_4() +// { } +// function test_iszero_5() +// { } +// function test_iszero_6() +// { } +// function test_and_0() +// { } +// function test_and_1() +// { } +// function test_and_2() +// { } +// function test_and_3() +// { } +// function test_and_4() +// { } +// function test_and_5() +// { } +// function test_and_6() +// { } +// function test_and_7() +// { } +// function test_and_8() +// { } +// function test_and_9() +// { } +// function test_and_10() +// { } +// function test_and_11() +// { } +// function test_and_12() +// { } +// function test_and_13() +// { } +// function test_and_14() +// { } +// function test_and_15() +// { } +// function test_and_16() +// { } +// function test_and_17() +// { } +// function test_and_18() +// { } +// function test_and_19() +// { } +// function test_and_20() +// { } +// function test_and_21() +// { } +// function test_and_22() +// { } +// function test_and_23() +// { } +// function test_and_24() +// { } +// function test_and_25() +// { } +// function test_and_26() +// { } +// function test_and_27() +// { } +// function test_and_28() +// { } +// function test_and_29() +// { } +// function test_and_30() +// { } +// function test_and_31() +// { } +// function test_and_32() +// { } +// function test_and_33() +// { } +// function test_and_34() +// { } +// function test_and_35() +// { } +// function test_and_36() +// { } +// function test_and_37() +// { } +// function test_and_38() +// { } +// function test_and_39() +// { } +// function test_and_40() +// { } +// function test_and_41() +// { } +// function test_and_42() +// { } +// function test_and_43() +// { } +// function test_and_44() +// { } +// function test_and_45() +// { } +// function test_and_46() +// { } +// function test_and_47() +// { } +// function test_and_48() +// { } +// function test_or_0() +// { } +// function test_or_1() +// { } +// function test_or_2() +// { } +// function test_or_3() +// { } +// function test_or_4() +// { } +// function test_or_5() +// { } +// function test_or_6() +// { } +// function test_or_7() +// { } +// function test_or_8() +// { } +// function test_or_9() +// { } +// function test_or_10() +// { } +// function test_or_11() +// { } +// function test_or_12() +// { } +// function test_or_13() +// { } +// function test_or_14() +// { } +// function test_or_15() +// { } +// function test_or_16() +// { } +// function test_or_17() +// { } +// function test_or_18() +// { } +// function test_or_19() +// { } +// function test_or_20() +// { } +// function test_or_21() +// { } +// function test_or_22() +// { } +// function test_or_23() +// { } +// function test_or_24() +// { } +// function test_or_25() +// { } +// function test_or_26() +// { } +// function test_or_27() +// { } +// function test_or_28() +// { } +// function test_or_29() +// { } +// function test_or_30() +// { } +// function test_or_31() +// { } +// function test_or_32() +// { } +// function test_or_33() +// { } +// function test_or_34() +// { } +// function test_or_35() +// { } +// function test_or_36() +// { } +// function test_or_37() +// { } +// function test_or_38() +// { } +// function test_or_39() +// { } +// function test_or_40() +// { } +// function test_or_41() +// { } +// function test_or_42() +// { } +// function test_or_43() +// { } +// function test_or_44() +// { } +// function test_or_45() +// { } +// function test_or_46() +// { } +// function test_or_47() +// { } +// function test_or_48() +// { } +// function test_xor_0() +// { } +// function test_xor_1() +// { } +// function test_xor_2() +// { } +// function test_xor_3() +// { } +// function test_xor_4() +// { } +// function test_xor_5() +// { } +// function test_xor_6() +// { } +// function test_xor_7() +// { } +// function test_xor_8() +// { } +// function test_xor_9() +// { } +// function test_xor_10() +// { } +// function test_xor_11() +// { } +// function test_xor_12() +// { } +// function test_xor_13() +// { } +// function test_xor_14() +// { } +// function test_xor_15() +// { } +// function test_xor_16() +// { } +// function test_xor_17() +// { } +// function test_xor_18() +// { } +// function test_xor_19() +// { } +// function test_xor_20() +// { } +// function test_xor_21() +// { } +// function test_xor_22() +// { } +// function test_xor_23() +// { } +// function test_xor_24() +// { } +// function test_xor_25() +// { } +// function test_xor_26() +// { } +// function test_xor_27() +// { } +// function test_xor_28() +// { } +// function test_xor_29() +// { } +// function test_xor_30() +// { } +// function test_xor_31() +// { } +// function test_xor_32() +// { } +// function test_xor_33() +// { } +// function test_xor_34() +// { } +// function test_xor_35() +// { } +// function test_xor_36() +// { } +// function test_xor_37() +// { } +// function test_xor_38() +// { } +// function test_xor_39() +// { } +// function test_xor_40() +// { } +// function test_xor_41() +// { } +// function test_xor_42() +// { } +// function test_xor_43() +// { } +// function test_xor_44() +// { } +// function test_xor_45() +// { } +// function test_xor_46() +// { } +// function test_xor_47() +// { } +// function test_xor_48() +// { } +// function test_byte_0() +// { } +// function test_byte_1() +// { } +// function test_byte_2() +// { } +// function test_byte_3() +// { } +// function test_byte_4() +// { } +// function test_byte_5() +// { } +// function test_byte_6() +// { } +// function test_byte_7() +// { } +// function test_byte_8() +// { } +// function test_byte_9() +// { } +// function test_byte_10() +// { } +// function test_byte_11() +// { } +// function test_byte_12() +// { } +// function test_byte_13() +// { } +// function test_byte_14() +// { } +// function test_byte_15() +// { } +// function test_byte_16() +// { } +// function test_byte_17() +// { } +// function test_byte_18() +// { } +// function test_byte_19() +// { } +// function test_byte_20() +// { } +// function test_byte_21() +// { } +// function test_byte_22() +// { } +// function test_byte_23() +// { } +// function test_byte_24() +// { } +// function test_shl_0() +// { } +// function test_shl_1() +// { } +// function test_shl_2() +// { } +// function test_shl_3() +// { } +// function test_shl_4() +// { } +// function test_shl_5() +// { } +// function test_shl_6() +// { } +// function test_shl_7() +// { } +// function test_shl_8() +// { } +// function test_shl_9() +// { } +// function test_shl_10() +// { } +// function test_shl_11() +// { } +// function test_shl_12() +// { } +// function test_shl_13() +// { } +// function test_shl_14() +// { } +// function test_shl_15() +// { } +// function test_shl_16() +// { } +// function test_shl_17() +// { } +// function test_shl_18() +// { } +// function test_shl_19() +// { } +// function test_shl_20() +// { } +// function test_shl_21() +// { } +// function test_shl_22() +// { } +// function test_shl_23() +// { } +// function test_shl_24() +// { } +// function test_shl_25() +// { } +// function test_shl_26() +// { } +// function test_shl_27() +// { } +// function test_shl_28() +// { } +// function test_shl_29() +// { } +// function test_shl_30() +// { } +// function test_shl_31() +// { } +// function test_shl_32() +// { } +// function test_shl_33() +// { } +// function test_shl_34() +// { } +// function test_shl_35() +// { } +// function test_shl_36() +// { } +// function test_shl_37() +// { } +// function test_shl_38() +// { } +// function test_shl_39() +// { } +// function test_shl_40() +// { } +// function test_shl_41() +// { } +// function test_shl_42() +// { } +// function test_shl_43() +// { } +// function test_shl_44() +// { } +// function test_shl_45() +// { } +// function test_shl_46() +// { } +// function test_shl_47() +// { } +// function test_shl_48() +// { } +// function test_shr_0() +// { } +// function test_shr_1() +// { } +// function test_shr_2() +// { } +// function test_shr_3() +// { } +// function test_shr_4() +// { } +// function test_shr_5() +// { } +// function test_shr_6() +// { } +// function test_shr_7() +// { } +// function test_shr_8() +// { } +// function test_shr_9() +// { } +// function test_shr_10() +// { } +// function test_shr_11() +// { } +// function test_shr_12() +// { } +// function test_shr_13() +// { } +// function test_shr_14() +// { } +// function test_shr_15() +// { } +// function test_shr_16() +// { } +// function test_shr_17() +// { } +// function test_shr_18() +// { } +// function test_shr_19() +// { } +// function test_shr_20() +// { } +// function test_shr_21() +// { } +// function test_shr_22() +// { } +// function test_shr_23() +// { } +// function test_shr_24() +// { } +// function test_shr_25() +// { } +// function test_shr_26() +// { } +// function test_shr_27() +// { } +// function test_shr_28() +// { } +// function test_shr_29() +// { } +// function test_shr_30() +// { } +// function test_shr_31() +// { } +// function test_shr_32() +// { } +// function test_shr_33() +// { } +// function test_shr_34() +// { } +// function test_shr_35() +// { } +// function test_shr_36() +// { } +// function test_shr_37() +// { } +// function test_shr_38() +// { } +// function test_shr_39() +// { } +// function test_shr_40() +// { } +// function test_shr_41() +// { } +// function test_shr_42() +// { } +// function test_shr_43() +// { } +// function test_shr_44() +// { } +// function test_shr_45() +// { } +// function test_shr_46() +// { } +// function test_shr_47() +// { } +// function test_shr_48() +// { } +// function test_sar_0() +// { } +// function test_sar_1() +// { } +// function test_sar_2() +// { } +// function test_sar_3() +// { } +// function test_sar_4() +// { } +// function test_sar_5() +// { } +// function test_sar_6() +// { } +// function test_sar_7() +// { } +// function test_sar_8() +// { } +// function test_sar_9() +// { } +// function test_sar_10() +// { } +// function test_sar_11() +// { } +// function test_sar_12() +// { } +// function test_sar_13() +// { } +// function test_sar_14() +// { } +// function test_sar_15() +// { } +// function test_sar_16() +// { } +// function test_sar_17() +// { } +// function test_sar_18() +// { } +// function test_sar_19() +// { } +// function test_sar_20() +// { } +// function test_sar_21() +// { } +// function test_sar_22() +// { } +// function test_sar_23() +// { } +// function test_sar_24() +// { } +// function test_sar_25() +// { } +// function test_sar_26() +// { } +// function test_sar_27() +// { } +// function test_sar_28() +// { } +// function test_sar_29() +// { } +// function test_sar_30() +// { } +// function test_sar_31() +// { } +// function test_sar_32() +// { } +// function test_sar_33() +// { } +// function test_sar_34() +// { } +// function test_sar_35() +// { } +// function test_sar_36() +// { } +// function test_sar_37() +// { } +// function test_sar_38() +// { } +// function test_sar_39() +// { } +// function test_sar_40() +// { } +// function test_sar_41() +// { } +// function test_sar_42() +// { } +// function test_sar_43() +// { } +// function test_sar_44() +// { } +// function test_sar_45() +// { } +// function test_sar_46() +// { } +// function test_sar_47() +// { } +// function test_sar_48() +// { } +// function test_addmod_0() +// { } +// function test_addmod_1() +// { } +// function test_addmod_2() +// { } +// function test_addmod_3() +// { } +// function test_addmod_4() +// { } +// function test_addmod_5() +// { } +// function test_addmod_6() +// { } +// function test_addmod_7() +// { } +// function test_addmod_8() +// { } +// function test_addmod_9() +// { } +// function test_addmod_10() +// { } +// function test_addmod_11() +// { } +// function test_addmod_12() +// { } +// function test_addmod_13() +// { } +// function test_addmod_14() +// { } +// function test_addmod_15() +// { } +// function test_addmod_16() +// { } +// function test_addmod_17() +// { } +// function test_addmod_18() +// { } +// function test_addmod_19() +// { } +// function test_addmod_20() +// { } +// function test_addmod_21() +// { } +// function test_addmod_22() +// { } +// function test_addmod_23() +// { } +// function test_addmod_24() +// { } +// function test_addmod_25() +// { } +// function test_addmod_26() +// { } +// function test_addmod_27() +// { } +// function test_addmod_28() +// { } +// function test_addmod_29() +// { } +// function test_addmod_30() +// { } +// function test_addmod_31() +// { } +// function test_addmod_32() +// { } +// function test_addmod_33() +// { } +// function test_addmod_34() +// { } +// function test_addmod_35() +// { } +// function test_addmod_36() +// { } +// function test_addmod_37() +// { } +// function test_addmod_38() +// { } +// function test_addmod_39() +// { } +// function test_addmod_40() +// { } +// function test_addmod_41() +// { } +// function test_addmod_42() +// { } +// function test_addmod_43() +// { } +// function test_addmod_44() +// { } +// function test_addmod_45() +// { } +// function test_addmod_46() +// { } +// function test_addmod_47() +// { } +// function test_addmod_48() +// { } +// function test_addmod_49() +// { } +// function test_addmod_50() +// { } +// function test_addmod_51() +// { } +// function test_addmod_52() +// { } +// function test_addmod_53() +// { } +// function test_addmod_54() +// { } +// function test_addmod_55() +// { } +// function test_addmod_56() +// { } +// function test_addmod_57() +// { } +// function test_addmod_58() +// { } +// function test_addmod_59() +// { } +// function test_addmod_60() +// { } +// function test_addmod_61() +// { } +// function test_addmod_62() +// { } +// function test_addmod_63() +// { } +// function test_mulmod_0() +// { } +// function test_mulmod_1() +// { } +// function test_mulmod_2() +// { } +// function test_mulmod_3() +// { } +// function test_mulmod_4() +// { } +// function test_mulmod_5() +// { } +// function test_mulmod_6() +// { } +// function test_mulmod_7() +// { } +// function test_mulmod_8() +// { } +// function test_mulmod_9() +// { } +// function test_mulmod_10() +// { } +// function test_mulmod_11() +// { } +// function test_mulmod_12() +// { } +// function test_mulmod_13() +// { } +// function test_mulmod_14() +// { } +// function test_mulmod_15() +// { } +// function test_mulmod_16() +// { } +// function test_mulmod_17() +// { } +// function test_mulmod_18() +// { } +// function test_mulmod_19() +// { } +// function test_mulmod_20() +// { } +// function test_mulmod_21() +// { } +// function test_mulmod_22() +// { } +// function test_mulmod_23() +// { } +// function test_mulmod_24() +// { } +// function test_mulmod_25() +// { } +// function test_mulmod_26() +// { } +// function test_mulmod_27() +// { } +// function test_mulmod_28() +// { } +// function test_mulmod_29() +// { } +// function test_mulmod_30() +// { } +// function test_mulmod_31() +// { } +// function test_mulmod_32() +// { } +// function test_mulmod_33() +// { } +// function test_mulmod_34() +// { } +// function test_mulmod_35() +// { } +// function test_mulmod_36() +// { } +// function test_mulmod_37() +// { } +// function test_mulmod_38() +// { } +// function test_mulmod_39() +// { } +// function test_mulmod_40() +// { } +// function test_mulmod_41() +// { } +// function test_mulmod_42() +// { } +// function test_mulmod_43() +// { } +// function test_mulmod_44() +// { } +// function test_mulmod_45() +// { } +// function test_mulmod_46() +// { } +// function test_mulmod_47() +// { } +// function test_mulmod_48() +// { } +// function test_mulmod_49() +// { } +// function test_mulmod_50() +// { } +// function test_mulmod_51() +// { } +// function test_mulmod_52() +// { } +// function test_mulmod_53() +// { } +// function test_mulmod_54() +// { } +// function test_mulmod_55() +// { } +// function test_mulmod_56() +// { } +// function test_mulmod_57() +// { } +// function test_mulmod_58() +// { } +// function test_mulmod_59() +// { } +// function test_mulmod_60() +// { } +// function test_mulmod_61() +// { } +// function test_mulmod_62() +// { } +// function test_mulmod_63() +// { } +// function test_signextend_0() +// { } +// function test_signextend_1() +// { } +// function test_signextend_2() +// { } +// function test_signextend_3() +// { } +// function test_signextend_4() +// { } +// function test_signextend_5() +// { } +// function test_signextend_6() +// { } +// function test_signextend_7() +// { } +// function test_signextend_8() +// { } +// function test_signextend_9() +// { } +// function test_signextend_10() +// { } +// function test_signextend_11() +// { } +// function test_signextend_12() +// { } +// function test_signextend_13() +// { } +// function test_signextend_14() +// { } +// function test_signextend_15() +// { } +// function test_signextend_16() +// { } +// function test_signextend_17() +// { } +// function test_signextend_18() +// { } +// function test_signextend_19() +// { } +// function test_signextend_20() +// { } +// function test_signextend_21() +// { } +// function test_signextend_22() +// { } +// function test_signextend_23() +// { } +// function test_signextend_24() +// { } +// function test_signextend_25() +// { } +// function test_signextend_26() +// { } +// function test_signextend_27() +// { } +// function test_signextend_28() +// { } +// function test_signextend_29() +// { } +// function test_signextend_30() +// { } +// function test_signextend_31() +// { } +// function test_signextend_32() +// { } +// function test_signextend_33() +// { } +// function test_signextend_34() +// { } +// function test_signextend_35() +// { } +// function test_signextend_36() +// { } +// function test_signextend_37() +// { } +// function test_signextend_38() +// { } +// function test_signextend_39() +// { } +// function test_signextend_40() +// { } +// function test_signextend_41() +// { } +// function test_signextend_42() +// { } +// function test_signextend_43() +// { } +// function test_signextend_44() +// { } +// function test_signextend_45() +// { } +// function test_signextend_46() +// { } +// function test_signextend_47() +// { } +// function test_signextend_48() +// { } +// } diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/all_side_effects.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/all_side_effects.yul new file mode 100644 index 000000000000..e101e647dfbb --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/all_side_effects.yul @@ -0,0 +1,368 @@ +object "Myobj" +{ + code { + function ops(id) -> r { + switch id + case 0 { r := 1 } + // --------------- blockchain stuff --------------- + case 1 { let _x := keccak256(0, 0) } + case 2 { let _x := address() } + case 3 { let _x := balance(0) } + case 4 { let _x := selfbalance() } + case 5 { let _x := origin() } + case 6 { let _x := caller() } + case 7 { let _x := calldataload(0) } + case 8 { let _x := calldatasize() } + case 9 { calldatacopy(0, 0, 0) } + case 10 { let _x := codesize() } + case 11 { codecopy(0, 0, 0) } + case 12 { let _x := gasprice() } + case 13 { let _x := chainid() } + case 14 { let _x := blobhash(0) } + case 15 { let _x := blobbasefee() } + case 16 { let _x := extcodesize(0) } + case 17 { let _x := extcodehash(0) } + case 18 { extcodecopy(0, 0, 0, 0) } + case 19 { let _x := returndatasize() } + case 20 { returndatacopy(0, 0, 0) } + case 21 { mcopy(0, 0, 0) } + case 22 { let _x := blockhash(0) } + case 23 { let _x := coinbase() } + case 24 { let _x := timestamp() } + case 25 { let _x := number() } + case 26 { let _x := prevrandao() } + case 27 { let _x := gaslimit() } + // --------------- memory / storage / logs --------------- + case 28 { let _x := mload(0) } + case 29 { mstore(0, 0) } + case 30 { mstore8(0, 0) } + case 31 { let _x := sload(0) } + case 32 { sstore(0, 0) } + // can not use PC here + // case 33 { let _x := pc() } + case 33 { revert(0, 0) } + case 34 { let _x := msize() } + case 35 { let _x := gas() } + case 36 { log0(0, 0) } + case 37 { log1(0, 0, 0) } + case 38 { log2(0, 0, 0, 0) } + case 39 { log3(0, 0, 0, 0, 0) } + case 40 { log4(0, 0, 0, 0, 0, 0) } + case 41 { let _x := tload(0) } + case 42 { tstore(0, 0) } + // --------------- calls --------------- + case 43 { let _x := create(0, 0, 0) } + case 44 { let _x := create2(0, 0, 0, 0) } + case 45 { let _x := call(0, 0, 0, 0, 0, 0, 0) } + case 46 { let _x := callcode(0, 0, 0, 0, 0, 0, 0) } + case 47 { let _x := delegatecall(0, 0, 0, 0, 0, 0) } + case 48 { let _x := staticcall(0, 0, 0, 0, 0, 0) } + case 49 { return(0, 0) } + case 50 { revert(0, 0) } + case 51 { invalid() } + case 52 { selfdestruct(0) } + // --------------- meta ---------------- + case 53 { let _x := datasize("Mydata") } + case 54 { let _x := dataoffset("Mydata") } + case 55 { datacopy("Mydata", 0, 0) } + case 56 { let _x := loadimmutable("x") } + case 57 { setimmutable(0, "x", 0) } + case 58 { let a := linkersymbol("x") } + case 59 { let _x := memoryguard(0) } + case 60 { verbatim_1i_0o(hex"deadbeef", 0) } + case 61 { let _x := verbatim_1i_1o(hex"deadbeef", 0) } + // --------------- stop --------------- + case 62 { stop() } + // should check if value is greater than 62 + default { revert(0, 0) } + } + function test_0() -> r { r := ops(0) } + function test_1() -> r { r := ops(1) } + function test_2() -> r { r := ops(2) } + function test_3() -> r { r := ops(3) } + function test_4() -> r { r := ops(4) } + function test_5() -> r { r := ops(5) } + function test_6() -> r { r := ops(6) } + function test_7() -> r { r := ops(7) } + function test_8() -> r { r := ops(8) } + function test_9() -> r { r := ops(9) } + function test_10() -> r { r := ops(10) } + function test_11() -> r { r := ops(11) } + function test_12() -> r { r := ops(12) } + function test_13() -> r { r := ops(13) } + function test_14() -> r { r := ops(14) } + function test_15() -> r { r := ops(15) } + function test_16() -> r { r := ops(16) } + function test_17() -> r { r := ops(17) } + function test_18() -> r { r := ops(18) } + function test_19() -> r { r := ops(19) } + function test_20() -> r { r := ops(20) } + function test_21() -> r { r := ops(21) } + function test_22() -> r { r := ops(22) } + function test_23() -> r { r := ops(23) } + function test_24() -> r { r := ops(24) } + function test_25() -> r { r := ops(25) } + function test_26() -> r { r := ops(26) } + function test_27() -> r { r := ops(27) } + function test_28() -> r { r := ops(28) } + function test_29() -> r { r := ops(29) } + function test_30() -> r { r := ops(30) } + function test_31() -> r { r := ops(31) } + function test_32() -> r { r := ops(32) } + function test_33() -> r { r := ops(33) } + function test_34() -> r { r := ops(34) } + function test_35() -> r { r := ops(35) } + function test_36() -> r { r := ops(36) } + function test_37() -> r { r := ops(37) } + function test_38() -> r { r := ops(38) } + function test_39() -> r { r := ops(39) } + function test_40() -> r { r := ops(40) } + function test_41() -> r { r := ops(41) } + function test_42() -> r { r := ops(42) } + function test_43() -> r { r := ops(43) } + function test_44() -> r { r := ops(44) } + function test_45() -> r { r := ops(45) } + function test_46() -> r { r := ops(46) } + function test_47() -> r { r := ops(47) } + function test_48() -> r { r := ops(48) } + function test_49() -> r { r := ops(49) } + function test_50() -> r { r := ops(50) } + function test_51() -> r { r := ops(51) } + function test_52() -> r { r := ops(52) } + function test_53() -> r { r := ops(53) } + function test_54() -> r { r := ops(54) } + function test_55() -> r { r := ops(55) } + function test_56() -> r { r := ops(56) } + function test_57() -> r { r := ops(57) } + function test_58() -> r { r := ops(58) } + function test_59() -> r { r := ops(59) } + function test_60() -> r { r := ops(60) } + function test_61() -> r { r := ops(61) } + function test_62() -> r { r := ops(62) } + } + data "Mydata" hex"1234" +} +// ==== +// EVMVersion: >=cancun +// ---- +// step: constantFunctionEvaluator +// +// object "Myobj" { +// code { +// function ops(id) -> r +// { +// switch id +// case 0 { r := 1 } +// case 1 { let _x := keccak256(0, 0) } +// case 2 { let _x_1 := address() } +// case 3 { let _x_2 := balance(0) } +// case 4 { let _x_3 := selfbalance() } +// case 5 { let _x_4 := origin() } +// case 6 { let _x_5 := caller() } +// case 7 { let _x_6 := calldataload(0) } +// case 8 { let _x_7 := calldatasize() } +// case 9 { calldatacopy(0, 0, 0) } +// case 10 { let _x_8 := codesize() } +// case 11 { codecopy(0, 0, 0) } +// case 12 { let _x_9 := gasprice() } +// case 13 { let _x_10 := chainid() } +// case 14 { let _x_11 := blobhash(0) } +// case 15 { let _x_12 := blobbasefee() } +// case 16 { let _x_13 := extcodesize(0) } +// case 17 { let _x_14 := extcodehash(0) } +// case 18 { extcodecopy(0, 0, 0, 0) } +// case 19 { let _x_15 := returndatasize() } +// case 20 { returndatacopy(0, 0, 0) } +// case 21 { mcopy(0, 0, 0) } +// case 22 { let _x_16 := blockhash(0) } +// case 23 { let _x_17 := coinbase() } +// case 24 { let _x_18 := timestamp() } +// case 25 { let _x_19 := number() } +// case 26 { let _x_20 := prevrandao() } +// case 27 { let _x_21 := gaslimit() } +// case 28 { let _x_22 := mload(0) } +// case 29 { mstore(0, 0) } +// case 30 { mstore8(0, 0) } +// case 31 { let _x_23 := sload(0) } +// case 32 { sstore(0, 0) } +// case 33 { revert(0, 0) } +// case 34 { let _x_24 := msize() } +// case 35 { let _x_25 := gas() } +// case 36 { log0(0, 0) } +// case 37 { log1(0, 0, 0) } +// case 38 { log2(0, 0, 0, 0) } +// case 39 { log3(0, 0, 0, 0, 0) } +// case 40 { log4(0, 0, 0, 0, 0, 0) } +// case 41 { let _x_26 := tload(0) } +// case 42 { tstore(0, 0) } +// case 43 { let _x_27 := create(0, 0, 0) } +// case 44 { +// let _x_28 := create2(0, 0, 0, 0) +// } +// case 45 { +// let _x_29 := call(0, 0, 0, 0, 0, 0, 0) +// } +// case 46 { +// let _x_30 := callcode(0, 0, 0, 0, 0, 0, 0) +// } +// case 47 { +// let _x_31 := delegatecall(0, 0, 0, 0, 0, 0) +// } +// case 48 { +// let _x_32 := staticcall(0, 0, 0, 0, 0, 0) +// } +// case 49 { return(0, 0) } +// case 50 { revert(0, 0) } +// case 51 { invalid() } +// case 52 { selfdestruct(0) } +// case 53 { +// let _x_33 := datasize("Mydata") +// } +// case 54 { +// let _x_34 := dataoffset("Mydata") +// } +// case 55 { datacopy("Mydata", 0, 0) } +// case 56 { +// let _x_35 := loadimmutable("x") +// } +// case 57 { setimmutable(0, "x", 0) } +// case 58 { let a := linkersymbol("x") } +// case 59 { let _x_36 := memoryguard(0) } +// case 60 { +// verbatim_1i_0o("\xde\xad\xbe\xef", 0) +// } +// case 61 { +// let _x_37 := verbatim_1i_1o("\xde\xad\xbe\xef", 0) +// } +// case 62 { stop() } +// default { revert(0, 0) } +// } +// function test_0() -> r_38 +// { r_38 := 1 } +// function test_1() -> r_39 +// { r_39 := ops(1) } +// function test_2() -> r_40 +// { r_40 := ops(2) } +// function test_3() -> r_41 +// { r_41 := ops(3) } +// function test_4() -> r_42 +// { r_42 := ops(4) } +// function test_5() -> r_43 +// { r_43 := ops(5) } +// function test_6() -> r_44 +// { r_44 := ops(6) } +// function test_7() -> r_45 +// { r_45 := ops(7) } +// function test_8() -> r_46 +// { r_46 := ops(8) } +// function test_9() -> r_47 +// { r_47 := ops(9) } +// function test_10() -> r_48 +// { r_48 := ops(10) } +// function test_11() -> r_49 +// { r_49 := ops(11) } +// function test_12() -> r_50 +// { r_50 := ops(12) } +// function test_13() -> r_51 +// { r_51 := ops(13) } +// function test_14() -> r_52 +// { r_52 := ops(14) } +// function test_15() -> r_53 +// { r_53 := ops(15) } +// function test_16() -> r_54 +// { r_54 := ops(16) } +// function test_17() -> r_55 +// { r_55 := ops(17) } +// function test_18() -> r_56 +// { r_56 := ops(18) } +// function test_19() -> r_57 +// { r_57 := ops(19) } +// function test_20() -> r_58 +// { r_58 := ops(20) } +// function test_21() -> r_59 +// { r_59 := ops(21) } +// function test_22() -> r_60 +// { r_60 := ops(22) } +// function test_23() -> r_61 +// { r_61 := ops(23) } +// function test_24() -> r_62 +// { r_62 := ops(24) } +// function test_25() -> r_63 +// { r_63 := ops(25) } +// function test_26() -> r_64 +// { r_64 := ops(26) } +// function test_27() -> r_65 +// { r_65 := ops(27) } +// function test_28() -> r_66 +// { r_66 := ops(28) } +// function test_29() -> r_67 +// { r_67 := ops(29) } +// function test_30() -> r_68 +// { r_68 := ops(30) } +// function test_31() -> r_69 +// { r_69 := ops(31) } +// function test_32() -> r_70 +// { r_70 := ops(32) } +// function test_33() -> r_71 +// { r_71 := ops(33) } +// function test_34() -> r_72 +// { r_72 := ops(34) } +// function test_35() -> r_73 +// { r_73 := ops(35) } +// function test_36() -> r_74 +// { r_74 := ops(36) } +// function test_37() -> r_75 +// { r_75 := ops(37) } +// function test_38() -> r_76 +// { r_76 := ops(38) } +// function test_39() -> r_77 +// { r_77 := ops(39) } +// function test_40() -> r_78 +// { r_78 := ops(40) } +// function test_41() -> r_79 +// { r_79 := ops(41) } +// function test_42() -> r_80 +// { r_80 := ops(42) } +// function test_43() -> r_81 +// { r_81 := ops(43) } +// function test_44() -> r_82 +// { r_82 := ops(44) } +// function test_45() -> r_83 +// { r_83 := ops(45) } +// function test_46() -> r_84 +// { r_84 := ops(46) } +// function test_47() -> r_85 +// { r_85 := ops(47) } +// function test_48() -> r_86 +// { r_86 := ops(48) } +// function test_49() -> r_87 +// { r_87 := ops(49) } +// function test_50() -> r_88 +// { r_88 := ops(50) } +// function test_51() -> r_89 +// { r_89 := ops(51) } +// function test_52() -> r_90 +// { r_90 := ops(52) } +// function test_53() -> r_91 +// { r_91 := ops(53) } +// function test_54() -> r_92 +// { r_92 := ops(54) } +// function test_55() -> r_93 +// { r_93 := ops(55) } +// function test_56() -> r_94 +// { r_94 := ops(56) } +// function test_57() -> r_95 +// { r_95 := ops(57) } +// function test_58() -> r_96 +// { r_96 := ops(58) } +// function test_59() -> r_97 +// { r_97 := ops(59) } +// function test_60() -> r_98 +// { r_98 := ops(60) } +// function test_61() -> r_99 +// { r_99 := ops(61) } +// function test_62() -> r_100 +// { r_100 := ops(62) } +// } +// data "Mydata" hex"1234" +// } diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/branch_with_sideeffect.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/branch_with_sideeffect.yul new file mode 100644 index 000000000000..fabe26456b96 --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/branch_with_sideeffect.yul @@ -0,0 +1,40 @@ +{ + function foo(x, y) -> r { + switch mod(add(x, y), 2) + case 0 { + r := 1 + } + case 1 + { + sstore(0, 1) + r := 2 + } + } + + function a() -> k { + k := foo(1, 1) + } + + function b() -> h { + h := foo(2, 1) + } +} + +// ---- +// step: constantFunctionEvaluator +// +// { +// function foo(x, y) -> r +// { +// switch mod(add(x, y), 2) +// case 0 { r := 1 } +// case 1 { +// sstore(0, 1) +// r := 2 +// } +// } +// function a() -> k +// { k := 1 } +// function b() -> h +// { h := foo(2, 1) } +// } diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/checked_power.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/checked_power.yul new file mode 100644 index 000000000000..0dacf46e81f0 --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/checked_power.yul @@ -0,0 +1,199 @@ +{ + function test_ok() -> r1, r2, r3, r4, r5, r6, r7, r8, r9 + { + r9 := checked_exp_t_uint256_t_uint256(10, 18) + r8 := checked_exp_t_uint256_t_uint256(2, 255) + r7 := checked_exp_t_uint256_t_uint256(1, not(0)) + r6 := checked_exp_t_uint256_t_uint256(0, 0) + r5 := checked_exp_t_uint256_t_uint256(not(0), 0) + r4 := checked_exp_t_uint256_t_uint256(not(0), 1) + r3 := checked_exp_t_uint256_t_uint256(10, 77) + r2 := checked_exp_t_uint256_t_uint256(306, 31) + r1 := checked_exp_t_uint256_t_uint256(shl(127, 1), 2) + } + function test_overflow1() -> r + { r := checked_exp_t_uint256_t_uint256(not(0), not(0)) } + function test_overflow2() -> r + { r := checked_exp_t_uint256_t_uint256(2, 256) } + function test_overflow3() -> r + { r := checked_exp_t_uint256_t_uint256(11, 78) } + function test_overflow4() -> r + { r := checked_exp_t_uint256_t_uint256(307, 32) } + function test_overflow5() -> r + { r := checked_exp_t_uint256_t_uint256(10, 78) } + function test_overflow6() -> r + { r := checked_exp_t_uint256_t_uint256(50859009, 10) } + + function panic_error_0x11() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x11) + revert(0, 0x24) + } + function shift_right_1_unsigned(value) -> newValue { + newValue := shr(1, value) + } + function checked_exp_helper(_power, _base, exponent, max) -> power, base { + power := _power + base := _base + for { } gt(exponent, 1) {} + { + // overflow check for base * base + if gt(base, div(max, base)) { panic_error_0x11() } + if and(exponent, 1) + { + // No checks for power := mul(power, base) needed, because the check + // for base * base above is sufficient, since: + // |power| <= base (proof by induction) and thus: + // |power * base| <= base * base <= max <= |min| (for signed) + // (this is equally true for signed and unsigned exp) + power := mul(power, base) + } + base := mul(base, base) + exponent := shift_right_1_unsigned(exponent) + } + } + function checked_exp_unsigned(base, exponent, max) -> power { + // This function currently cannot be inlined because of the + // "leave" statements. We have to improve the optimizer. + + // Note that 0**0 == 1 + if iszero(exponent) { power := 1 leave } + if iszero(base) { power := 0 leave } + + // Specializations for small bases + switch base + // 0 is handled above + case 1 { power := 1 leave } + case 2 + { + if gt(exponent, 255) { panic_error_0x11() } + power := exp(2, exponent) + if gt(power, max) { panic_error_0x11() } + leave + } + if or( + and(lt(base, 11), lt(exponent, 78)), + and(lt(base, 307), lt(exponent, 32)) + ) + { + power := exp(base, exponent) + if gt(power, max) { panic_error_0x11() } + leave + } + + power, base := checked_exp_helper(1, base, exponent, max) + + if gt(power, div(max, base)) { panic_error_0x11() } + power := mul(power, base) + } + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + function checked_exp_t_uint256_t_uint256(base, exponent) -> power { + base := cleanup_t_uint256(base) + exponent := cleanup_t_uint256(exponent) + power := checked_exp_unsigned(base, exponent, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + } +} +// ---- +// step: constantFunctionEvaluator +// +// { +// function test_ok() -> r1, r2, r3, r4, r5, r6, r7, r8, r9 +// { +// r1 := 28948022309329048855892746252171976963317496166410141009864396001978282409984 +// r2 := 114120645878241659292862104872151745131076900847207153599812066301423392915456 +// r3 := 100000000000000000000000000000000000000000000000000000000000000000000000000000 +// r4 := 115792089237316195423570985008687907853269984665640564039457584007913129639935 +// r5 := 1 +// r6 := 1 +// r7 := 1 +// r8 := 57896044618658097711785492504343953926634992332820282019728792003956564819968 +// r9 := 1000000000000000000 +// } +// function test_overflow1() -> r +// { +// r := checked_exp_t_uint256_t_uint256(not(0), not(0)) +// } +// function test_overflow2() -> r_1 +// { +// r_1 := checked_exp_t_uint256_t_uint256(2, 256) +// } +// function test_overflow3() -> r_2 +// { +// r_2 := checked_exp_t_uint256_t_uint256(11, 78) +// } +// function test_overflow4() -> r_3 +// { +// r_3 := checked_exp_t_uint256_t_uint256(307, 32) +// } +// function test_overflow5() -> r_4 +// { +// r_4 := checked_exp_t_uint256_t_uint256(10, 78) +// } +// function test_overflow6() -> r_5 +// { +// r_5 := checked_exp_t_uint256_t_uint256(50859009, 10) +// } +// function panic_error_0x11() +// { +// mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) +// mstore(4, 0x11) +// revert(0, 0x24) +// } +// function shift_right_1_unsigned(value) -> newValue +// { newValue := shr(1, value) } +// function checked_exp_helper(_power, _base, exponent, max) -> power, base +// { +// power := _power +// base := _base +// for { } gt(exponent, 1) { } +// { +// if gt(base, div(max, base)) { panic_error_0x11() } +// if and(exponent, 1) { power := mul(power, base) } +// base := mul(base, base) +// exponent := shift_right_1_unsigned(exponent) +// } +// } +// function checked_exp_unsigned(base_6, exponent_7, max_8) -> power_9 +// { +// if iszero(exponent_7) +// { +// power_9 := 1 +// leave +// } +// if iszero(base_6) +// { +// power_9 := 0 +// leave +// } +// switch base_6 +// case 1 { +// power_9 := 1 +// leave +// } +// case 2 { +// if gt(exponent_7, 255) { panic_error_0x11() } +// power_9 := exp(2, exponent_7) +// if gt(power_9, max_8) { panic_error_0x11() } +// leave +// } +// if or(and(lt(base_6, 11), lt(exponent_7, 78)), and(lt(base_6, 307), lt(exponent_7, 32))) +// { +// power_9 := exp(base_6, exponent_7) +// if gt(power_9, max_8) { panic_error_0x11() } +// leave +// } +// power_9, base_6 := checked_exp_helper(1, base_6, exponent_7, max_8) +// if gt(power_9, div(max_8, base_6)) { panic_error_0x11() } +// power_9 := mul(power_9, base_6) +// } +// function cleanup_t_uint256(value_10) -> cleaned +// { cleaned := value_10 } +// function checked_exp_t_uint256_t_uint256(base_11, exponent_12) -> power_13 +// { +// base_11 := cleanup_t_uint256(base_11) +// exponent_12 := cleanup_t_uint256(exponent_12) +// power_13 := checked_exp_unsigned(base_11, exponent_12, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) +// } +// } diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/deeply_nested_with_sideeffect.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/deeply_nested_with_sideeffect.yul new file mode 100644 index 000000000000..378d59fce620 --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/deeply_nested_with_sideeffect.yul @@ -0,0 +1,79 @@ +{ + // with side effect + { + function a(x) -> r { + r := b(x) + } + + function b(x) -> r { + r := c(x) + } + + function c(x) -> r { + r := d(x) + } + + function d(x) -> r { + mstore(x, 1) + r := add(x, 1) + } + + function test() -> k { + k := a(10) + } + } + // without side effect + { + function a(x) -> r { + r := b(x) + } + + function b(x) -> r { + r := c(x) + } + + function c(x) -> r { + r := d(x) + } + + function d(x) -> r { + r := add(x, 1) + } + + function test() -> k { + k := a(10) + } + } +} +// ---- +// step: constantFunctionEvaluator +// +// { +// { +// function a(x) -> r +// { r := b(x) } +// function b(x_1) -> r_2 +// { r_2 := c(x_1) } +// function c(x_3) -> r_4 +// { r_4 := d(x_3) } +// function d(x_5) -> r_6 +// { +// mstore(x_5, 1) +// r_6 := add(x_5, 1) +// } +// function test() -> k +// { k := a(10) } +// } +// { +// function a_7(x_8) -> r_9 +// { r_9 := b_10(x_8) } +// function b_10(x_11) -> r_12 +// { r_12 := c_13(x_11) } +// function c_13(x_14) -> r_15 +// { r_15 := d_16(x_14) } +// function d_16(x_17) -> r_18 +// { r_18 := add(x_17, 1) } +// function test_19() -> k_20 +// { k_20 := 11 } +// } +// } diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/forloop_factorial.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/forloop_factorial.yul new file mode 100644 index 000000000000..9530d0ab1311 --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/forloop_factorial.yul @@ -0,0 +1,51 @@ +{ + function factorial(n) -> res { + res := 1 + for {} gt(n, 0) { n := sub(n, 1) } + { + res := mul(res, n) + } + } + + function f0() -> r + { r := factorial(0) } + function f1() -> r + { r := factorial(1) } + function f2() -> r + { r := factorial(2) } + function f3() -> r + { r := factorial(3) } + function f10() -> r + { r := factorial(10) } + function f20() -> r + { r := factorial(20) } + function f69() -> r + { r := factorial(69) } +} +// ---- +// step: constantFunctionEvaluator +// +// { +// function factorial(n) -> res +// { +// res := 1 +// for { } gt(n, 0) { n := sub(n, 1) } +// { res := mul(res, n) } +// } +// function f0() -> r +// { r := 1 } +// function f1() -> r_1 +// { r_1 := 1 } +// function f2() -> r_2 +// { r_2 := 2 } +// function f3() -> r_3 +// { r_3 := 6 } +// function f10() -> r_4 +// { r_4 := 3628800 } +// function f20() -> r_5 +// { r_5 := 2432902008176640000 } +// function f69() -> r_6 +// { +// r_6 := 16741780892319805204297532714932875773929443833795836392311461786655658082304 +// } +// } diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/forloop_fibonacci.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/forloop_fibonacci.yul new file mode 100644 index 000000000000..638a4380c8e0 --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/forloop_fibonacci.yul @@ -0,0 +1,79 @@ +{ + function fibonacci(n) -> res { + let a := 0 + let b := 1 + for {} gt(n, 0) { n := sub(n, 1) } + { + let t := b + b := add(a, b) + a := t + } + res := a + } + + function f0() -> r + { r := fibonacci(0) } + function f1() -> r + { r := fibonacci(1) } + function f2() -> r + { r := fibonacci(2) } + function f3() -> r + { r := fibonacci(3) } + function f4() -> r + { r := fibonacci(4) } + function f5() -> r + { r := fibonacci(5) } + function f10() -> r + { r := fibonacci(10) } + function f11() -> r + { r := fibonacci(11) } + function f12() -> r + { r := fibonacci(12) } + function f13() -> r + { r := fibonacci(13) } + function f20() -> r + { r := fibonacci(20) } + function f69() -> r + { r := fibonacci(69) } +} +// ---- +// step: constantFunctionEvaluator +// +// { +// function fibonacci(n) -> res +// { +// let a := 0 +// let b := 1 +// for { } gt(n, 0) { n := sub(n, 1) } +// { +// let t := b +// b := add(a, b) +// a := t +// } +// res := a +// } +// function f0() -> r +// { r := 0 } +// function f1() -> r_1 +// { r_1 := 1 } +// function f2() -> r_2 +// { r_2 := 1 } +// function f3() -> r_3 +// { r_3 := 2 } +// function f4() -> r_4 +// { r_4 := 3 } +// function f5() -> r_5 +// { r_5 := 5 } +// function f10() -> r_6 +// { r_6 := 55 } +// function f11() -> r_7 +// { r_7 := 89 } +// function f12() -> r_8 +// { r_8 := 144 } +// function f13() -> r_9 +// { r_9 := 233 } +// function f20() -> r_10 +// { r_10 := 6765 } +// function f69() -> r_11 +// { r_11 := 117669030460994 } +// } diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/nested_expression.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/nested_expression.yul new file mode 100644 index 000000000000..900091758b90 --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/nested_expression.yul @@ -0,0 +1,20 @@ +{ + function nested_100() -> r { + r := add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,0x1)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) + } + + function nested_32() -> r { + r := add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,0x1)))))))))))))))))))))))))))))))) + } +} +// ---- +// step: constantFunctionEvaluator +// +// { +// function nested_100() -> r +// { +// r := add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, add(0x1, 0x1)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +// } +// function nested_32() -> r_1 +// { r_1 := 33 } +// } diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/nested_functions.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/nested_functions.yul new file mode 100644 index 000000000000..cdb4ececa601 --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/nested_functions.yul @@ -0,0 +1,109 @@ +{ + // should contracted to only function a + { + function a() -> r { + r := add(b(), 1) + + function b() -> x { + let p, q := c() + x := add(p, q) + + function c() -> m, n { + m := mul(d(), e()) + n := div(d(), e()) + + function d() -> s { + for { let i := 0 } lt(i, 100) { i := add(i, 1) } + { s := add(s, i) } + } + + function e() -> s { + for { let i := 0 } lt(i, 100) { i := add(i, 1) } + { s := add(s, f(i)) } + + function f(i) -> k { + let foo := 1 + let bar := 2 + + if iszero(mod(i,3)) { + k := or(k,foo) + } + if iszero(mod(i,5)) { + k := or(k,bar) + } + } + } + } + } + } + } + + // this one is the same as above + // used to trace each function's result + { + function a() -> r { + r := add(b(), 1) + + } + function b() -> x { + let p, q := c() + x := add(p, q) + } + function c() -> m, n { + m := mul(d(), e()) + n := div(d(), e()) + } + function d() -> s { + for { let i := 0 } lt(i, 100) { i := add(i, 1) } + { s := add(s, i) } + } + + function e() -> s { + for { let i := 0 } lt(i, 100) { i := add(i, 1) } + { s := add(s, f(i)) } + } + function f(i) -> k { + let foo := 1 + let bar := 2 + + if iszero(mod(i,3)) { + k := or(k,foo) + } + if iszero(mod(i,5)) { + k := or(k,bar) + } + } + } +} + +// ---- +// step: constantFunctionEvaluator +// +// { +// { +// function a() -> r +// { r := 366367 } +// } +// { +// function a_4() -> r_5 +// { r_5 := 366367 } +// function b_6() -> x_7 +// { x_7 := 366366 } +// function c_10() -> m_11, n_12 +// { +// m_11 := 366300 +// n_12 := 66 +// } +// function d_13() -> s_15 +// { s_15 := 4950 } +// function e_14() -> s_17 +// { s_17 := 74 } +// function f_19(i_20) -> k_21 +// { +// let foo_22 := 1 +// let bar_23 := 2 +// if iszero(mod(i_20, 3)) { k_21 := or(k_21, foo_22) } +// if iszero(mod(i_20, 5)) { k_21 := or(k_21, bar_23) } +// } +// } +// } diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/nested_functions_not_toplevel.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/nested_functions_not_toplevel.yul new file mode 100644 index 000000000000..d36cae8c74ca --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/nested_functions_not_toplevel.yul @@ -0,0 +1,20 @@ +{ + function foo(x) -> ret + { + ret := div(x, bar()) + + function bar() -> k + { k := exp(2, 10) } + } +} +// ---- +// step: constantFunctionEvaluator +// +// { +// function foo(x) -> ret +// { +// ret := div(x, bar()) +// function bar() -> k +// { k := 1024 } +// } +// } diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/no_return_variables.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/no_return_variables.yul new file mode 100644 index 000000000000..b75f0fb3cc90 --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/no_return_variables.yul @@ -0,0 +1,34 @@ +{ + function should_be_empty() { + pop(foo(1, 2)) + } + + function should_remain() { + pop(bar(1, 2)) + } + + function foo(x, y) -> s { + s := add(x, y) + } + + function bar(x, y) -> s { + s := mul(x, y) + sstore(1, s) + } +} +// ---- +// step: constantFunctionEvaluator +// +// { +// function should_be_empty() +// { } +// function should_remain() +// { pop(bar(1, 2)) } +// function foo(x, y) -> s +// { s := add(x, y) } +// function bar(x_1, y_2) -> s_3 +// { +// s_3 := mul(x_1, y_2) +// sstore(1, s_3) +// } +// } diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/prime_check.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/prime_check.yul new file mode 100644 index 000000000000..8ab75b1c7eea --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/prime_check.yul @@ -0,0 +1,91 @@ +{ + function is_prime(x) -> res { + if lt(x, 2) + { leave } + + if eq(x, 2) + { res := true leave } + + if iszero(mod(x, 2)) + { leave } + + for { let i := 3 } iszero(gt(mul(i, i), x)) { i := add(i, 2) } + { + if iszero(mod(x, i)) + { leave } + } + res := true + } + + function c0() -> r { r := is_prime(0) } + function c1() -> r { r := is_prime(1) } + function c2() -> r { r := is_prime(2) } + function c3() -> r { r := is_prime(3) } + function c4() -> r { r := is_prime(4) } + function c5() -> r { r := is_prime(5) } + function c6() -> r { r := is_prime(6) } + function c7() -> r { r := is_prime(7) } + function c9() -> r { r := is_prime(9) } + function c69() -> r { r := is_prime(69) } + function c420() -> r { r := is_prime(420) } + // https://en.wikipedia.org/wiki/List_of_prime_numbers#Bell_primes + function c27644437() -> r { r := is_prime(27644437) } + // https://en.wikipedia.org/wiki/List_of_prime_numbers#Circular_primes + function c999331() -> r { r := is_prime(999331) } + + // The following are too big. Need better algorithm. + function c1e9plus7() -> r { r := is_prime(add(exp(10, 9), 7)) } + function c998244353() -> r { r := is_prime(998244353) } +} +// ---- +// step: constantFunctionEvaluator +// +// { +// function is_prime(x) -> res +// { +// if lt(x, 2) { leave } +// if eq(x, 2) +// { +// res := true +// leave +// } +// if iszero(mod(x, 2)) { leave } +// for { let i := 3 } iszero(gt(mul(i, i), x)) { i := add(i, 2) } +// { +// if iszero(mod(x, i)) { leave } +// } +// res := true +// } +// function c0() -> r +// { r := 0 } +// function c1() -> r_1 +// { r_1 := 0 } +// function c2() -> r_2 +// { r_2 := 1 } +// function c3() -> r_3 +// { r_3 := 1 } +// function c4() -> r_4 +// { r_4 := 0 } +// function c5() -> r_5 +// { r_5 := 1 } +// function c6() -> r_6 +// { r_6 := 0 } +// function c7() -> r_7 +// { r_7 := 1 } +// function c9() -> r_8 +// { r_8 := 0 } +// function c69() -> r_9 +// { r_9 := 0 } +// function c420() -> r_10 +// { r_10 := 0 } +// function c27644437() -> r_11 +// { r_11 := 1 } +// function c999331() -> r_12 +// { r_12 := 1 } +// function c1e9plus7() -> r_13 +// { +// r_13 := is_prime(add(exp(10, 9), 7)) +// } +// function c998244353() -> r_14 +// { r_14 := is_prime(998244353) } +// } diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/recursive_calls_to_eachother.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/recursive_calls_to_eachother.yul new file mode 100644 index 000000000000..0c442e759e52 --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/recursive_calls_to_eachother.yul @@ -0,0 +1,82 @@ +/* python program to double check +def a1(x): + if x > 0: + return a2(x - 1) + 1 + return 0 + +def a2(x): + if x > 0: + return 2 * a3(x - 1) + return 0 + +def a3(x): + if x > 0: + if x < 5: + return a1(x - 1) + return a2(x - 1) + return 0 + +print(a1(10)) +print(a2(10)) +print(a3(10)) +*/ + +{ + function a1(x) -> r { + if x { + r := add(1, a2(sub(x, 1))) + } + } + function a2(x) -> r { + if x { + r := mul(2, a3(sub(x, 1))) + } + } + function a3(x) -> r { + if x { + switch lt(x, 5) + case 1 { r := a1(sub(x, 1)) } + default { r := a2(sub(x, 1)) } + } + } + function c1() -> r { + r := a1(10) + } + function c2() -> r { + r := a2(10) + } + function c3() -> r { + r := a3(10) + } +} +// ---- +// step: constantFunctionEvaluator +// +// { +// function a1(x) -> r +// { +// if x { r := add(1, a2(sub(x, 1))) } +// } +// function a2(x_1) -> r_2 +// { +// if x_1 +// { +// r_2 := mul(2, a3(sub(x_1, 1))) +// } +// } +// function a3(x_3) -> r_4 +// { +// if x_3 +// { +// switch lt(x_3, 5) +// case 1 { r_4 := a1(sub(x_3, 1)) } +// default { r_4 := a2(sub(x_3, 1)) } +// } +// } +// function c1() -> r_5 +// { r_5 := 9 } +// function c2() -> r_6 +// { r_6 := 16 } +// function c3() -> r_7 +// { r_7 := 8 } +// } diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/recursive_factorial.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/recursive_factorial.yul new file mode 100644 index 000000000000..9df187b8ee40 --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/recursive_factorial.yul @@ -0,0 +1,52 @@ +{ + function factorial(n) -> res { + if lt(n, 2) { + res := 1 + leave + } + res := mul(factorial(sub(n, 1)), n) + } + + function f0() -> r + { r := factorial(0) } + function f1() -> r + { r := factorial(1) } + function f2() -> r + { r := factorial(2) } + function f3() -> r + { r := factorial(3) } + function f10() -> r + { r := factorial(10) } + function f20() -> r + { r := factorial(20) } + function f69() -> r + { r := factorial(69) } +} +// ---- +// step: constantFunctionEvaluator +// +// { +// function factorial(n) -> res +// { +// if lt(n, 2) +// { +// res := 1 +// leave +// } +// res := mul(factorial(sub(n, 1)), n) +// } +// function f0() -> r +// { r := 1 } +// function f1() -> r_1 +// { r_1 := 1 } +// function f2() -> r_2 +// { r_2 := 2 } +// function f3() -> r_3 +// { r_3 := 6 } +// function f10() -> r_4 +// { r_4 := 3628800 } +// function f20() -> r_5 +// { r_5 := 2432902008176640000 } +// function f69() -> r_6 +// { r_6 := factorial(69) } +// } diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/recursive_fibonacci.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/recursive_fibonacci.yul new file mode 100644 index 000000000000..8179855c3c47 --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/recursive_fibonacci.yul @@ -0,0 +1,74 @@ +{ + function fibonacci(n) -> res { + if lt(n, 2) { + res := n + leave + } + res := add(fibonacci(sub(n, 1)), fibonacci(sub(n, 2))) + } + + function f0() -> r + { r := fibonacci(0) } + function f1() -> r + { r := fibonacci(1) } + function f2() -> r + { r := fibonacci(2) } + function f3() -> r + { r := fibonacci(3) } + function f4() -> r + { r := fibonacci(4) } + function f5() -> r + { r := fibonacci(5) } + function f10() -> r + { r := fibonacci(10) } + function f11() -> r + { r := fibonacci(11) } + function f12() -> r + { r := fibonacci(12) } + function f13() -> r + { r := fibonacci(13) } + + // won't be calculated because the number of steps is too high + function f20() -> r + { r := fibonacci(20) } + function f69() -> r + { r := fibonacci(69) } +} +// ---- +// step: constantFunctionEvaluator +// +// { +// function fibonacci(n) -> res +// { +// if lt(n, 2) +// { +// res := n +// leave +// } +// res := add(fibonacci(sub(n, 1)), fibonacci(sub(n, 2))) +// } +// function f0() -> r +// { r := 0 } +// function f1() -> r_1 +// { r_1 := 1 } +// function f2() -> r_2 +// { r_2 := 1 } +// function f3() -> r_3 +// { r_3 := 2 } +// function f4() -> r_4 +// { r_4 := 3 } +// function f5() -> r_5 +// { r_5 := 5 } +// function f10() -> r_6 +// { r_6 := 55 } +// function f11() -> r_7 +// { r_7 := 89 } +// function f12() -> r_8 +// { r_8 := 144 } +// function f13() -> r_9 +// { r_9 := 233 } +// function f20() -> r_10 +// { r_10 := fibonacci(20) } +// function f69() -> r_11 +// { r_11 := fibonacci(69) } +// } diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/recursive_multi_return.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/recursive_multi_return.yul new file mode 100644 index 000000000000..fd2226ca94a9 --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/recursive_multi_return.yul @@ -0,0 +1,18 @@ +{ + function g() -> a, b { + let x, y := g() + a := x + b := y + } +} +// ---- +// step: constantFunctionEvaluator +// +// { +// function g() -> a, b +// { +// let x, y := g() +// a := x +// b := y +// } +// } diff --git a/test/libyul/yulOptimizerTests/constantFunctionEvaluator/slow_gcd.yul b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/slow_gcd.yul new file mode 100644 index 000000000000..3eb2aa23a4db --- /dev/null +++ b/test/libyul/yulOptimizerTests/constantFunctionEvaluator/slow_gcd.yul @@ -0,0 +1,45 @@ +// this mainly tests the break and continue keyword +{ + function slow_gcd(a, b) -> res + { + for { res := a } gt(res, 1) { res := sub(res, 1) } + { + if mod(a, res) { continue } + if mod(b, res) { continue } + break + } + } + + function c1() -> r { r := slow_gcd(6, 9) } + function c2() -> r { r := slow_gcd(10, 15) } + function c3() -> r { r := slow_gcd(4, 2) } + function c4() -> r { r := slow_gcd(2, 4) } + function c5() -> r { r := slow_gcd(7, 6) } + function c6() -> r { r := slow_gcd(99, 132) } +} +// ---- +// step: constantFunctionEvaluator +// +// { +// function slow_gcd(a, b) -> res +// { +// for { res := a } gt(res, 1) { res := sub(res, 1) } +// { +// if mod(a, res) { continue } +// if mod(b, res) { continue } +// break +// } +// } +// function c1() -> r +// { r := 3 } +// function c2() -> r_1 +// { r_1 := 5 } +// function c3() -> r_2 +// { r_2 := 2 } +// function c4() -> r_3 +// { r_3 := 2 } +// function c5() -> r_4 +// { r_4 := 1 } +// function c6() -> r_5 +// { r_5 := 33 } +// } diff --git a/test/libyul/yulOptimizerTests/fullSuite/checked_power.yul b/test/libyul/yulOptimizerTests/fullSuite/checked_power.yul new file mode 100644 index 000000000000..719b9b1b3d82 --- /dev/null +++ b/test/libyul/yulOptimizerTests/fullSuite/checked_power.yul @@ -0,0 +1,120 @@ +{ + function test_ok() -> r1, r2 + { + r1 := checked_exp_t_uint256_t_uint256(10, 18) + r2 := checked_exp_t_uint256_t_uint256(shl(127, 1), 2) + } + function test_overflow() -> r + { r := checked_exp_t_uint256_t_uint256(not(0), not(0)) } + + let a1, a2 := test_ok() + sstore(0, add(a1, a2)) + sstore(1, test_overflow()) + + function panic_error_0x11() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x11) + revert(0, 0x24) + } + function shift_right_1_unsigned(value) -> newValue { + newValue := shr(1, value) + } + function checked_exp_helper(_power, _base, exponent, max) -> power, base { + power := _power + base := _base + for { } gt(exponent, 1) {} + { + // overflow check for base * base + if gt(base, div(max, base)) { panic_error_0x11() } + if and(exponent, 1) + { + // No checks for power := mul(power, base) needed, because the check + // for base * base above is sufficient, since: + // |power| <= base (proof by induction) and thus: + // |power * base| <= base * base <= max <= |min| (for signed) + // (this is equally true for signed and unsigned exp) + power := mul(power, base) + } + base := mul(base, base) + exponent := shift_right_1_unsigned(exponent) + } + } + function checked_exp_unsigned(base, exponent, max) -> power { + // This function currently cannot be inlined because of the + // "leave" statements. We have to improve the optimizer. + + // Note that 0**0 == 1 + if iszero(exponent) { power := 1 leave } + if iszero(base) { power := 0 leave } + + // Specializations for small bases + switch base + // 0 is handled above + case 1 { power := 1 leave } + case 2 + { + if gt(exponent, 255) { panic_error_0x11() } + power := exp(2, exponent) + if gt(power, max) { panic_error_0x11() } + leave + } + if or( + and(lt(base, 11), lt(exponent, 78)), + and(lt(base, 307), lt(exponent, 32)) + ) + { + power := exp(base, exponent) + if gt(power, max) { panic_error_0x11() } + leave + } + + power, base := checked_exp_helper(1, base, exponent, max) + + if gt(power, div(max, base)) { panic_error_0x11() } + power := mul(power, base) + } + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + function checked_exp_t_uint256_t_uint256(base, exponent) -> power { + base := cleanup_t_uint256(base) + exponent := cleanup_t_uint256(exponent) + power := checked_exp_unsigned(base, exponent, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// step: fullSuite +// +// { +// { +// sstore(0, add(shl(254, 1), 0x0de0b6b3a7640000)) +// let power := 0 +// let _1 := 0 +// _1 := 0 +// _1 := 0 +// _1 := 0 +// let exponent := not(0) +// let power_1 := 0 +// let base := 0 +// power_1 := 1 +// base := exponent +// for { } gt(exponent, 1) { } +// { +// if gt(base, div(not(0), base)) { panic_error_0x11() } +// if and(exponent, 1) { power_1 := mul(power_1, base) } +// base := mul(base, base) +// exponent := shr(1, exponent) +// } +// if gt(power_1, div(not(0), base)) { panic_error_0x11() } +// power := mul(power_1, base) +// sstore(1, power) +// } +// function panic_error_0x11() +// { +// mstore(0, shl(224, 0x4e487b71)) +// mstore(4, 0x11) +// revert(0, 0x24) +// } +// } diff --git a/test/libyul/yulOptimizerTests/fullSuite/lots_of_dependent_constants.yul b/test/libyul/yulOptimizerTests/fullSuite/lots_of_dependent_constants.yul new file mode 100644 index 000000000000..bc395897c594 --- /dev/null +++ b/test/libyul/yulOptimizerTests/fullSuite/lots_of_dependent_constants.yul @@ -0,0 +1,727 @@ +/* +pragma solidity ^0.8.26; + +contract Test { + uint256 public constant A0 = 8; + uint256 public constant A1 = A0 * 2; + uint256 public constant A2 = A1 * 2; + uint256 public constant A3 = A2 * 2; + uint256 public constant A4 = A3 * 2; + uint256 public constant A5 = A4 * 2; + uint256 public constant A6 = A5 * 2; + uint256 public constant A7 = A6 * 2; + uint256 public constant A8 = A7 * 2; + uint256 public constant A9 = A8 * 2; + uint256 public constant A10 = A9 * 2; + + function test(uint256 x) public pure returns (uint256) { + return x / A10; + } +} +*/ + +{ + /// @src 0:26:582 "contract Test {..." + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0x29e99f07 + { + // test(uint256) + + external_fun_test_66() + } + + case 0x3c823131 + { + // A6() + + external_fun_A6_34() + } + + case 0x4a23d454 + { + // A7() + + external_fun_A7_39() + } + + case 0x5902c17a + { + // A2() + + external_fun_A2_14() + } + + case 0x5cc23f7d + { + // A0() + + external_fun_A0_4() + } + + case 0x7d6d1f39 + { + // A4() + + external_fun_A4_24() + } + + case 0x97a28744 + { + // A10() + + external_fun_A10_54() + } + + case 0x9f08ce4f + { + // A5() + + external_fun_A5_29() + } + + case 0xa33eadce + { + // A3() + + external_fun_A3_19() + } + + case 0xca035e93 + { + // A9() + + external_fun_A9_49() + } + + case 0xd173ee61 + { + // A8() + + external_fun_A8_44() + } + + case 0xf8341309 + { + // A1() + + external_fun_A1_9() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) + } + + } + + function abi_encode_t_uint256_to_t_uint256_fromStack(value, pos) { + mstore(pos, cleanup_t_uint256(value)) + } + + function abi_encode_tuple_t_uint256__to_t_uint256__fromStack(headStart , value0) -> tail { + tail := add(headStart, 32) + + abi_encode_t_uint256_to_t_uint256_fromStack(value0, add(headStart, 0)) + + } + + function external_fun_test_66() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + let ret_0 := fun_test_66(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple_t_uint256__to_t_uint256__fromStack(memPos , ret_0) + return(memPos, sub(memEnd, memPos)) + + } + + function abi_decode_tuple_(headStart, dataEnd) { + if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + } + + function cleanup_t_rational_8_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_8_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_8_by_1(value))) + } + + /// @src 0:46:76 "uint256 public constant A0 = 8" + function constant_A0_4() -> ret { + /// @src 0:75:76 "8" + let expr_3 := 0x08 + let _1 := convert_t_rational_8_by_1_to_t_uint256(expr_3) + + ret := _1 + } + + function cleanup_t_rational_2_by_1(value) -> cleaned { + cleaned := value + } + + function convert_t_rational_2_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_2_by_1(value))) + } + + function panic_error_0x11() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x11) + revert(0, 0x24) + } + + function checked_mul_t_uint256(x, y) -> product { + x := cleanup_t_uint256(x) + y := cleanup_t_uint256(y) + let product_raw := mul(x, y) + product := cleanup_t_uint256(product_raw) + + // overflow, if x != 0 and y != product/x + if iszero( + or( + iszero(x), + eq(y, div(product, x)) + ) + ) { panic_error_0x11() } + + } + + /// @src 0:82:117 "uint256 public constant A1 = A0 * 2" + function constant_A1_9() -> ret { + /// @src 0:111:113 "A0" + let expr_6 := constant_A0_4() + /// @src 0:116:117 "2" + let expr_7 := 0x02 + /// @src 0:111:117 "A0 * 2" + let expr_8 := checked_mul_t_uint256(expr_6, convert_t_rational_2_by_1_to_t_uint256(expr_7)) + + let _2 := expr_8 + + ret := _2 + } + + /// @src 0:123:158 "uint256 public constant A2 = A1 * 2" + function constant_A2_14() -> ret { + /// @src 0:152:154 "A1" + let expr_11 := constant_A1_9() + /// @src 0:157:158 "2" + let expr_12 := 0x02 + /// @src 0:152:158 "A1 * 2" + let expr_13 := checked_mul_t_uint256(expr_11, convert_t_rational_2_by_1_to_t_uint256(expr_12)) + + let _3 := expr_13 + + ret := _3 + } + + /// @src 0:164:199 "uint256 public constant A3 = A2 * 2" + function constant_A3_19() -> ret { + /// @src 0:193:195 "A2" + let expr_16 := constant_A2_14() + /// @src 0:198:199 "2" + let expr_17 := 0x02 + /// @src 0:193:199 "A2 * 2" + let expr_18 := checked_mul_t_uint256(expr_16, convert_t_rational_2_by_1_to_t_uint256(expr_17)) + + let _4 := expr_18 + + ret := _4 + } + + /// @src 0:205:240 "uint256 public constant A4 = A3 * 2" + function constant_A4_24() -> ret { + /// @src 0:234:236 "A3" + let expr_21 := constant_A3_19() + /// @src 0:239:240 "2" + let expr_22 := 0x02 + /// @src 0:234:240 "A3 * 2" + let expr_23 := checked_mul_t_uint256(expr_21, convert_t_rational_2_by_1_to_t_uint256(expr_22)) + + let _5 := expr_23 + + ret := _5 + } + + /// @src 0:246:281 "uint256 public constant A5 = A4 * 2" + function constant_A5_29() -> ret { + /// @src 0:275:277 "A4" + let expr_26 := constant_A4_24() + /// @src 0:280:281 "2" + let expr_27 := 0x02 + /// @src 0:275:281 "A4 * 2" + let expr_28 := checked_mul_t_uint256(expr_26, convert_t_rational_2_by_1_to_t_uint256(expr_27)) + + let _6 := expr_28 + + ret := _6 + } + + /// @src 0:287:322 "uint256 public constant A6 = A5 * 2" + function constant_A6_34() -> ret { + /// @src 0:316:318 "A5" + let expr_31 := constant_A5_29() + /// @src 0:321:322 "2" + let expr_32 := 0x02 + /// @src 0:316:322 "A5 * 2" + let expr_33 := checked_mul_t_uint256(expr_31, convert_t_rational_2_by_1_to_t_uint256(expr_32)) + + let _7 := expr_33 + + ret := _7 + } + + /// @ast-id 34 + /// @src 0:287:322 "uint256 public constant A6 = A5 * 2" + function getter_fun_A6_34() -> ret_0 { + ret_0 := constant_A6_34() + } + /// @src 0:26:582 "contract Test {..." + + function external_fun_A6_34() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + let ret_0 := getter_fun_A6_34() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple_t_uint256__to_t_uint256__fromStack(memPos , ret_0) + return(memPos, sub(memEnd, memPos)) + + } + + /// @src 0:328:363 "uint256 public constant A7 = A6 * 2" + function constant_A7_39() -> ret { + /// @src 0:357:359 "A6" + let expr_36 := constant_A6_34() + /// @src 0:362:363 "2" + let expr_37 := 0x02 + /// @src 0:357:363 "A6 * 2" + let expr_38 := checked_mul_t_uint256(expr_36, convert_t_rational_2_by_1_to_t_uint256(expr_37)) + + let _8 := expr_38 + + ret := _8 + } + + /// @ast-id 39 + /// @src 0:328:363 "uint256 public constant A7 = A6 * 2" + function getter_fun_A7_39() -> ret_0 { + ret_0 := constant_A7_39() + } + /// @src 0:26:582 "contract Test {..." + + function external_fun_A7_39() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + let ret_0 := getter_fun_A7_39() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple_t_uint256__to_t_uint256__fromStack(memPos , ret_0) + return(memPos, sub(memEnd, memPos)) + + } + + /// @ast-id 14 + /// @src 0:123:158 "uint256 public constant A2 = A1 * 2" + function getter_fun_A2_14() -> ret_0 { + ret_0 := constant_A2_14() + } + /// @src 0:26:582 "contract Test {..." + + function external_fun_A2_14() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + let ret_0 := getter_fun_A2_14() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple_t_uint256__to_t_uint256__fromStack(memPos , ret_0) + return(memPos, sub(memEnd, memPos)) + + } + + /// @ast-id 4 + /// @src 0:46:76 "uint256 public constant A0 = 8" + function getter_fun_A0_4() -> ret_0 { + ret_0 := constant_A0_4() + } + /// @src 0:26:582 "contract Test {..." + + function external_fun_A0_4() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + let ret_0 := getter_fun_A0_4() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple_t_uint256__to_t_uint256__fromStack(memPos , ret_0) + return(memPos, sub(memEnd, memPos)) + + } + + /// @ast-id 24 + /// @src 0:205:240 "uint256 public constant A4 = A3 * 2" + function getter_fun_A4_24() -> ret_0 { + ret_0 := constant_A4_24() + } + /// @src 0:26:582 "contract Test {..." + + function external_fun_A4_24() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + let ret_0 := getter_fun_A4_24() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple_t_uint256__to_t_uint256__fromStack(memPos , ret_0) + return(memPos, sub(memEnd, memPos)) + + } + + /// @src 0:369:404 "uint256 public constant A8 = A7 * 2" + function constant_A8_44() -> ret { + /// @src 0:398:400 "A7" + let expr_41 := constant_A7_39() + /// @src 0:403:404 "2" + let expr_42 := 0x02 + /// @src 0:398:404 "A7 * 2" + let expr_43 := checked_mul_t_uint256(expr_41, convert_t_rational_2_by_1_to_t_uint256(expr_42)) + + let _9 := expr_43 + + ret := _9 + } + + /// @src 0:410:445 "uint256 public constant A9 = A8 * 2" + function constant_A9_49() -> ret { + /// @src 0:439:441 "A8" + let expr_46 := constant_A8_44() + /// @src 0:444:445 "2" + let expr_47 := 0x02 + /// @src 0:439:445 "A8 * 2" + let expr_48 := checked_mul_t_uint256(expr_46, convert_t_rational_2_by_1_to_t_uint256(expr_47)) + + let _10 := expr_48 + + ret := _10 + } + + /// @src 0:451:487 "uint256 public constant A10 = A9 * 2" + function constant_A10_54() -> ret { + /// @src 0:481:483 "A9" + let expr_51 := constant_A9_49() + /// @src 0:486:487 "2" + let expr_52 := 0x02 + /// @src 0:481:487 "A9 * 2" + let expr_53 := checked_mul_t_uint256(expr_51, convert_t_rational_2_by_1_to_t_uint256(expr_52)) + + let _11 := expr_53 + + ret := _11 + } + + /// @ast-id 54 + /// @src 0:451:487 "uint256 public constant A10 = A9 * 2" + function getter_fun_A10_54() -> ret_0 { + ret_0 := constant_A10_54() + } + /// @src 0:26:582 "contract Test {..." + + function external_fun_A10_54() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + let ret_0 := getter_fun_A10_54() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple_t_uint256__to_t_uint256__fromStack(memPos , ret_0) + return(memPos, sub(memEnd, memPos)) + + } + + /// @ast-id 29 + /// @src 0:246:281 "uint256 public constant A5 = A4 * 2" + function getter_fun_A5_29() -> ret_0 { + ret_0 := constant_A5_29() + } + /// @src 0:26:582 "contract Test {..." + + function external_fun_A5_29() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + let ret_0 := getter_fun_A5_29() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple_t_uint256__to_t_uint256__fromStack(memPos , ret_0) + return(memPos, sub(memEnd, memPos)) + + } + + /// @ast-id 19 + /// @src 0:164:199 "uint256 public constant A3 = A2 * 2" + function getter_fun_A3_19() -> ret_0 { + ret_0 := constant_A3_19() + } + /// @src 0:26:582 "contract Test {..." + + function external_fun_A3_19() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + let ret_0 := getter_fun_A3_19() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple_t_uint256__to_t_uint256__fromStack(memPos , ret_0) + return(memPos, sub(memEnd, memPos)) + + } + + /// @ast-id 49 + /// @src 0:410:445 "uint256 public constant A9 = A8 * 2" + function getter_fun_A9_49() -> ret_0 { + ret_0 := constant_A9_49() + } + /// @src 0:26:582 "contract Test {..." + + function external_fun_A9_49() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + let ret_0 := getter_fun_A9_49() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple_t_uint256__to_t_uint256__fromStack(memPos , ret_0) + return(memPos, sub(memEnd, memPos)) + + } + + /// @ast-id 44 + /// @src 0:369:404 "uint256 public constant A8 = A7 * 2" + function getter_fun_A8_44() -> ret_0 { + ret_0 := constant_A8_44() + } + /// @src 0:26:582 "contract Test {..." + + function external_fun_A8_44() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + let ret_0 := getter_fun_A8_44() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple_t_uint256__to_t_uint256__fromStack(memPos , ret_0) + return(memPos, sub(memEnd, memPos)) + + } + + /// @ast-id 9 + /// @src 0:82:117 "uint256 public constant A1 = A0 * 2" + function getter_fun_A1_9() -> ret_0 { + ret_0 := constant_A1_9() + } + /// @src 0:26:582 "contract Test {..." + + function external_fun_A1_9() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + let ret_0 := getter_fun_A1_9() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple_t_uint256__to_t_uint256__fromStack(memPos , ret_0) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + function zero_value_for_split_t_uint256() -> ret { + ret := 0 + } + + function panic_error_0x12() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x12) + revert(0, 0x24) + } + + function checked_div_t_uint256(x, y) -> r { + x := cleanup_t_uint256(x) + y := cleanup_t_uint256(y) + if iszero(y) { panic_error_0x12() } + + r := div(x, y) + } + + /// @ast-id 66 + /// @src 0:494:580 "function test(uint256 x) public pure returns (uint256) {..." + function fun_test_66(var_x_56) -> var__59 { + /// @src 0:540:547 "uint256" + let zero_t_uint256_12 := zero_value_for_split_t_uint256() + var__59 := zero_t_uint256_12 + + /// @src 0:566:567 "x" + let _13 := var_x_56 + let expr_61 := _13 + /// @src 0:570:573 "A10" + let expr_62 := constant_A10_54() + /// @src 0:566:573 "x / A10" + let expr_63 := checked_div_t_uint256(expr_61, expr_62) + + /// @src 0:559:573 "return x / A10" + var__59 := expr_63 + leave + + } + /// @src 0:26:582 "contract Test {..." + +} + +// ---- +// step: fullSuite +// +// { +// { +// let _1 := memoryguard(0x80) +// mstore(64, _1) +// if iszero(lt(calldatasize(), 4)) +// { +// switch shr(224, calldataload(0)) +// case 0x29e99f07 { +// if callvalue() { revert(0, 0) } +// if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } +// mstore(_1, shr(13, calldataload(4))) +// return(_1, 32) +// } +// case 0x3c823131 { +// if callvalue() { revert(0, 0) } +// if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } +// let memPos := mload(64) +// mstore(memPos, 512) +// return(memPos, 32) +// } +// case 0x4a23d454 { +// if callvalue() { revert(0, 0) } +// if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } +// let memPos_1 := mload(64) +// mstore(memPos_1, 1024) +// return(memPos_1, 32) +// } +// case 0x5902c17a { +// if callvalue() { revert(0, 0) } +// if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } +// let memPos_2 := mload(64) +// mstore(memPos_2, 32) +// return(memPos_2, 32) +// } +// case 0x5cc23f7d { +// if callvalue() { revert(0, 0) } +// if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } +// let memPos_3 := mload(64) +// mstore(memPos_3, 8) +// return(memPos_3, 32) +// } +// case 0x7d6d1f39 { +// if callvalue() { revert(0, 0) } +// if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } +// let memPos_4 := mload(64) +// mstore(memPos_4, 128) +// return(memPos_4, 32) +// } +// case 0x97a28744 { +// if callvalue() { revert(0, 0) } +// if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } +// let memPos_5 := mload(64) +// mstore(memPos_5, 8192) +// return(memPos_5, 32) +// } +// case 0x9f08ce4f { +// if callvalue() { revert(0, 0) } +// if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } +// let memPos_6 := mload(64) +// mstore(memPos_6, 256) +// return(memPos_6, 32) +// } +// case 0xa33eadce { +// if callvalue() { revert(0, 0) } +// if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } +// let memPos_7 := mload(64) +// mstore(memPos_7, 64) +// return(memPos_7, 32) +// } +// case 0xca035e93 { +// if callvalue() { revert(0, 0) } +// if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } +// let memPos_8 := mload(64) +// mstore(memPos_8, 4096) +// return(memPos_8, 32) +// } +// case 0xd173ee61 { +// if callvalue() { revert(0, 0) } +// if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } +// let memPos_9 := mload(64) +// mstore(memPos_9, 2048) +// return(memPos_9, 32) +// } +// case 0xf8341309 { +// if callvalue() { revert(0, 0) } +// if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } +// let memPos_10 := mload(64) +// mstore(memPos_10, 16) +// return(memPos_10, 32) +// } +// } +// revert(0, 0) +// } +// } diff --git a/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul b/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul index 5fbe8d22e615..c2ab594a429a 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul @@ -40,25 +40,12 @@ // // { // { -// let _1 := gt(not(gcd(10, 15)), 1) -// let _2 := gcd(10, 15) -// let _3 := lt(or(1, add(gcd(10, 15), not(0))), 1) -// let _4 := gcd(10, 15) -// let _5 := gcd(10, 15) -// pop(keccak256(gcd(10, 15), or(gt(not(gcd(10, 15)), 1), 1))) -// mstore(lt(or(gt(1, or(or(gt(or(or(or(gt(or(gt(not(0), _5), 1), _4), _3), _2), 1), 1), _1), 1)), 1), 1), 1) -// sstore(not(gcd(10, 15)), 1) +// pop(keccak256(5, 1)) +// mstore(0, 1) +// sstore(not(5), 1) // sstore(2, 1) -// foo_singlereturn() +// extcodecopy(1, msize(), 1, 1) // sstore(0, 0) // sstore(3, 1) // } -// function gcd(_a, _b) -> out -// { -// switch _b -// case 0 { out := _a } -// default { out := gcd(_b, mod(_a, _b)) } -// } -// function foo_singlereturn() -// { extcodecopy(1, msize(), 1, 1) } // } diff --git a/test/yulPhaser/Chromosome.cpp b/test/yulPhaser/Chromosome.cpp index da109086a916..dda087857374 100644 --- a/test/yulPhaser/Chromosome.cpp +++ b/test/yulPhaser/Chromosome.cpp @@ -137,7 +137,7 @@ BOOST_AUTO_TEST_CASE(output_operator_should_create_concise_and_unambiguous_strin BOOST_TEST(chromosome.length() == allSteps.size()); BOOST_TEST(chromosome.optimisationSteps() == allSteps); - BOOST_TEST(toString(chromosome) == "flcCUnDEvejsxIOoighFTLMmVatrpuSd"); + BOOST_TEST(toString(chromosome) == "flcCUknDEvejsxIOoighFTLMmVatrpuSd"); } BOOST_AUTO_TEST_CASE(optimisationSteps_should_translate_chromosomes_genes_to_optimisation_step_names)