Skip to content

Commit 3b6c2e6

Browse files
authored
Merge pull request #16765 from argotorg/ssa-change-arg-order
SSA-CFG: Store function call arguments in the same order as Yul
2 parents 839e2c3 + 1ae5f58 commit 3b6c2e6

17 files changed

Lines changed: 391 additions & 382 deletions

File tree

libyul/backends/evm/ssa/CodeTransform.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ void CodeTransform::operator()(InstId _instId, StackData const& _operationInputL
235235
yulAssert(m_stack.size() >= _inst.inputs.size());
236236
for (auto const& [stackEntry, input]: ranges::views::zip(
237237
m_stack | ranges::views::take_last(_inst.inputs.size()),
238-
_inst.inputs
238+
_inst.inputs | ranges::views::reverse
239239
))
240240
yulAssert(stackEntry.isValue() && stackEntry.value() == input);
241241

libyul/backends/evm/ssa/SSACFGBuilder.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <libsolutil/StringUtils.h>
3333
#include <libsolutil/Visitor.h>
3434

35+
#include <range/v3/algorithm/reverse.hpp>
3536
#include <range/v3/range/conversion.hpp>
3637
#include <range/v3/view/drop_last.hpp>
3738
#include <range/v3/view/enumerate.hpp>
@@ -235,7 +236,7 @@ void SSACFGBuilder::operator()(Switch const& _switch)
235236
return m_graph.makeBuiltinCallWithProjections(
236237
m_currentBlock,
237238
SSACFG::BuiltinCall{*equalityBuiltinHandle, {}},
238-
{m_graph.newLiteral(debugDataOf(_case), _case.value->value.value()), expression},
239+
{expression, m_graph.newLiteral(debugDataOf(_case), _case.value->value.value())},
239240
static_cast<InstructionStore::NumReturnsSizeType>(equalityBuiltin.numReturns),
240241
debugDataOf(_case)
241242
);
@@ -477,10 +478,13 @@ InstId SSACFGBuilder::visitFunctionCall(FunctionCall const& _call)
477478
yulAssert(std::holds_alternative<Literal>(arg));
478479
literalArguments.emplace_back(std::get<Literal>(arg));
479480
}
481+
// Arguments must be evaluated from right to left, according to Yul specification
480482
std::vector<InstId> inputs;
481483
for (auto&& [idx, arg]: _call.arguments | ranges::views::enumerate | ranges::views::reverse)
482484
if (!builtin.literalArgument(idx).has_value())
483485
inputs.emplace_back(std::visit(*this, arg));
486+
// But we want to store them in the original order
487+
ranges::reverse(inputs);
484488
canContinue = builtin.controlFlowSideEffects.canContinue;
485489
return m_graph.makeBuiltinCallWithProjections(
486490
m_currentBlock,
@@ -497,9 +501,12 @@ InstId SSACFGBuilder::visitFunctionCall(FunctionCall const& _call)
497501
auto const calleeIt = m_functionRegistry.find(&function);
498502
yulAssert(calleeIt != m_functionRegistry.end(), "Called function has no registered graph id.");
499503
canContinue = m_sideEffects.functionSideEffects().at(calleeIt->second.definition).canContinue;
504+
// Arguments must be evaluated from right to left, according to Yul specification
500505
std::vector<InstId> inputs;
501506
for (auto const& arg: _call.arguments | ranges::views::reverse)
502507
inputs.emplace_back(std::visit(*this, arg));
508+
// But we want to store them in the original order
509+
ranges::reverse(inputs);
503510
return m_graph.makeCallWithProjections(
504511
m_currentBlock,
505512
SSACFG::Call{calleeIt->second.id, canContinue, function.numReturns},

libyul/backends/evm/ssa/StackLayoutGenerator.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,10 @@ void StackLayoutGenerator::visitBlock(SSACFG::BlockId const& _blockId)
251251
requiredStackTop.emplace_back(Slot::makeFunctionCallReturnLabel(*callSiteID));
252252
}
253253
}
254-
requiredStackTop += _inst.inputs | ranges::views::transform([this](InstId const& _id) { return StackSlot::makeValue(m_cfg, _id); });
254+
requiredStackTop +=
255+
_inst.inputs |
256+
ranges::views::reverse |
257+
ranges::views::transform([this](InstId const& _id) { return StackSlot::makeValue(m_cfg, _id); });
255258

256259
for (StackType::Depth depth{0}; depth < stack.size(); ++depth.value)
257260
if (

libyul/backends/evm/ssa/io/Printer.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include <fmt/format.h>
3131
#include <fmt/ranges.h>
3232

33-
#include <range/v3/view/reverse.hpp>
3433
#include <range/v3/view/transform.hpp>
3534
#include <range/v3/view/zip.hpp>
3635

@@ -74,7 +73,7 @@ void printBuiltinOperands(
7473
_out << ' ';
7574

7675
auto litIt = payload.literalArguments.begin();
77-
auto valIt = _inst.inputs.rbegin();
76+
auto valIt = _inst.inputs.begin();
7877
for (std::size_t i = 0; i < builtin.numParameters; ++i)
7978
{
8079
if (i > 0)
@@ -86,7 +85,7 @@ void printBuiltinOperands(
8685
}
8786
else
8887
{
89-
yulAssert(valIt != _inst.inputs.rend());
88+
yulAssert(valIt != _inst.inputs.end());
9089
_out << formatValueRef(*valIt++);
9190
}
9291
}
@@ -111,12 +110,12 @@ void printCallOperands(
111110

112111
_out << ' ';
113112
bool first = true;
114-
for (auto it = _inst.inputs.rbegin(); it != _inst.inputs.rend(); ++it)
113+
for (auto const input: _inst.inputs)
115114
{
116115
if (!first)
117116
_out << ", ";
118117
first = false;
119-
_out << formatValueRef(*it);
118+
_out << formatValueRef(input);
120119
}
121120
}
122121

0 commit comments

Comments
 (0)