<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>