[llvm-bugs] [Bug 41502] New: WebAssembly isel breaks up small switches

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Apr 15 09:53:14 PDT 2019


https://bugs.llvm.org/show_bug.cgi?id=41502

            Bug ID: 41502
           Summary: WebAssembly isel breaks up small switches
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Backend: WebAssembly
          Assignee: unassignedbugs at nondot.org
          Reporter: alonzakai at gmail.com
                CC: llvm-bugs at lists.llvm.org

Created attachment 21774
  --> https://bugs.llvm.org/attachment.cgi?id=21774&action=edit
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?

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190415/b318f373/attachment-0001.html>


More information about the llvm-bugs mailing list