[WebAssembly] Remove ExceptionInfo grouping tweaks (NFC) (#191495)

This removes fixes implemented in
https://github.com/llvm/llvm-project/commit/ea8c6375e3330f181105106b3adb84ff9fa76a7c,
https://github.com/llvm/llvm-project/commit/4a58116b7e5e1439c5fefdf59a89fc4f1d42875c,
and
https://github.com/llvm/llvm-project/commit/2b957ed4ff3344d8f761a053566e307277a1cdeb.
We don't need them anymore after #130374.

---

A little (unfortunate) winding history, mostly for my mental bookeeping.
Read the below only if you are curious:

There is a function called `findUnwindDestinations` in
`SelectionDAGBuilder.cpp`.

https://github.com/llvm/llvm-project/blob/c94f79886035a61bb5f3dc992f75fe0c08bdcd4b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp#L2107-L2164

This function adds unwind successors to BBs with `invoke`s. In case of
Itanium EH, you only add one `landingpad` BB. In WinEH, `catchswitch`
may not catch an exception, so you add all possible unwind
destionations. For example,
```ll
entry:
  invoke void @foo()
          to label %try.cont unwind label %catch.dispatch

catch.dispatch:
  %0 = catchswitch within none [label %catch.start] unwind label %catch.dispatch1

catch.start:
  ...

catch.dispatch1:
  %7 = catchswitch within none [label %catch.start1] unwind to caller

catch.start1:
  ...
```
`catchswitch` BBs are removed in iSel. So in this case, both
`catch.start` and `catch.start1` BBs are added as unwind successors to
`entry`, because an exception may not be caught by `catch.dispatch` and
unwind further to `catch.dispatch1`.

In the beginning of 2019, I added our own `findWasmUnwindDestinations`
in
https://github.com/llvm/llvm-project/commit/d6f487863dc951d467b545b86b9ea62980569b5a.
This was when I was implementing [the V2 (pre-legacy)
proposal,](https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/pre-legacy/Exceptions-v2.md)
which had `exnref` and `try`-`catch_all` (It was named `catch`, but
semantically it was `catch_all`) The rationale was, even though we were
using WinEH, we only had one catchpad and `catch` caught everything. So
I figured adding only the first catchpad successor, `catch.start` in the
example above, would simpify things.

By the end of 2020, we changed the proposal to [the V3 (legacy)
proposal](https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/legacy/Exceptions.md),
which removed `exnref` and introduced separate `catch` and `catch_all`
instructions. The previous invariant "`catch` always catches everything"
didn't hold anymore, but I left `findWasmUnwindDestinations` as was with
some updated comments in
https://github.com/llvm/llvm-project/commit/9e4eadeb135d140b3a9e499354472170017cbe58.
The comments could be summed up as "there will always be an `invoke`
instruction in the first catchpad that unwinds to the next unwind
destination. (which later turned out to be false)

And in 2021, I tweaked the ExceptionInfo algorithm to fix exception
grouping
(https://github.com/llvm/llvm-project/commit/ea8c6375e3330f181105106b3adb84ff9fa76a7c,
https://github.com/llvm/llvm-project/commit/4a58116b7e5e1439c5fefdf59a89fc4f1d42875c,
and
https://github.com/llvm/llvm-project/commit/2b957ed4ff3344d8f761a053566e307277a1cdeb)
The bug was, in tl;dr: "Your next unwind destination can be
(accidentally) dominated by your current catchpad, making your unwind
destination a subexception of the current exception). For example:
```cpp
try {
  try {
    foo();
  } catch (int) { // EH pad
    ...
  }
} catch (...) {   // unwind destination
}
```
Here the outer `catch` is (accidentally) dominated by the inner `catch`,
because we only added the first catchpad (inner `catch`) as an unwind
successor of `foo()` BB, and hoped that some `invoke`s within the inner
`catch` to unwind it to the outer `catch`. But this caused us to
`delegate` to a middle of an inner scope. So I tweaked the algorithm to
take the outer `catch` out to form a separate exception. I didn't
realize `findWasmUnwindDestinations` was actually the source of problem
then.

Fast forward to 2025. The 2020 assumption of "There will always be an
`invoke` instruction in the first catchpad" turned out to be false. So I
just removed `findWasmUnwindDestinations` and switched to use the common
`findUnwindDestinations` in #130374, which recently accidentally
discovered another bug (#187302).

While investigating #187302, I realized we don't need those tweaks in
WebAssemblyExceptionInfo anymore, because `findUnwindDestinations` adds
all unwind destinations as successors. (#187302 is actually not related
to this; it was just a trigger to investigate things) So in case of the
little C++ example above, the outer `catch` BB will also be added as an
unwind successor of the `foo()` BB. I actually think we may not even
need WebAssemblyExceptionInfo analysis at all if we only use [the latest
standard (exnref)
proposal](https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md).
But we still need to keep the legacy support, so we need it for now.
2 files changed
tree: d32c8e2f68b1c9087c694965b661b209f5c129b5
  1. .ci/
  2. .github/
  3. bolt/
  4. clang/
  5. clang-tools-extra/
  6. cmake/
  7. compiler-rt/
  8. cross-project-tests/
  9. flang/
  10. flang-rt/
  11. libc/
  12. libclc/
  13. libcxx/
  14. libcxxabi/
  15. libsycl/
  16. libunwind/
  17. lld/
  18. lldb/
  19. llvm/
  20. llvm-libgcc/
  21. mlir/
  22. offload/
  23. openmp/
  24. orc-rt/
  25. polly/
  26. runtimes/
  27. third-party/
  28. utils/
  29. .clang-format
  30. .clang-format-ignore
  31. .clang-tidy
  32. .git-blame-ignore-revs
  33. .gitattributes
  34. .gitignore
  35. .mailmap
  36. CODE_OF_CONDUCT.md
  37. CONTRIBUTING.md
  38. LICENSE.TXT
  39. pyproject.toml
  40. README.md
  41. SECURITY.md
README.md

The LLVM Compiler Infrastructure

OpenSSF Scorecard OpenSSF Best Practices libc++

Welcome to the LLVM project!

This repository contains the source code for LLVM, a toolkit for the construction of highly optimized compilers, optimizers, and run-time environments.

The LLVM project has multiple components. The core of the project is itself called “LLVM”. This contains all of the tools, libraries, and header files needed to process intermediate representations and convert them into object files. Tools include an assembler, disassembler, bitcode analyzer, and bitcode optimizer.

C-like languages use the Clang frontend. This component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode -- and from there into object files, using LLVM.

Other components include: the libc++ C++ standard library, the LLD linker, and more.

Getting the Source Code and Building LLVM

Consult the Getting Started with LLVM page for information on building and running LLVM.

For information on how to contribute to the LLVM project, please take a look at the Contributing to LLVM guide.

Getting in touch

Join the LLVM Discourse forums, Discord chat, LLVM Office Hours or Regular sync-ups.

The LLVM project has adopted a code of conduct for participants to all modes of communication within the project.