Skip to content

Commit 140fdbd

Browse files
committed
ssa cfg builder: treat constant switches explicitly
1 parent 84dd707 commit 140fdbd

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

libyul/backends/evm/SSAControlFlowGraphBuilder.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,28 @@ void SSAControlFlowGraphBuilder::operator()(Switch const& _switch)
355355
}
356356
else
357357
{
358+
if (auto const* constantExpression = std::get_if<Literal>(_switch.expression.get()))
359+
{
360+
Case const* matchedCase = nullptr;
361+
// select case that matches (or default if available)
362+
for (auto const& switchCase: _switch.cases)
363+
{
364+
if (!switchCase.value)
365+
matchedCase = &switchCase;
366+
if (switchCase.value && switchCase.value->value.value() == constantExpression->value.value())
367+
{
368+
matchedCase = &switchCase;
369+
break;
370+
}
371+
}
372+
if (matchedCase)
373+
{
374+
// inject directly into the current block
375+
(*this)(matchedCase->body);
376+
}
377+
return;
378+
}
379+
358380
std::optional<BuiltinHandle> equalityBuiltinHandle = m_dialect.equalityFunctionHandle();
359381
yulAssert(equalityBuiltinHandle);
360382

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
let x := calldataload(3)
3+
4+
// this should yield calldataload(88) directly
5+
switch 1
6+
case 0 {
7+
x := calldataload(77)
8+
}
9+
case 1 {
10+
x := calldataload(88)
11+
}
12+
default {
13+
x := calldataload(99)
14+
}
15+
16+
// this should yield the default case
17+
switch 55
18+
case 0 {
19+
x := calldataload(77)
20+
}
21+
case 1 {
22+
x := calldataload(88)
23+
}
24+
default {
25+
x := calldataload(99)
26+
}
27+
28+
// this should be skipped entirely
29+
switch 66
30+
case 0 {
31+
x := calldataload(77)
32+
}
33+
case 1 {
34+
x := calldataload(88)
35+
}
36+
sstore(x, 0)
37+
}
38+
// ----
39+
// digraph SSACFG {
40+
// nodesep=0.7;
41+
// graph[fontname="DejaVu Sans"]
42+
// node[shape=box,fontname="DejaVu Sans"];
43+
//
44+
// Entry0 [label="Entry"];
45+
// Entry0 -> Block0_0;
46+
// Block0_0 [label="\
47+
// Block 0; (0, max 0)\nLiveIn: \l\
48+
// LiveOut: \l\nv1 := calldataload(3)\l\
49+
// v4 := calldataload(88)\l\
50+
// v7 := calldataload(99)\l\
51+
// sstore(0, v7)\l\
52+
// "];
53+
// Block0_0Exit [label="MainExit"];
54+
// Block0_0 -> Block0_0Exit;
55+
// }

0 commit comments

Comments
 (0)