<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/136353>136353</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [WebAssembly] Incorrect stackification of effectful instructions
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          SingleAccretion
      </td>
    </tr>
</table>

<pre>
    Reading the stackification code, I came across this in `WebAssemblyRegStackify.cpp / static void query`:
```
// These instructions have hasUnmodeledSideEffects() returning true
// because they trap on overflow and invalid so they can't be arbitrarily
// moved, however in the specific case of register stackifying, it is safe
// to move them because overflow and invalid are Undefined Behavior.
```
Which prompted me to think about this this example:
```llvm
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
target triple = "wasm32-unknown-wasi"

declare i32 @extern_func(i32, i32)

define i32 @func(i32 %0, i32 %1) {
  %call_value = call i32 @extern_func(i32 %0, i32 %1)
  %div = udiv i32 %0, %1
  %sub = sub i32 %div, %call_value
  ret i32 %sub
}
```
Running this through `llc` we get:
```
> llc test.ll -o test.o --filetype=obj -O1 && wasm-objdump -d test.o

test.o: file format wasm 0x1

Code Disassembly:

000055 func[1] <func>:
 000056: 20 00                      | local.get 0
 000058: 20 01 | local.get 1
 00005a: 6e                         | i32.div_u
 00005b: 20 00                      | local.get 0
 00005d: 20 01 | local.get 1
 00005f: 10 80 80 80 80 00          | call 0 <env.extern_func>
 000065: 6b                         | i32.sub
 000066: 0b                         | end
```
This `udiv` and the call get swapped. This does not look correct, since we now have _introduced UB_ (a trap) under the following conditions:
1) The divisor (`%1`) is zero.
2) `extern_func` throws (either a WASM exception or a JS exception).
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJycVk2P4ywS_jXkUnKEcewkhxzSX9K70mql6RnNsYWhEjONwQvY6eyvXxVOOj2t3h3pjWKD7eepKuoLZIzm6BB3rL5j9cNCjqnzYfds3NHiXqmAyXi3aL0-776h1MYdIXUIMUn1ag5GSfoOymtk4h7-AiV7BKmCjxFSZyIYB6zhP7Hdx4h9a8_f8Pg8s89LNQzAxBOJS0bB5I2Gf48YzqzhrNozvqfJ_Od7Jp4I_L3DiGBcTGFUpD5CJyeETsYfrvcaLepno_HxcECVIhMbJrYQMI3BZfvDiDdpLSo5RqRVnSEFOYB34CcMB-tPIJ0G4yZpjYboZ5CSjol1ghZBhtakIIOx55vE3k-oyRudP-GEgVyQfTagIpeBkhHBHyDg0cSE4erNs3FH4pkEJkKUhw9mJp_lkqD-3eYvzZQB4YfTeDAONdxhJyfjw_KTL392RnUwBN8PCTX0SBpSZ9wryNaPaQ5evuGb7AeLn-Jh7dQzvk8yHDGBlklaeSYiqx6ACYFFz6o9FgOr9pXIt2IoKaobuopB3OamWbFq36wKl5HNqnguxaZwhlX7ki6CCs6EuGlMwQwWr9pOMvaVKEb36vzJFScZzYxmfK9RWXKKqQSwFce3hMG9HEanmNiYSmSX07C94sl1V_gNB0zU_AKmeUlpxdZ3jO-BnpW09mWSdpytosf_qfMrWVc52kxZwEiTj9iMu4Di2GYQjReMNtMFdbMkwwOmKyaOLS1y_fApHb6Nbq6NOerBj8cOcpQVazicEI6YvqjI6hGsVZAwpqW1UPh56qEoDsZiOg_Iqgff_oLiXyUw0TDRAAWr8O0vPfYDFPpCmZ1_mVd7ID4cfOhlygzgb-WMufca4cFEeekoF7v4nnPO6xqym-u7ktUPwKr7_Fg9zijImIYUCA6cw5c_tr4H65W0S0o1_s7bXHnlJ0j5DpEEafBruRfRphJLbaaX8Z3V_k2D9J8NOhCk5LD58P-ohng5Vzk5C920_Jit1eNVUFPnlbV_XNmcYzMnO5r_fw46_SmtvlMWsoZTBVD6UXujDprNpNXFkxwG1EvISO0xgvMJrPevoHwIqBKVQjROISWv86d5j3gxLgWvR4Uafty9ABMbmbs-1fLoNIas6OCt9ScqCOWdNnmTmfMnF_33DkGbyUQfSAIZTaVJw5Za938weGq4IneI5rfyb3iur1MkJprUYQAJP_fP_wR8Uzjk_dTTu388394wsV0u9K7S22orF7gr16ua85Wo-KLbVZxvdKNXa64kim3FRbPeNBXWWrUbXa4XZie4qPmq3JRbUdV8uZLrpmx4vaq27aaua2pRvTR2SV196cNxYWIccVdWTVVXCytbtDGfEYRweIL8lRps_bAIOyIV7XiMbMWtiSnexCSTbD5cfDgAUFn-5S5h-nyS8AfAvG8fRvvbHr8Yg911KQ05EHlTPJrUje1S-Z6Jp7wfzUMxBP8rp8BTNjQy8XRZybQT_w0AAP__v5SiRQ">