2019-02-26 11:29:59 +08:00
|
|
|
; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -disable-block-placement -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 -exception-model=wasm -mattr=+exception-handling | FileCheck %s
|
2019-03-27 01:15:55 +08:00
|
|
|
; RUN: llc < %s -O0 -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -verify-machineinstrs -exception-model=wasm -mattr=+exception-handling | FileCheck %s --check-prefix=NOOPT
|
2018-08-08 04:19:23 +08:00
|
|
|
|
|
|
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
|
|
|
target triple = "wasm32-unknown-unknown"
|
|
|
|
|
|
|
|
@_ZTIi = external constant i8*
|
|
|
|
@_ZTId = external constant i8*
|
|
|
|
|
|
|
|
; Simple test case with two catch clauses
|
2019-02-26 11:29:59 +08:00
|
|
|
;
|
|
|
|
; void foo();
|
[WebAssembly] Exception handling: Switch to the new proposal
Summary:
This switches the EH implementation to the new proposal:
https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md
(The previous proposal was
https://github.com/WebAssembly/exception-handling/blob/master/proposals/old/Exceptions.md)
- Instruction changes
- Now we have one single `catch` instruction that returns a except_ref
value
- `throw` now can take variable number of operations
- `rethrow` does not have 'depth' argument anymore
- `br_on_exn` queries an except_ref to see if it matches the tag and
branches to the given label if true.
- `extract_exception` is a pseudo instruction that simulates popping
values from wasm stack. This is to make `br_on_exn`, a very special
instruction, work: `br_on_exn` puts values onto the stack only if it
is taken, and the # of values can vay depending on the tag.
- Now there's only one `catch` per `try`, this patch removes all special
handling for terminate pad with a call to `__clang_call_terminate`.
Before it was the only case there are two catch clauses (a normal
`catch` and `catch_all` per `try`).
- Make `rethrow` act as a terminator like `throw`. This splits BB after
`rethrow` in WasmEHPrepare, and deletes an unnecessary `unreachable`
after `rethrow` in LateEHPrepare.
- Now we stop at all catchpads (because we add wasm `catch` instruction
that catches all exceptions), this creates new
`findWasmUnwindDestinations` function in SelectionDAGBuilder.
- Now we use `br_on_exn` instrution to figure out if an except_ref
matches the current tag or not, LateEHPrepare generates this sequence
for catch pads:
```
catch
block i32
br_on_exn $__cpp_exception
end_block
extract_exception
```
- Branch analysis for `br_on_exn` in WebAssemblyInstrInfo
- Other various misc. changes to switch to the new proposal.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D57134
llvm-svn: 352598
2019-01-30 11:21:57 +08:00
|
|
|
; void test0() {
|
|
|
|
; try {
|
|
|
|
; foo();
|
2019-02-26 11:29:59 +08:00
|
|
|
; } catch (int) {
|
|
|
|
; } catch (double) {
|
[WebAssembly] Exception handling: Switch to the new proposal
Summary:
This switches the EH implementation to the new proposal:
https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md
(The previous proposal was
https://github.com/WebAssembly/exception-handling/blob/master/proposals/old/Exceptions.md)
- Instruction changes
- Now we have one single `catch` instruction that returns a except_ref
value
- `throw` now can take variable number of operations
- `rethrow` does not have 'depth' argument anymore
- `br_on_exn` queries an except_ref to see if it matches the tag and
branches to the given label if true.
- `extract_exception` is a pseudo instruction that simulates popping
values from wasm stack. This is to make `br_on_exn`, a very special
instruction, work: `br_on_exn` puts values onto the stack only if it
is taken, and the # of values can vay depending on the tag.
- Now there's only one `catch` per `try`, this patch removes all special
handling for terminate pad with a call to `__clang_call_terminate`.
Before it was the only case there are two catch clauses (a normal
`catch` and `catch_all` per `try`).
- Make `rethrow` act as a terminator like `throw`. This splits BB after
`rethrow` in WasmEHPrepare, and deletes an unnecessary `unreachable`
after `rethrow` in LateEHPrepare.
- Now we stop at all catchpads (because we add wasm `catch` instruction
that catches all exceptions), this creates new
`findWasmUnwindDestinations` function in SelectionDAGBuilder.
- Now we use `br_on_exn` instrution to figure out if an except_ref
matches the current tag or not, LateEHPrepare generates this sequence
for catch pads:
```
catch
block i32
br_on_exn $__cpp_exception
end_block
extract_exception
```
- Branch analysis for `br_on_exn` in WebAssemblyInstrInfo
- Other various misc. changes to switch to the new proposal.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D57134
llvm-svn: 352598
2019-01-30 11:21:57 +08:00
|
|
|
; }
|
|
|
|
; }
|
2018-08-08 04:19:23 +08:00
|
|
|
|
|
|
|
; CHECK-LABEL: test0
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: try
|
|
|
|
; CHECK: call foo
|
|
|
|
; CHECK: catch
|
|
|
|
; CHECK: block
|
|
|
|
; CHECK: br_if 0, {{.*}} # 0: down to label2
|
|
|
|
; CHECK: i32.call $drop=, __cxa_begin_catch
|
|
|
|
; CHECK: call __cxa_end_catch
|
|
|
|
; CHECK: br 1 # 1: down to label0
|
|
|
|
; CHECK: end_block # label2:
|
|
|
|
; CHECK: block
|
|
|
|
; CHECK: br_if 0, {{.*}} # 0: down to label3
|
|
|
|
; CHECK: i32.call $drop=, __cxa_begin_catch
|
|
|
|
; CHECK: call __cxa_end_catch
|
|
|
|
; CHECK: br 1 # 1: down to label0
|
|
|
|
; CHECK: end_block # label3:
|
[WebAssembly] Make rethrow take an except_ref type argument
Summary:
In the new wasm EH proposal, `rethrow` takes an `except_ref` argument.
This change was missing in r352598.
This patch adds `llvm.wasm.rethrow.in.catch` intrinsic. This is an
intrinsic that's gonna eventually be lowered to wasm `rethrow`
instruction, but this intrinsic can appear only within a catchpad or a
cleanuppad scope. Also this intrinsic needs to be invokable - otherwise
EH pad successor for it will not be correctly generated in clang.
This also adds lowering logic for this intrinsic in
`SelectionDAGBuilder::visitInvoke`. This routine is basically a
specialized and simplified version of
`SelectionDAGBuilder::visitTargetIntrinsic`, but we can't use it
because if is only for `CallInst`s.
This deletes the previous `llvm.wasm.rethrow` intrinsic and related
tests, which was meant to be used within a `__cxa_rethrow` library
function. Turned out this needs some more logic, so the intrinsic for
this purpose will be added later.
LateEHPrepare takes a result value of `catch` and inserts it into
matching `rethrow` as an argument.
`RETHROW_IN_CATCH` is a pseudo instruction that serves as a link between
`llvm.wasm.rethrow.in.catch` and the real wasm `rethrow` instruction. To
generate a `rethrow` instruction, we need an `except_ref` argument,
which is generated from `catch` instruction. But `catch` instrutions are
added in LateEHPrepare pass, so we use `RETHROW_IN_CATCH`, which takes
no argument, until we are able to correctly lower it to `rethrow` in
LateEHPrepare.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59352
llvm-svn: 356316
2019-03-16 13:38:57 +08:00
|
|
|
; CHECK: rethrow {{.*}} # to caller
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: end_try # label0:
|
2018-08-08 04:19:23 +08:00
|
|
|
define void @test0() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
|
|
|
|
entry:
|
|
|
|
invoke void @foo()
|
|
|
|
to label %try.cont unwind label %catch.dispatch
|
|
|
|
|
|
|
|
catch.dispatch: ; preds = %entry
|
|
|
|
%0 = catchswitch within none [label %catch.start] unwind to caller
|
|
|
|
|
|
|
|
catch.start: ; preds = %catch.dispatch
|
|
|
|
%1 = catchpad within %0 [i8* bitcast (i8** @_ZTIi to i8*), i8* bitcast (i8** @_ZTId to i8*)]
|
|
|
|
%2 = call i8* @llvm.wasm.get.exception(token %1)
|
|
|
|
%3 = call i32 @llvm.wasm.get.ehselector(token %1)
|
|
|
|
%4 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
|
|
|
|
%matches = icmp eq i32 %3, %4
|
|
|
|
br i1 %matches, label %catch2, label %catch.fallthrough
|
|
|
|
|
|
|
|
catch2: ; preds = %catch.start
|
|
|
|
%5 = call i8* @__cxa_begin_catch(i8* %2) [ "funclet"(token %1) ]
|
|
|
|
call void @__cxa_end_catch() [ "funclet"(token %1) ]
|
|
|
|
catchret from %1 to label %try.cont
|
|
|
|
|
|
|
|
catch.fallthrough: ; preds = %catch.start
|
2019-02-26 11:29:59 +08:00
|
|
|
%6 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTId to i8*))
|
|
|
|
%matches1 = icmp eq i32 %3, %6
|
2018-08-08 04:19:23 +08:00
|
|
|
br i1 %matches1, label %catch, label %rethrow
|
|
|
|
|
|
|
|
catch: ; preds = %catch.fallthrough
|
2019-02-26 11:29:59 +08:00
|
|
|
%7 = call i8* @__cxa_begin_catch(i8* %2) [ "funclet"(token %1) ]
|
2018-08-08 04:19:23 +08:00
|
|
|
call void @__cxa_end_catch() [ "funclet"(token %1) ]
|
|
|
|
catchret from %1 to label %try.cont
|
|
|
|
|
|
|
|
rethrow: ; preds = %catch.fallthrough
|
[WebAssembly] Make rethrow take an except_ref type argument
Summary:
In the new wasm EH proposal, `rethrow` takes an `except_ref` argument.
This change was missing in r352598.
This patch adds `llvm.wasm.rethrow.in.catch` intrinsic. This is an
intrinsic that's gonna eventually be lowered to wasm `rethrow`
instruction, but this intrinsic can appear only within a catchpad or a
cleanuppad scope. Also this intrinsic needs to be invokable - otherwise
EH pad successor for it will not be correctly generated in clang.
This also adds lowering logic for this intrinsic in
`SelectionDAGBuilder::visitInvoke`. This routine is basically a
specialized and simplified version of
`SelectionDAGBuilder::visitTargetIntrinsic`, but we can't use it
because if is only for `CallInst`s.
This deletes the previous `llvm.wasm.rethrow` intrinsic and related
tests, which was meant to be used within a `__cxa_rethrow` library
function. Turned out this needs some more logic, so the intrinsic for
this purpose will be added later.
LateEHPrepare takes a result value of `catch` and inserts it into
matching `rethrow` as an argument.
`RETHROW_IN_CATCH` is a pseudo instruction that serves as a link between
`llvm.wasm.rethrow.in.catch` and the real wasm `rethrow` instruction. To
generate a `rethrow` instruction, we need an `except_ref` argument,
which is generated from `catch` instruction. But `catch` instrutions are
added in LateEHPrepare pass, so we use `RETHROW_IN_CATCH`, which takes
no argument, until we are able to correctly lower it to `rethrow` in
LateEHPrepare.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59352
llvm-svn: 356316
2019-03-16 13:38:57 +08:00
|
|
|
call void @llvm.wasm.rethrow.in.catch() [ "funclet"(token %1) ]
|
2018-08-08 04:19:23 +08:00
|
|
|
unreachable
|
|
|
|
|
2019-03-27 01:15:55 +08:00
|
|
|
try.cont: ; preds = %catch, %catch2, %entry
|
2018-08-08 04:19:23 +08:00
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
; Nested try-catches within a catch
|
[WebAssembly] Exception handling: Switch to the new proposal
Summary:
This switches the EH implementation to the new proposal:
https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md
(The previous proposal was
https://github.com/WebAssembly/exception-handling/blob/master/proposals/old/Exceptions.md)
- Instruction changes
- Now we have one single `catch` instruction that returns a except_ref
value
- `throw` now can take variable number of operations
- `rethrow` does not have 'depth' argument anymore
- `br_on_exn` queries an except_ref to see if it matches the tag and
branches to the given label if true.
- `extract_exception` is a pseudo instruction that simulates popping
values from wasm stack. This is to make `br_on_exn`, a very special
instruction, work: `br_on_exn` puts values onto the stack only if it
is taken, and the # of values can vay depending on the tag.
- Now there's only one `catch` per `try`, this patch removes all special
handling for terminate pad with a call to `__clang_call_terminate`.
Before it was the only case there are two catch clauses (a normal
`catch` and `catch_all` per `try`).
- Make `rethrow` act as a terminator like `throw`. This splits BB after
`rethrow` in WasmEHPrepare, and deletes an unnecessary `unreachable`
after `rethrow` in LateEHPrepare.
- Now we stop at all catchpads (because we add wasm `catch` instruction
that catches all exceptions), this creates new
`findWasmUnwindDestinations` function in SelectionDAGBuilder.
- Now we use `br_on_exn` instrution to figure out if an except_ref
matches the current tag or not, LateEHPrepare generates this sequence
for catch pads:
```
catch
block i32
br_on_exn $__cpp_exception
end_block
extract_exception
```
- Branch analysis for `br_on_exn` in WebAssemblyInstrInfo
- Other various misc. changes to switch to the new proposal.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D57134
llvm-svn: 352598
2019-01-30 11:21:57 +08:00
|
|
|
; void test1() {
|
|
|
|
; try {
|
|
|
|
; foo();
|
2019-02-26 11:29:59 +08:00
|
|
|
; } catch (int) {
|
[WebAssembly] Exception handling: Switch to the new proposal
Summary:
This switches the EH implementation to the new proposal:
https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md
(The previous proposal was
https://github.com/WebAssembly/exception-handling/blob/master/proposals/old/Exceptions.md)
- Instruction changes
- Now we have one single `catch` instruction that returns a except_ref
value
- `throw` now can take variable number of operations
- `rethrow` does not have 'depth' argument anymore
- `br_on_exn` queries an except_ref to see if it matches the tag and
branches to the given label if true.
- `extract_exception` is a pseudo instruction that simulates popping
values from wasm stack. This is to make `br_on_exn`, a very special
instruction, work: `br_on_exn` puts values onto the stack only if it
is taken, and the # of values can vay depending on the tag.
- Now there's only one `catch` per `try`, this patch removes all special
handling for terminate pad with a call to `__clang_call_terminate`.
Before it was the only case there are two catch clauses (a normal
`catch` and `catch_all` per `try`).
- Make `rethrow` act as a terminator like `throw`. This splits BB after
`rethrow` in WasmEHPrepare, and deletes an unnecessary `unreachable`
after `rethrow` in LateEHPrepare.
- Now we stop at all catchpads (because we add wasm `catch` instruction
that catches all exceptions), this creates new
`findWasmUnwindDestinations` function in SelectionDAGBuilder.
- Now we use `br_on_exn` instrution to figure out if an except_ref
matches the current tag or not, LateEHPrepare generates this sequence
for catch pads:
```
catch
block i32
br_on_exn $__cpp_exception
end_block
extract_exception
```
- Branch analysis for `br_on_exn` in WebAssemblyInstrInfo
- Other various misc. changes to switch to the new proposal.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D57134
llvm-svn: 352598
2019-01-30 11:21:57 +08:00
|
|
|
; try {
|
|
|
|
; foo();
|
2019-02-26 11:29:59 +08:00
|
|
|
; } catch (int) {
|
[WebAssembly] Exception handling: Switch to the new proposal
Summary:
This switches the EH implementation to the new proposal:
https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md
(The previous proposal was
https://github.com/WebAssembly/exception-handling/blob/master/proposals/old/Exceptions.md)
- Instruction changes
- Now we have one single `catch` instruction that returns a except_ref
value
- `throw` now can take variable number of operations
- `rethrow` does not have 'depth' argument anymore
- `br_on_exn` queries an except_ref to see if it matches the tag and
branches to the given label if true.
- `extract_exception` is a pseudo instruction that simulates popping
values from wasm stack. This is to make `br_on_exn`, a very special
instruction, work: `br_on_exn` puts values onto the stack only if it
is taken, and the # of values can vay depending on the tag.
- Now there's only one `catch` per `try`, this patch removes all special
handling for terminate pad with a call to `__clang_call_terminate`.
Before it was the only case there are two catch clauses (a normal
`catch` and `catch_all` per `try`).
- Make `rethrow` act as a terminator like `throw`. This splits BB after
`rethrow` in WasmEHPrepare, and deletes an unnecessary `unreachable`
after `rethrow` in LateEHPrepare.
- Now we stop at all catchpads (because we add wasm `catch` instruction
that catches all exceptions), this creates new
`findWasmUnwindDestinations` function in SelectionDAGBuilder.
- Now we use `br_on_exn` instrution to figure out if an except_ref
matches the current tag or not, LateEHPrepare generates this sequence
for catch pads:
```
catch
block i32
br_on_exn $__cpp_exception
end_block
extract_exception
```
- Branch analysis for `br_on_exn` in WebAssemblyInstrInfo
- Other various misc. changes to switch to the new proposal.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D57134
llvm-svn: 352598
2019-01-30 11:21:57 +08:00
|
|
|
; foo();
|
|
|
|
; }
|
|
|
|
; }
|
|
|
|
; }
|
2018-08-08 04:19:23 +08:00
|
|
|
|
|
|
|
; CHECK-LABEL: test1
|
2019-02-27 09:35:14 +08:00
|
|
|
; CHECK: try
|
|
|
|
; CHECK: call foo
|
|
|
|
; CHECK: catch
|
|
|
|
; CHECK: block
|
|
|
|
; CHECK: block
|
|
|
|
; CHECK: br_if 0, {{.*}} # 0: down to label7
|
|
|
|
; CHECK: i32.call $drop=, __cxa_begin_catch
|
|
|
|
; CHECK: try
|
|
|
|
; CHECK: call foo
|
|
|
|
; CHECK: br 2 # 2: down to label6
|
|
|
|
; CHECK: catch
|
|
|
|
; CHECK: try
|
|
|
|
; CHECK: block
|
|
|
|
; CHECK: br_if 0, {{.*}} # 0: down to label11
|
|
|
|
; CHECK: i32.call $drop=, __cxa_begin_catch
|
|
|
|
; CHECK: try
|
|
|
|
; CHECK: call foo
|
[WebAssembly] Delete ThrowUnwindDest map from WasmEHFuncInfo
Summary:
Before when we implemented the first EH proposal, 'catch <tag>'
instruction may not catch an exception so there were multiple EH pads an
exception can unwind to. That means a BB could have multiple EH pad
successors.
Now after we switched to the new proposal, every 'catch' instruction
catches an exception, and there is only one catchpad per catchswitch, so
we at most have one EH pad successor, making `ThrowUnwindDest` map in
`WasmEHInfo` unnecessary.
Keeping `ThrowUnwindDest` map in `WasmEHInfo` has its own problems,
because other optimization passes can split a BB that contains possibly
throwing calls (previously invokes), and we have to update the map every
time that happens, which is not easy for common CodeGen passes.
This also correctly updates successor info in LateEHPrepare when we add
a rethrow instruction.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D58486
llvm-svn: 355296
2019-03-04 06:35:56 +08:00
|
|
|
; CHECK: br 2 # 2: down to label9
|
2019-02-27 09:35:14 +08:00
|
|
|
; CHECK: catch
|
|
|
|
; CHECK: call __cxa_end_catch
|
[WebAssembly] Make rethrow take an except_ref type argument
Summary:
In the new wasm EH proposal, `rethrow` takes an `except_ref` argument.
This change was missing in r352598.
This patch adds `llvm.wasm.rethrow.in.catch` intrinsic. This is an
intrinsic that's gonna eventually be lowered to wasm `rethrow`
instruction, but this intrinsic can appear only within a catchpad or a
cleanuppad scope. Also this intrinsic needs to be invokable - otherwise
EH pad successor for it will not be correctly generated in clang.
This also adds lowering logic for this intrinsic in
`SelectionDAGBuilder::visitInvoke`. This routine is basically a
specialized and simplified version of
`SelectionDAGBuilder::visitTargetIntrinsic`, but we can't use it
because if is only for `CallInst`s.
This deletes the previous `llvm.wasm.rethrow` intrinsic and related
tests, which was meant to be used within a `__cxa_rethrow` library
function. Turned out this needs some more logic, so the intrinsic for
this purpose will be added later.
LateEHPrepare takes a result value of `catch` and inserts it into
matching `rethrow` as an argument.
`RETHROW_IN_CATCH` is a pseudo instruction that serves as a link between
`llvm.wasm.rethrow.in.catch` and the real wasm `rethrow` instruction. To
generate a `rethrow` instruction, we need an `except_ref` argument,
which is generated from `catch` instruction. But `catch` instrutions are
added in LateEHPrepare pass, so we use `RETHROW_IN_CATCH`, which takes
no argument, until we are able to correctly lower it to `rethrow` in
LateEHPrepare.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59352
llvm-svn: 356316
2019-03-16 13:38:57 +08:00
|
|
|
; CHECK: rethrow {{.*}} # down to catch3
|
2019-02-27 09:35:14 +08:00
|
|
|
; CHECK: end_try
|
|
|
|
; CHECK: end_block # label11:
|
[WebAssembly] Make rethrow take an except_ref type argument
Summary:
In the new wasm EH proposal, `rethrow` takes an `except_ref` argument.
This change was missing in r352598.
This patch adds `llvm.wasm.rethrow.in.catch` intrinsic. This is an
intrinsic that's gonna eventually be lowered to wasm `rethrow`
instruction, but this intrinsic can appear only within a catchpad or a
cleanuppad scope. Also this intrinsic needs to be invokable - otherwise
EH pad successor for it will not be correctly generated in clang.
This also adds lowering logic for this intrinsic in
`SelectionDAGBuilder::visitInvoke`. This routine is basically a
specialized and simplified version of
`SelectionDAGBuilder::visitTargetIntrinsic`, but we can't use it
because if is only for `CallInst`s.
This deletes the previous `llvm.wasm.rethrow` intrinsic and related
tests, which was meant to be used within a `__cxa_rethrow` library
function. Turned out this needs some more logic, so the intrinsic for
this purpose will be added later.
LateEHPrepare takes a result value of `catch` and inserts it into
matching `rethrow` as an argument.
`RETHROW_IN_CATCH` is a pseudo instruction that serves as a link between
`llvm.wasm.rethrow.in.catch` and the real wasm `rethrow` instruction. To
generate a `rethrow` instruction, we need an `except_ref` argument,
which is generated from `catch` instruction. But `catch` instrutions are
added in LateEHPrepare pass, so we use `RETHROW_IN_CATCH`, which takes
no argument, until we are able to correctly lower it to `rethrow` in
LateEHPrepare.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59352
llvm-svn: 356316
2019-03-16 13:38:57 +08:00
|
|
|
; CHECK: rethrow {{.*}} # down to catch3
|
2019-02-27 09:35:14 +08:00
|
|
|
; CHECK: catch {{.*}} # catch3:
|
|
|
|
; CHECK: call __cxa_end_catch
|
[WebAssembly] Make rethrow take an except_ref type argument
Summary:
In the new wasm EH proposal, `rethrow` takes an `except_ref` argument.
This change was missing in r352598.
This patch adds `llvm.wasm.rethrow.in.catch` intrinsic. This is an
intrinsic that's gonna eventually be lowered to wasm `rethrow`
instruction, but this intrinsic can appear only within a catchpad or a
cleanuppad scope. Also this intrinsic needs to be invokable - otherwise
EH pad successor for it will not be correctly generated in clang.
This also adds lowering logic for this intrinsic in
`SelectionDAGBuilder::visitInvoke`. This routine is basically a
specialized and simplified version of
`SelectionDAGBuilder::visitTargetIntrinsic`, but we can't use it
because if is only for `CallInst`s.
This deletes the previous `llvm.wasm.rethrow` intrinsic and related
tests, which was meant to be used within a `__cxa_rethrow` library
function. Turned out this needs some more logic, so the intrinsic for
this purpose will be added later.
LateEHPrepare takes a result value of `catch` and inserts it into
matching `rethrow` as an argument.
`RETHROW_IN_CATCH` is a pseudo instruction that serves as a link between
`llvm.wasm.rethrow.in.catch` and the real wasm `rethrow` instruction. To
generate a `rethrow` instruction, we need an `except_ref` argument,
which is generated from `catch` instruction. But `catch` instrutions are
added in LateEHPrepare pass, so we use `RETHROW_IN_CATCH`, which takes
no argument, until we are able to correctly lower it to `rethrow` in
LateEHPrepare.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59352
llvm-svn: 356316
2019-03-16 13:38:57 +08:00
|
|
|
; CHECK: rethrow {{.*}} # to caller
|
[WebAssembly] Delete ThrowUnwindDest map from WasmEHFuncInfo
Summary:
Before when we implemented the first EH proposal, 'catch <tag>'
instruction may not catch an exception so there were multiple EH pads an
exception can unwind to. That means a BB could have multiple EH pad
successors.
Now after we switched to the new proposal, every 'catch' instruction
catches an exception, and there is only one catchpad per catchswitch, so
we at most have one EH pad successor, making `ThrowUnwindDest` map in
`WasmEHInfo` unnecessary.
Keeping `ThrowUnwindDest` map in `WasmEHInfo` has its own problems,
because other optimization passes can split a BB that contains possibly
throwing calls (previously invokes), and we have to update the map every
time that happens, which is not easy for common CodeGen passes.
This also correctly updates successor info in LateEHPrepare when we add
a rethrow instruction.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D58486
llvm-svn: 355296
2019-03-04 06:35:56 +08:00
|
|
|
; CHECK: end_try # label9:
|
2019-02-27 09:35:14 +08:00
|
|
|
; CHECK: call __cxa_end_catch
|
|
|
|
; CHECK: br 2 # 2: down to label6
|
|
|
|
; CHECK: end_try
|
|
|
|
; CHECK: end_block # label7:
|
[WebAssembly] Make rethrow take an except_ref type argument
Summary:
In the new wasm EH proposal, `rethrow` takes an `except_ref` argument.
This change was missing in r352598.
This patch adds `llvm.wasm.rethrow.in.catch` intrinsic. This is an
intrinsic that's gonna eventually be lowered to wasm `rethrow`
instruction, but this intrinsic can appear only within a catchpad or a
cleanuppad scope. Also this intrinsic needs to be invokable - otherwise
EH pad successor for it will not be correctly generated in clang.
This also adds lowering logic for this intrinsic in
`SelectionDAGBuilder::visitInvoke`. This routine is basically a
specialized and simplified version of
`SelectionDAGBuilder::visitTargetIntrinsic`, but we can't use it
because if is only for `CallInst`s.
This deletes the previous `llvm.wasm.rethrow` intrinsic and related
tests, which was meant to be used within a `__cxa_rethrow` library
function. Turned out this needs some more logic, so the intrinsic for
this purpose will be added later.
LateEHPrepare takes a result value of `catch` and inserts it into
matching `rethrow` as an argument.
`RETHROW_IN_CATCH` is a pseudo instruction that serves as a link between
`llvm.wasm.rethrow.in.catch` and the real wasm `rethrow` instruction. To
generate a `rethrow` instruction, we need an `except_ref` argument,
which is generated from `catch` instruction. But `catch` instrutions are
added in LateEHPrepare pass, so we use `RETHROW_IN_CATCH`, which takes
no argument, until we are able to correctly lower it to `rethrow` in
LateEHPrepare.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59352
llvm-svn: 356316
2019-03-16 13:38:57 +08:00
|
|
|
; CHECK: rethrow {{.*}} # to caller
|
2019-02-27 09:35:14 +08:00
|
|
|
; CHECK: end_block # label6:
|
|
|
|
; CHECK: call __cxa_end_catch
|
|
|
|
; CHECK: end_try
|
[WebAssembly] Exception handling: Switch to the new proposal
Summary:
This switches the EH implementation to the new proposal:
https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md
(The previous proposal was
https://github.com/WebAssembly/exception-handling/blob/master/proposals/old/Exceptions.md)
- Instruction changes
- Now we have one single `catch` instruction that returns a except_ref
value
- `throw` now can take variable number of operations
- `rethrow` does not have 'depth' argument anymore
- `br_on_exn` queries an except_ref to see if it matches the tag and
branches to the given label if true.
- `extract_exception` is a pseudo instruction that simulates popping
values from wasm stack. This is to make `br_on_exn`, a very special
instruction, work: `br_on_exn` puts values onto the stack only if it
is taken, and the # of values can vay depending on the tag.
- Now there's only one `catch` per `try`, this patch removes all special
handling for terminate pad with a call to `__clang_call_terminate`.
Before it was the only case there are two catch clauses (a normal
`catch` and `catch_all` per `try`).
- Make `rethrow` act as a terminator like `throw`. This splits BB after
`rethrow` in WasmEHPrepare, and deletes an unnecessary `unreachable`
after `rethrow` in LateEHPrepare.
- Now we stop at all catchpads (because we add wasm `catch` instruction
that catches all exceptions), this creates new
`findWasmUnwindDestinations` function in SelectionDAGBuilder.
- Now we use `br_on_exn` instrution to figure out if an except_ref
matches the current tag or not, LateEHPrepare generates this sequence
for catch pads:
```
catch
block i32
br_on_exn $__cpp_exception
end_block
extract_exception
```
- Branch analysis for `br_on_exn` in WebAssemblyInstrInfo
- Other various misc. changes to switch to the new proposal.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D57134
llvm-svn: 352598
2019-01-30 11:21:57 +08:00
|
|
|
define void @test1() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
|
2018-08-08 04:19:23 +08:00
|
|
|
entry:
|
|
|
|
invoke void @foo()
|
|
|
|
to label %try.cont11 unwind label %catch.dispatch
|
|
|
|
|
|
|
|
catch.dispatch: ; preds = %entry
|
|
|
|
%0 = catchswitch within none [label %catch.start] unwind to caller
|
|
|
|
|
|
|
|
catch.start: ; preds = %catch.dispatch
|
|
|
|
%1 = catchpad within %0 [i8* bitcast (i8** @_ZTIi to i8*)]
|
|
|
|
%2 = call i8* @llvm.wasm.get.exception(token %1)
|
|
|
|
%3 = call i32 @llvm.wasm.get.ehselector(token %1)
|
|
|
|
%4 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
|
|
|
|
%matches = icmp eq i32 %3, %4
|
|
|
|
br i1 %matches, label %catch, label %rethrow
|
|
|
|
|
|
|
|
catch: ; preds = %catch.start
|
|
|
|
%5 = call i8* @__cxa_begin_catch(i8* %2) [ "funclet"(token %1) ]
|
|
|
|
%6 = bitcast i8* %5 to i32*
|
|
|
|
%7 = load i32, i32* %6, align 4
|
|
|
|
invoke void @foo() [ "funclet"(token %1) ]
|
|
|
|
to label %try.cont unwind label %catch.dispatch2
|
|
|
|
|
|
|
|
catch.dispatch2: ; preds = %catch
|
|
|
|
%8 = catchswitch within %1 [label %catch.start3] unwind label %ehcleanup9
|
|
|
|
|
|
|
|
catch.start3: ; preds = %catch.dispatch2
|
|
|
|
%9 = catchpad within %8 [i8* bitcast (i8** @_ZTIi to i8*)]
|
|
|
|
%10 = call i8* @llvm.wasm.get.exception(token %9)
|
|
|
|
%11 = call i32 @llvm.wasm.get.ehselector(token %9)
|
|
|
|
%12 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
|
|
|
|
%matches4 = icmp eq i32 %11, %12
|
|
|
|
br i1 %matches4, label %catch6, label %rethrow5
|
|
|
|
|
|
|
|
catch6: ; preds = %catch.start3
|
|
|
|
%13 = call i8* @__cxa_begin_catch(i8* %10) [ "funclet"(token %9) ]
|
|
|
|
%14 = bitcast i8* %13 to i32*
|
|
|
|
%15 = load i32, i32* %14, align 4
|
|
|
|
invoke void @foo() [ "funclet"(token %9) ]
|
|
|
|
to label %invoke.cont8 unwind label %ehcleanup
|
|
|
|
|
|
|
|
invoke.cont8: ; preds = %catch6
|
|
|
|
call void @__cxa_end_catch() [ "funclet"(token %9) ]
|
|
|
|
catchret from %9 to label %try.cont
|
|
|
|
|
|
|
|
rethrow5: ; preds = %catch.start3
|
[WebAssembly] Make rethrow take an except_ref type argument
Summary:
In the new wasm EH proposal, `rethrow` takes an `except_ref` argument.
This change was missing in r352598.
This patch adds `llvm.wasm.rethrow.in.catch` intrinsic. This is an
intrinsic that's gonna eventually be lowered to wasm `rethrow`
instruction, but this intrinsic can appear only within a catchpad or a
cleanuppad scope. Also this intrinsic needs to be invokable - otherwise
EH pad successor for it will not be correctly generated in clang.
This also adds lowering logic for this intrinsic in
`SelectionDAGBuilder::visitInvoke`. This routine is basically a
specialized and simplified version of
`SelectionDAGBuilder::visitTargetIntrinsic`, but we can't use it
because if is only for `CallInst`s.
This deletes the previous `llvm.wasm.rethrow` intrinsic and related
tests, which was meant to be used within a `__cxa_rethrow` library
function. Turned out this needs some more logic, so the intrinsic for
this purpose will be added later.
LateEHPrepare takes a result value of `catch` and inserts it into
matching `rethrow` as an argument.
`RETHROW_IN_CATCH` is a pseudo instruction that serves as a link between
`llvm.wasm.rethrow.in.catch` and the real wasm `rethrow` instruction. To
generate a `rethrow` instruction, we need an `except_ref` argument,
which is generated from `catch` instruction. But `catch` instrutions are
added in LateEHPrepare pass, so we use `RETHROW_IN_CATCH`, which takes
no argument, until we are able to correctly lower it to `rethrow` in
LateEHPrepare.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59352
llvm-svn: 356316
2019-03-16 13:38:57 +08:00
|
|
|
invoke void @llvm.wasm.rethrow.in.catch() [ "funclet"(token %9) ]
|
2018-08-08 04:19:23 +08:00
|
|
|
to label %unreachable unwind label %ehcleanup9
|
|
|
|
|
2019-03-27 01:15:55 +08:00
|
|
|
try.cont: ; preds = %invoke.cont8, %catch
|
2018-08-08 04:19:23 +08:00
|
|
|
call void @__cxa_end_catch() [ "funclet"(token %1) ]
|
|
|
|
catchret from %1 to label %try.cont11
|
|
|
|
|
|
|
|
rethrow: ; preds = %catch.start
|
[WebAssembly] Make rethrow take an except_ref type argument
Summary:
In the new wasm EH proposal, `rethrow` takes an `except_ref` argument.
This change was missing in r352598.
This patch adds `llvm.wasm.rethrow.in.catch` intrinsic. This is an
intrinsic that's gonna eventually be lowered to wasm `rethrow`
instruction, but this intrinsic can appear only within a catchpad or a
cleanuppad scope. Also this intrinsic needs to be invokable - otherwise
EH pad successor for it will not be correctly generated in clang.
This also adds lowering logic for this intrinsic in
`SelectionDAGBuilder::visitInvoke`. This routine is basically a
specialized and simplified version of
`SelectionDAGBuilder::visitTargetIntrinsic`, but we can't use it
because if is only for `CallInst`s.
This deletes the previous `llvm.wasm.rethrow` intrinsic and related
tests, which was meant to be used within a `__cxa_rethrow` library
function. Turned out this needs some more logic, so the intrinsic for
this purpose will be added later.
LateEHPrepare takes a result value of `catch` and inserts it into
matching `rethrow` as an argument.
`RETHROW_IN_CATCH` is a pseudo instruction that serves as a link between
`llvm.wasm.rethrow.in.catch` and the real wasm `rethrow` instruction. To
generate a `rethrow` instruction, we need an `except_ref` argument,
which is generated from `catch` instruction. But `catch` instrutions are
added in LateEHPrepare pass, so we use `RETHROW_IN_CATCH`, which takes
no argument, until we are able to correctly lower it to `rethrow` in
LateEHPrepare.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59352
llvm-svn: 356316
2019-03-16 13:38:57 +08:00
|
|
|
call void @llvm.wasm.rethrow.in.catch() [ "funclet"(token %1) ]
|
2018-08-08 04:19:23 +08:00
|
|
|
unreachable
|
|
|
|
|
2019-03-27 01:15:55 +08:00
|
|
|
try.cont11: ; preds = %try.cont, %entry
|
2018-08-08 04:19:23 +08:00
|
|
|
ret void
|
|
|
|
|
|
|
|
ehcleanup: ; preds = %catch6
|
|
|
|
%16 = cleanuppad within %9 []
|
|
|
|
call void @__cxa_end_catch() [ "funclet"(token %16) ]
|
|
|
|
cleanupret from %16 unwind label %ehcleanup9
|
|
|
|
|
|
|
|
ehcleanup9: ; preds = %ehcleanup, %rethrow5, %catch.dispatch2
|
|
|
|
%17 = cleanuppad within %1 []
|
|
|
|
call void @__cxa_end_catch() [ "funclet"(token %17) ]
|
|
|
|
cleanupret from %17 unwind to caller
|
|
|
|
|
|
|
|
unreachable: ; preds = %rethrow5
|
|
|
|
unreachable
|
|
|
|
}
|
|
|
|
|
|
|
|
; Nested loop within a catch clause
|
[WebAssembly] Exception handling: Switch to the new proposal
Summary:
This switches the EH implementation to the new proposal:
https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md
(The previous proposal was
https://github.com/WebAssembly/exception-handling/blob/master/proposals/old/Exceptions.md)
- Instruction changes
- Now we have one single `catch` instruction that returns a except_ref
value
- `throw` now can take variable number of operations
- `rethrow` does not have 'depth' argument anymore
- `br_on_exn` queries an except_ref to see if it matches the tag and
branches to the given label if true.
- `extract_exception` is a pseudo instruction that simulates popping
values from wasm stack. This is to make `br_on_exn`, a very special
instruction, work: `br_on_exn` puts values onto the stack only if it
is taken, and the # of values can vay depending on the tag.
- Now there's only one `catch` per `try`, this patch removes all special
handling for terminate pad with a call to `__clang_call_terminate`.
Before it was the only case there are two catch clauses (a normal
`catch` and `catch_all` per `try`).
- Make `rethrow` act as a terminator like `throw`. This splits BB after
`rethrow` in WasmEHPrepare, and deletes an unnecessary `unreachable`
after `rethrow` in LateEHPrepare.
- Now we stop at all catchpads (because we add wasm `catch` instruction
that catches all exceptions), this creates new
`findWasmUnwindDestinations` function in SelectionDAGBuilder.
- Now we use `br_on_exn` instrution to figure out if an except_ref
matches the current tag or not, LateEHPrepare generates this sequence
for catch pads:
```
catch
block i32
br_on_exn $__cpp_exception
end_block
extract_exception
```
- Branch analysis for `br_on_exn` in WebAssemblyInstrInfo
- Other various misc. changes to switch to the new proposal.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D57134
llvm-svn: 352598
2019-01-30 11:21:57 +08:00
|
|
|
; void test2() {
|
|
|
|
; try {
|
|
|
|
; foo();
|
|
|
|
; } catch (...) {
|
|
|
|
; for (int i = 0; i < 50; i++)
|
|
|
|
; foo();
|
|
|
|
; }
|
|
|
|
; }
|
2018-08-08 04:19:23 +08:00
|
|
|
|
|
|
|
; CHECK-LABEL: test2
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: try
|
|
|
|
; CHECK: call foo
|
|
|
|
; CHECK: catch
|
|
|
|
; CHECK: i32.call $drop=, __cxa_begin_catch
|
|
|
|
; CHECK: loop # label15:
|
|
|
|
; CHECK: block
|
2019-02-26 11:29:59 +08:00
|
|
|
; CHECK: block
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: br_if 0, {{.*}} # 0: down to label17
|
|
|
|
; CHECK: try
|
|
|
|
; CHECK: call foo
|
|
|
|
; CHECK: br 2 # 2: down to label16
|
|
|
|
; CHECK: catch
|
2019-02-26 11:29:59 +08:00
|
|
|
; CHECK: try
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: call __cxa_end_catch
|
2019-02-26 11:29:59 +08:00
|
|
|
; CHECK: catch
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: call __clang_call_terminate
|
|
|
|
; CHECK: unreachable
|
2019-02-26 11:29:59 +08:00
|
|
|
; CHECK: end_try
|
[WebAssembly] Make rethrow take an except_ref type argument
Summary:
In the new wasm EH proposal, `rethrow` takes an `except_ref` argument.
This change was missing in r352598.
This patch adds `llvm.wasm.rethrow.in.catch` intrinsic. This is an
intrinsic that's gonna eventually be lowered to wasm `rethrow`
instruction, but this intrinsic can appear only within a catchpad or a
cleanuppad scope. Also this intrinsic needs to be invokable - otherwise
EH pad successor for it will not be correctly generated in clang.
This also adds lowering logic for this intrinsic in
`SelectionDAGBuilder::visitInvoke`. This routine is basically a
specialized and simplified version of
`SelectionDAGBuilder::visitTargetIntrinsic`, but we can't use it
because if is only for `CallInst`s.
This deletes the previous `llvm.wasm.rethrow` intrinsic and related
tests, which was meant to be used within a `__cxa_rethrow` library
function. Turned out this needs some more logic, so the intrinsic for
this purpose will be added later.
LateEHPrepare takes a result value of `catch` and inserts it into
matching `rethrow` as an argument.
`RETHROW_IN_CATCH` is a pseudo instruction that serves as a link between
`llvm.wasm.rethrow.in.catch` and the real wasm `rethrow` instruction. To
generate a `rethrow` instruction, we need an `except_ref` argument,
which is generated from `catch` instruction. But `catch` instrutions are
added in LateEHPrepare pass, so we use `RETHROW_IN_CATCH`, which takes
no argument, until we are able to correctly lower it to `rethrow` in
LateEHPrepare.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59352
llvm-svn: 356316
2019-03-16 13:38:57 +08:00
|
|
|
; CHECK: rethrow {{.*}} # to caller
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: end_try
|
|
|
|
; CHECK: end_block # label17:
|
|
|
|
; CHECK: call __cxa_end_catch
|
|
|
|
; CHECK: br 2 # 2: down to label13
|
|
|
|
; CHECK: end_block # label16:
|
|
|
|
; CHECK: br 0 # 0: up to label15
|
|
|
|
; CHECK: end_loop
|
|
|
|
; CHECK: end_try # label13:
|
2018-08-08 04:19:23 +08:00
|
|
|
define void @test2() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
|
|
|
|
entry:
|
|
|
|
invoke void @foo()
|
|
|
|
to label %try.cont unwind label %catch.dispatch
|
|
|
|
|
|
|
|
catch.dispatch: ; preds = %entry
|
|
|
|
%0 = catchswitch within none [label %catch.start] unwind to caller
|
|
|
|
|
|
|
|
catch.start: ; preds = %catch.dispatch
|
|
|
|
%1 = catchpad within %0 [i8* null]
|
|
|
|
%2 = call i8* @llvm.wasm.get.exception(token %1)
|
|
|
|
%3 = call i32 @llvm.wasm.get.ehselector(token %1)
|
|
|
|
%4 = call i8* @__cxa_begin_catch(i8* %2) [ "funclet"(token %1) ]
|
|
|
|
br label %for.cond
|
|
|
|
|
|
|
|
for.cond: ; preds = %for.inc, %catch.start
|
|
|
|
%i.0 = phi i32 [ 0, %catch.start ], [ %inc, %for.inc ]
|
|
|
|
%cmp = icmp slt i32 %i.0, 50
|
|
|
|
br i1 %cmp, label %for.body, label %for.end
|
|
|
|
|
|
|
|
for.body: ; preds = %for.cond
|
|
|
|
invoke void @foo() [ "funclet"(token %1) ]
|
|
|
|
to label %for.inc unwind label %ehcleanup
|
|
|
|
|
|
|
|
for.inc: ; preds = %for.body
|
|
|
|
%inc = add nsw i32 %i.0, 1
|
|
|
|
br label %for.cond
|
|
|
|
|
|
|
|
for.end: ; preds = %for.cond
|
|
|
|
call void @__cxa_end_catch() [ "funclet"(token %1) ]
|
|
|
|
catchret from %1 to label %try.cont
|
|
|
|
|
|
|
|
try.cont: ; preds = %for.end, %entry
|
|
|
|
ret void
|
|
|
|
|
|
|
|
ehcleanup: ; preds = %for.body
|
|
|
|
%5 = cleanuppad within %1 []
|
|
|
|
invoke void @__cxa_end_catch() [ "funclet"(token %5) ]
|
|
|
|
to label %invoke.cont2 unwind label %terminate
|
|
|
|
|
|
|
|
invoke.cont2: ; preds = %ehcleanup
|
|
|
|
cleanupret from %5 unwind to caller
|
|
|
|
|
|
|
|
terminate: ; preds = %ehcleanup
|
|
|
|
%6 = cleanuppad within %5 []
|
|
|
|
%7 = call i8* @llvm.wasm.get.exception(token %6)
|
|
|
|
call void @__clang_call_terminate(i8* %7) [ "funclet"(token %6) ]
|
|
|
|
unreachable
|
|
|
|
}
|
|
|
|
|
2019-03-27 01:15:55 +08:00
|
|
|
; Tests if block and try markers are correctly placed. Even if two predecessors
|
|
|
|
; of the EH pad are bb2 and bb3 and their nearest common dominator is bb1, the
|
|
|
|
; TRY marker should be placed at bb0 because there's a branch from bb0 to bb2,
|
|
|
|
; and scopes cannot be interleaved.
|
|
|
|
|
|
|
|
; NOOPT-LABEL: test3
|
|
|
|
; NOOPT: try
|
|
|
|
; NOOPT: block
|
|
|
|
; NOOPT: block
|
|
|
|
; NOOPT: block
|
|
|
|
; NOOPT: end_block
|
|
|
|
; NOOPT: end_block
|
|
|
|
; NOOPT: call foo
|
|
|
|
; NOOPT: end_block
|
|
|
|
; NOOPT: call bar
|
|
|
|
; NOOPT: catch {{.*}}
|
|
|
|
; NOOPT: end_try
|
|
|
|
define void @test3() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
|
|
|
|
bb0:
|
|
|
|
br i1 undef, label %bb1, label %bb2
|
|
|
|
|
|
|
|
bb1: ; preds = %bb0
|
|
|
|
br i1 undef, label %bb3, label %bb4
|
|
|
|
|
|
|
|
bb2: ; preds = %bb0
|
|
|
|
br label %try.cont
|
|
|
|
|
|
|
|
bb3: ; preds = %bb1
|
|
|
|
invoke void @foo()
|
|
|
|
to label %try.cont unwind label %catch.dispatch
|
|
|
|
|
|
|
|
bb4: ; preds = %bb1
|
|
|
|
invoke void @bar()
|
|
|
|
to label %try.cont unwind label %catch.dispatch
|
|
|
|
|
|
|
|
catch.dispatch: ; preds = %bb4, %bb3
|
|
|
|
%0 = catchswitch within none [label %catch.start] unwind to caller
|
|
|
|
|
|
|
|
catch.start: ; preds = %catch.dispatch
|
|
|
|
%1 = catchpad within %0 [i8* null]
|
|
|
|
%2 = call i8* @llvm.wasm.get.exception(token %1)
|
|
|
|
%3 = call i32 @llvm.wasm.get.ehselector(token %1)
|
|
|
|
catchret from %1 to label %try.cont
|
|
|
|
|
|
|
|
try.cont: ; preds = %catch.start, %bb4, %bb3, %bb2
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
2018-08-08 04:19:23 +08:00
|
|
|
declare void @foo()
|
|
|
|
declare void @bar()
|
|
|
|
declare i32 @__gxx_wasm_personality_v0(...)
|
|
|
|
declare i8* @llvm.wasm.get.exception(token)
|
|
|
|
declare i32 @llvm.wasm.get.ehselector(token)
|
[WebAssembly] Make rethrow take an except_ref type argument
Summary:
In the new wasm EH proposal, `rethrow` takes an `except_ref` argument.
This change was missing in r352598.
This patch adds `llvm.wasm.rethrow.in.catch` intrinsic. This is an
intrinsic that's gonna eventually be lowered to wasm `rethrow`
instruction, but this intrinsic can appear only within a catchpad or a
cleanuppad scope. Also this intrinsic needs to be invokable - otherwise
EH pad successor for it will not be correctly generated in clang.
This also adds lowering logic for this intrinsic in
`SelectionDAGBuilder::visitInvoke`. This routine is basically a
specialized and simplified version of
`SelectionDAGBuilder::visitTargetIntrinsic`, but we can't use it
because if is only for `CallInst`s.
This deletes the previous `llvm.wasm.rethrow` intrinsic and related
tests, which was meant to be used within a `__cxa_rethrow` library
function. Turned out this needs some more logic, so the intrinsic for
this purpose will be added later.
LateEHPrepare takes a result value of `catch` and inserts it into
matching `rethrow` as an argument.
`RETHROW_IN_CATCH` is a pseudo instruction that serves as a link between
`llvm.wasm.rethrow.in.catch` and the real wasm `rethrow` instruction. To
generate a `rethrow` instruction, we need an `except_ref` argument,
which is generated from `catch` instruction. But `catch` instrutions are
added in LateEHPrepare pass, so we use `RETHROW_IN_CATCH`, which takes
no argument, until we are able to correctly lower it to `rethrow` in
LateEHPrepare.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59352
llvm-svn: 356316
2019-03-16 13:38:57 +08:00
|
|
|
declare void @llvm.wasm.rethrow.in.catch()
|
2018-08-08 04:19:23 +08:00
|
|
|
declare i32 @llvm.eh.typeid.for(i8*)
|
|
|
|
declare i8* @__cxa_begin_catch(i8*)
|
|
|
|
declare void @__cxa_end_catch()
|
|
|
|
declare void @__clang_call_terminate(i8*)
|
|
|
|
declare void @_ZSt9terminatev()
|