<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - WebAssembly isel breaks up small switches"
href="https://bugs.llvm.org/show_bug.cgi?id=41502">41502</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>WebAssembly isel breaks up small switches
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Backend: WebAssembly
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>alonzakai@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=21774" name="attach_21774" title="testcase for llc">attachment 21774</a> <a href="attachment.cgi?id=21774&action=edit" title="testcase for llc">[details]</a></span>
testcase for llc
In the attached small testcase, we started with
===
extern "C" int A();
extern "C" void B();
extern "C" void C();
extern "C" void D();
extern "C" void E();
int main() {
switch (A())
{
case 0:
B();
case 1:
C();
case 2:
D();
default:
E();
}
}
===
And the optimized LLVM IR includes
===
switch i32 %call, label %sw.default [
i32 0, label %sw.bb
i32 1, label %sw.bb1
i32 2, label %sw.bb2
]
[..]
===
In asm2wasm, this gets lowered to the expected
===
(block $label$1
(block $label$2
(block $label$3
(block $label$4
(br_table $label$4 $label$3 $label$2 $label$1
(call $_A)
)
)
(call $_B)
)
(call $_C)
)
(call $_D)
)
(call $_E)
===
In the wasm backend isel though the switch is broken up into sequential br_ifs
that compare the various values,
===
bb.0.entry:
successors: %bb.3(0x20000000), %bb.5(0x60000000); %bb.3(25.00%),
%bb.5(75.00%)
liveins: $arguments
%1:i32 = CONST_I32 2, implicit-def dead $arguments
%0:i32 = CALL_I32 @A, implicit-def dead $arguments, implicit $sp32, implicit
$sp64
%2:i32 = EQ_I32 %0:i32, killed %1:i32, implicit-def dead $arguments
BR_IF %bb.3, killed %2:i32, implicit-def dead $arguments
BR %bb.5, implicit-def dead $arguments
bb.5.entry:
; predecessors: %bb.0
successors: %bb.2(0x2aaaaaab), %bb.6(0x55555555); %bb.2(33.33%),
%bb.6(66.67%)
%3:i32 = CONST_I32 1, implicit-def dead $arguments
%4:i32 = EQ_I32 %0:i32, killed %3:i32, implicit-def dead $arguments
BR_IF %bb.2, killed %4:i32, implicit-def dead $arguments
BR %bb.6, implicit-def dead $arguments
bb.6.entry:
; predecessors: %bb.5
successors: %bb.1(0x40000000), %bb.4(0x40000000); %bb.1(50.00%),
%bb.4(50.00%)
BR_IF %bb.4, %0:i32, implicit-def dead $arguments
BR %bb.1, implicit-def dead $arguments
[..]
===
This is larger and looks less efficient. Why is it avoiding a br_table here?</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>