<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/63909>63909</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[WebAssembly] Switch lowering
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
dschuff,
aheejin
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
sparker-arm
</td>
</tr>
</table>
<pre>
The WebAssembly backend is very keen to lower switches to branch tables, with the argument being that it is better for code size. I've found that this isn't the case, and that the behaviour of switch lowering is dependent on the case values. The following two functions are the same, except for the case values, but the first is lowered to a `br_table` whereas the second isn't:
```
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn writeonly
define hidden void @_Z25conditional_store_1_20_50Pii(i32* nocapture noundef writeonly %0, i32 noundef %1) local_unnamed_addr #0 {
switch i32 %1, label %4 [
i32 50, label %3
i32 20, label %3
i32 1, label %3
]
3: ; preds = %2, %2, %2
store i32 %1, i32* %0, align 4, !tbaa !2
br label %4
4: ; preds = %2, %3
ret void
}
define hidden void @_Z26conditional_store_1_50_100Pii(i32* nocapture noundef writeonly %0, i32 noundef %1) local_unnamed_addr #0 {
switch i32 %1, label %4 [
i32 100, label %3
i32 50, label %3
i32 1, label %3
]
3: ; preds = %2, %2, %2
store i32 %1, i32* %0, align 4, !tbaa !2
br label %4
4: ; preds = %2, %3
ret void
}
```
Using a `br_table` results in the first function being 53 bytes, versus 37 when three conditional branches.
```
000071 func[1] <_Z25conditional_store_1_20_50Pii>:
000072: 02 40 | block
000074: 02 40 | block
000076: 02 40 | block
000078: 20 01 | local.get 1
00007a: 41 7f | i32.const 4294967295
00007c: 6a | i32.add
00007d: 0e 14 01 02 02 02 02 02 02 | br_table 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 0
000086: 02 02 02 02 02 02 02 02 02 |
00008f: 02 02 02 01 00 |
000094: 0b | end
000095: 20 01 | local.get 1
000097: 41 32 | i32.const 50
000099: 47 | i32.ne
00009a: 0d 01 | br_if 1
00009c: 0b | end
00009d: 20 00 | local.get 0
00009f: 20 01 | local.get 1
0000a1: 36 02 00 | i32.store 2 0
0000a4: 0b | end
0000a5: 0b | end
```
I noticed this when looking at some rather ugly codegen from V8, as having a largely empty `br_table` currently isn't optimised. Is there something LLVM can do about this, or is this something consumers just need to handle?
>From a brief browse, I don't think the current interface between the backend and switch lowering is sufficient, and I don't understand why the specific case values are affecting the behaviour.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8V0tv4zgS_jX0pdAGRb2igw95rIEAvcACu9sDzMWgyJLFDk0aJBWP59cPSMmxnHYePYMZR7Ais76qrx4sFbn3amsQV6S8I4xJL_qh6whjhN0TxniP-F2Z-Fw-LPgQeutWfs_dE7ov3O0WrZXH1f96hF-wvfUed60-QsvFExoJysMzuiM8IRoIFrQ9oAN_UEH06OMvreNG9BB4q9ETdg8HFXoIPQJ322GHJkCLymwh9DyAClFliyGgg846EFYiePU7LuGRsPoZobODkaN06JUH5Q1hdUgqBfcYbfCzBEKLPX9WdnBgu4nayDNaVR4k7tHISMSaFy3wzPWAfgnR885qbQ-J5MFCNxgRlDUeuMME8HyXzOJvAvch8X6lJ662w8inU84nNxMJlDFKHEhFW7dJYSIVhUOPDrkf1aOwKdbJUZLfEvpA6Om7otM1PuZ3sJ4Iwm0IzpP8FnaDD3tntw69B2M7hwjGOhSD8_E_fzQCjB3MQRkJB6W1wzA4AwenAlqjj6N2iZ0yCL2SEg08WyWBFHTzKysjQxWNcr3xwTrcZBtGNyX9j1KE3aicEXYLxgq-D4PDZExidzYAhJU0hknl7GWVsDIjrAFtBdebwRi-Q7nhUjogLKdA6ruR2CmvETyC7kHzFnV8KiCW_igHkGRGUy8S-eUqu74al7LrOFI-zJOSx6DHVOwdSg8kf4jSccdd3id0CtgF9ylep5hwrbYGihGXhZbzeD_hWzfzdU6jiDR-8vMm6xdfHYaU-slSfeH5mxVSXauQkm4y-k-VyM_WSEbfLZL3S-jvqJO_WCYf1MmfT_yrDpS-_-9ju_yhrTn0gw4elJm1wlNDnV4EZQ7tMYw98xmdHzzkdWyIERM716ySptcL-uU7PZFSSussmSHlXUbKByD5_YddK__XS6uFpILFMFEGBX1j69T30Gornuag4hMg-BFWnWGjxBWZmyjDKNDsbdVpWyy3GCCbQ3mEFhnU3XuspmJeCmt8gII1RVPVrCnnmkTUVPG3-8mFJi7lHCyTlwhZEZ2g7PV1Bp-KCDJgn_jLgM7s3Jyi-dYV7czlu0v5DCh9LdOMiW0_dBzN3OWm_ETS4ud64pp6Slx-Ds45Q-Xc6aZJovWHBCPe4ByZqoPKDzm2bqO6S35iisoo8sp3efL93b1w9vzCne5TgbseNp5FcF6lbJ52VPR7bKnswhL_TGYvPePlz0CuNsxHMDYoEcfBONWmdqetfUptNIC3OwTHQ48Ohq0-psF4iwY6Z3fw7Sa1fw9x0k19V3O3RX0E3O3D8XUXFoNzaII-vgzPdh_UTnmUS3hMQ6fDZDL0Ud3Xr9_-DYIbkBZ4a4dx8o4mrYuDbGJ8Fo_FOOzQefg--AAGxxm350ZqJPl67vY60ufQOoUdtM4exgH-EaQ9jfXKPI3j9MgalAnoOi7iZB8O6eARp_zpRBJH_ytDvh-6TgmFJpzOB2cTcZBwPsQfD_1xHLn3KFSnxHyGT-M-7zoUYTyvzI4Wy4Vc5bLJG77AVVbdNBXN8qJe9KtCYCkkq4o8L3IpMixuuopmXZM12BS8XqgVoyyndVZnecFYvWxyWlV1WcmOcVE1FSko7rjSS62fd0vrtgvl_YCrKm9os0hvdD8d7gweIC1Oxzm3ipgv7bD1pKBa-eDPWoIKOp0KZwe7-G7872X0FoPTqz6EfTxJELYmbL1VoR_apbA7wtZR33T7snf2O4pA2Dqx8IStE8s_AgAA__9wLP55">