[all-commits] [llvm/llvm-project] c3dfd3: [WebAssembly] Add unreachable before catch destina...

Heejin Ahn via All-commits all-commits at lists.llvm.org
Wed Jan 22 22:40:05 PST 2025


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: c3dfd34e54c1cb9e0e6c7472a6d30d03a63f6f0a
      https://github.com/llvm/llvm-project/commit/c3dfd34e54c1cb9e0e6c7472a6d30d03a63f6f0a
  Author: Heejin Ahn <aheejin at gmail.com>
  Date:   2025-01-22 (Wed, 22 Jan 2025)

  Changed paths:
    M llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
    M llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
    M llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll
    M llvm/test/CodeGen/WebAssembly/exception-legacy.mir
    M llvm/test/CodeGen/WebAssembly/exception.ll

  Log Message:
  -----------
  [WebAssembly] Add unreachable before catch destinations (#123915)

When `try_table`'s catch clause's destination has a return type, as in
the case of catch with a concrete tag, catch_ref, and catch_all_ref. For
example:
```wasm
block exnref
  try_table (catch_all_ref 0)
    ...
  end_try_table
end_block
... use exnref ...
```

This code is not valid because the block's body type is not exnref. So
we add an unreachable after the 'end_try_table' to make the code valid
here:
```wasm
block exnref
  try_table (catch_all_ref 0)
    ...
  end_try_table
  unreachable                    ;; Newly added
end_block
```
Because 'unreachable' is a terminator we also need to split the BB.

---

We need to handle the same thing for unwind mismatch handling. In the
code below, we create a "trampoline BB" that will be the destination for
the nested `try_table`~`end_try_table` added to fix a unwind mismatch:
```wasm
try_table (catch ... )
  block exnref
    ...
    try_table (catch_all_ref N)
      some code
    end_try_table
    ...
  end_block                      ;; Trampoline BB
  throw_ref
end_try_table
```
While the `block` added for the trampoline BB has the return type
`exnref`, its body, which contains the nested `try_table` and other
code, wouldn't have the `exnref` return type. Most times it didn't
become a problem because the block's body ended with something like `br`
or `return`, but that may not always be the case, especially when there
is a loop. So we add an `unreachable` to make the code valid here too:
```wasm
try_table (catch ... )
  block exnref
    ...
    try_table (catch_all_ref N)
      some code
    end_try_table
    ...
    unreachable                  ;; Newly added
  end_block                      ;; Trampoline BB
  throw_ref
end_try_table
```
In this case we just append the `unreachable` at the end of the layout
predecessor BB. (This was tricky to do in the first (non-mismatch) case
because there `end_try_table` and `end_block` were added in the
beginning of an EH pad in `placeTryTableMarker` and moving
`end_try_table` and the new `unreachable` to the previous BB caused
other problems.)

---

This adds many `unreaachable`s to the output, but this adds
`unreachable` to only a few places to see if this is working. The
FileCheck lines in `exception.ll` and `cfg-stackify-eh.ll` are already
heavily redacted to only leave important control-flow instructions, so I
don't think it's worth adding `unreachable`s everywhere.



To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications


More information about the All-commits mailing list