2018-08-27 23:45:51 +08:00
|
|
|
; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -exception-model=wasm
|
[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
|
|
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -exception-model=wasm -mattr=+exception-handling -verify-machineinstrs | FileCheck -allow-deprecated-dag-overlap %s
|
[WebAssembly] Fix bugs in rethrow depth counting and InstPrinter
Summary:
EH stack depth is incremented at `try` and decremented at `catch`. When
there are more than two catch instructions for a try instruction, we
shouldn't count non-first catches when calculating EH stack depths.
This patch fixes two bugs:
- CFGStackify: Exclude `catch_all` in the terminate catch pad when
calculating EH pad stack, because when we have multiple catches for a
try we should count only the first catch instruction when calculating
EH pad stack.
- InstPrinter: The initial intention was also to exclude non-first
catches, but it didn't account nested try-catches, so it failed on
this case:
```
try
try
catch
end
catch <-- (1)
end
```
In the example, when we are at the catch (1), the last seen EH
instruction is not `try` but `end_try`, violating the wrong assumption.
We don't need these after we switch to the second proposal because there
is gonna be only one `catch` instruction. But anyway before then these
bugfixes are necessary for keep trunk in working state.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D53819
llvm-svn: 346029
2018-11-03 02:38:52 +08:00
|
|
|
; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-keep-registers -exception-model=wasm -mattr=+exception-handling
|
2017-06-30 08:43:15 +08:00
|
|
|
|
|
|
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
2018-05-11 01:49:11 +08:00
|
|
|
target triple = "wasm32-unknown-unknown"
|
2017-06-30 08:43:15 +08:00
|
|
|
|
2019-02-26 11:29:59 +08:00
|
|
|
%struct.Temp = type { i8 }
|
[WebAssembly] Support instruction selection for catching exceptions
Summary:
This lowers exception catching-related instructions:
1. Lowers `wasm.catch` intrinsic to `catch` instruction
2. Removes `catchpad` and `cleanuppad` instructions; they are not
necessary after isel phase. (`MachineBasicBlock::isEHFuncletEntry()` or
`MachineBasicBlock::isEHPad()` can be used instead.)
3. Lowers `catchret` and `cleanupret` instructions to pseudo `catchret`
and `cleanupret` instructions in isel, which will be replaced with other
instructions in `WebAssemblyExceptionPrepare` pass.
4. Adds 'WebAssemblyExceptionPrepare` pass, which is for running various
transformation for EH. Currently this pass only replaces `catchret` and
`cleanupret` instructions into appropriate wasm instructions to make
this patch successfully run until the end.
Currently this does not handle lowering of intrinsics related to LSDA
info generation (`wasm.landingpad.index` and `wasm.lsda`), because they
cannot be tested without implementing `EHStreamer`'s wasm-specific
handlers. They are marked as TODO, which is needed to make isel pass.
Also this does not generate `try` and `end_try` markers yet, which will
be handled in later patches.
This patch is based on the first wasm EH proposal.
(https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md)
Reviewers: dschuff, majnemer
Subscribers: jfb, sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D44090
llvm-svn: 333705
2018-06-01 06:25:54 +08:00
|
|
|
|
|
|
|
@_ZTIi = external constant i8*
|
|
|
|
|
|
|
|
; CHECK-LABEL: test_throw:
|
2019-02-26 11:29:59 +08:00
|
|
|
; CHECK: throw __cpp_exception, $0
|
|
|
|
; CHECK-NOT: unreachable
|
2018-11-16 08:47:18 +08:00
|
|
|
define void @test_throw(i8* %p) {
|
|
|
|
call void @llvm.wasm.throw(i32 0, i8* %p)
|
2017-06-30 08:43:15 +08:00
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
2019-02-26 11:29:59 +08:00
|
|
|
; Simple test with a try-catch
|
|
|
|
;
|
|
|
|
; void foo();
|
|
|
|
; void test_catch() {
|
|
|
|
; try {
|
|
|
|
; foo();
|
|
|
|
; } catch (int) {
|
|
|
|
; }
|
|
|
|
; }
|
|
|
|
|
|
|
|
; CHECK-LABEL: test_catch:
|
|
|
|
; CHECK: global.get ${{.+}}=, __stack_pointer
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: try
|
|
|
|
; CHECK: call foo
|
2019-07-16 06:49:25 +08:00
|
|
|
; CHECK: catch $[[EXNREF:[0-9]+]]=
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: global.set __stack_pointer
|
|
|
|
; CHECK: block i32
|
2019-07-16 06:49:25 +08:00
|
|
|
; CHECK: br_on_exn 0, __cpp_exception, $[[EXNREF]]
|
|
|
|
; CHECK: rethrow $[[EXNREF]]
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: end_block
|
|
|
|
; CHECK: extract_exception $[[EXN:[0-9]+]]=
|
|
|
|
; CHECK-DAG: i32.store __wasm_lpad_context
|
|
|
|
; CHECK-DAG: i32.store __wasm_lpad_context+4
|
|
|
|
; CHECK: i32.call $drop=, _Unwind_CallPersonality, $[[EXN]]
|
|
|
|
; CHECK: block
|
|
|
|
; CHECK: br_if 0
|
|
|
|
; CHECK: i32.call $drop=, __cxa_begin_catch
|
|
|
|
; CHECK: call __cxa_end_catch
|
|
|
|
; CHECK: br 1
|
|
|
|
; CHECK: end_block
|
2019-07-16 06:49:25 +08:00
|
|
|
; CHECK: rethrow $[[EXNREF]]
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: end_try
|
2019-02-26 11:29:59 +08:00
|
|
|
define void @test_catch() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
|
[WebAssembly] Support instruction selection for catching exceptions
Summary:
This lowers exception catching-related instructions:
1. Lowers `wasm.catch` intrinsic to `catch` instruction
2. Removes `catchpad` and `cleanuppad` instructions; they are not
necessary after isel phase. (`MachineBasicBlock::isEHFuncletEntry()` or
`MachineBasicBlock::isEHPad()` can be used instead.)
3. Lowers `catchret` and `cleanupret` instructions to pseudo `catchret`
and `cleanupret` instructions in isel, which will be replaced with other
instructions in `WebAssemblyExceptionPrepare` pass.
4. Adds 'WebAssemblyExceptionPrepare` pass, which is for running various
transformation for EH. Currently this pass only replaces `catchret` and
`cleanupret` instructions into appropriate wasm instructions to make
this patch successfully run until the end.
Currently this does not handle lowering of intrinsics related to LSDA
info generation (`wasm.landingpad.index` and `wasm.lsda`), because they
cannot be tested without implementing `EHStreamer`'s wasm-specific
handlers. They are marked as TODO, which is needed to make isel pass.
Also this does not generate `try` and `end_try` markers yet, which will
be handled in later patches.
This patch is based on the first wasm EH proposal.
(https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md)
Reviewers: dschuff, majnemer
Subscribers: jfb, sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D44090
llvm-svn: 333705
2018-06-01 06:25:54 +08:00
|
|
|
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*)]
|
|
|
|
%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) ]
|
|
|
|
call void @__cxa_end_catch() [ "funclet"(token %1) ]
|
|
|
|
catchret from %1 to label %try.cont
|
|
|
|
|
|
|
|
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) ]
|
[WebAssembly] Support instruction selection for catching exceptions
Summary:
This lowers exception catching-related instructions:
1. Lowers `wasm.catch` intrinsic to `catch` instruction
2. Removes `catchpad` and `cleanuppad` instructions; they are not
necessary after isel phase. (`MachineBasicBlock::isEHFuncletEntry()` or
`MachineBasicBlock::isEHPad()` can be used instead.)
3. Lowers `catchret` and `cleanupret` instructions to pseudo `catchret`
and `cleanupret` instructions in isel, which will be replaced with other
instructions in `WebAssemblyExceptionPrepare` pass.
4. Adds 'WebAssemblyExceptionPrepare` pass, which is for running various
transformation for EH. Currently this pass only replaces `catchret` and
`cleanupret` instructions into appropriate wasm instructions to make
this patch successfully run until the end.
Currently this does not handle lowering of intrinsics related to LSDA
info generation (`wasm.landingpad.index` and `wasm.lsda`), because they
cannot be tested without implementing `EHStreamer`'s wasm-specific
handlers. They are marked as TODO, which is needed to make isel pass.
Also this does not generate `try` and `end_try` markers yet, which will
be handled in later patches.
This patch is based on the first wasm EH proposal.
(https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md)
Reviewers: dschuff, majnemer
Subscribers: jfb, sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D44090
llvm-svn: 333705
2018-06-01 06:25:54 +08:00
|
|
|
unreachable
|
|
|
|
|
|
|
|
try.cont: ; preds = %entry, %catch
|
2017-06-30 08:43:15 +08:00
|
|
|
ret void
|
|
|
|
}
|
[WebAssembly] Support instruction selection for catching exceptions
Summary:
This lowers exception catching-related instructions:
1. Lowers `wasm.catch` intrinsic to `catch` instruction
2. Removes `catchpad` and `cleanuppad` instructions; they are not
necessary after isel phase. (`MachineBasicBlock::isEHFuncletEntry()` or
`MachineBasicBlock::isEHPad()` can be used instead.)
3. Lowers `catchret` and `cleanupret` instructions to pseudo `catchret`
and `cleanupret` instructions in isel, which will be replaced with other
instructions in `WebAssemblyExceptionPrepare` pass.
4. Adds 'WebAssemblyExceptionPrepare` pass, which is for running various
transformation for EH. Currently this pass only replaces `catchret` and
`cleanupret` instructions into appropriate wasm instructions to make
this patch successfully run until the end.
Currently this does not handle lowering of intrinsics related to LSDA
info generation (`wasm.landingpad.index` and `wasm.lsda`), because they
cannot be tested without implementing `EHStreamer`'s wasm-specific
handlers. They are marked as TODO, which is needed to make isel pass.
Also this does not generate `try` and `end_try` markers yet, which will
be handled in later patches.
This patch is based on the first wasm EH proposal.
(https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md)
Reviewers: dschuff, majnemer
Subscribers: jfb, sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D44090
llvm-svn: 333705
2018-06-01 06:25:54 +08:00
|
|
|
|
2019-02-26 11:29:59 +08:00
|
|
|
; Destructor (cleanup) test
|
|
|
|
;
|
|
|
|
; void foo();
|
|
|
|
; struct Temp {
|
|
|
|
; ~Temp() {}
|
|
|
|
; };
|
|
|
|
; void test_cleanup() {
|
|
|
|
; Temp t;
|
|
|
|
; foo();
|
|
|
|
; }
|
|
|
|
|
[WebAssembly] Support instruction selection for catching exceptions
Summary:
This lowers exception catching-related instructions:
1. Lowers `wasm.catch` intrinsic to `catch` instruction
2. Removes `catchpad` and `cleanuppad` instructions; they are not
necessary after isel phase. (`MachineBasicBlock::isEHFuncletEntry()` or
`MachineBasicBlock::isEHPad()` can be used instead.)
3. Lowers `catchret` and `cleanupret` instructions to pseudo `catchret`
and `cleanupret` instructions in isel, which will be replaced with other
instructions in `WebAssemblyExceptionPrepare` pass.
4. Adds 'WebAssemblyExceptionPrepare` pass, which is for running various
transformation for EH. Currently this pass only replaces `catchret` and
`cleanupret` instructions into appropriate wasm instructions to make
this patch successfully run until the end.
Currently this does not handle lowering of intrinsics related to LSDA
info generation (`wasm.landingpad.index` and `wasm.lsda`), because they
cannot be tested without implementing `EHStreamer`'s wasm-specific
handlers. They are marked as TODO, which is needed to make isel pass.
Also this does not generate `try` and `end_try` markers yet, which will
be handled in later patches.
This patch is based on the first wasm EH proposal.
(https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md)
Reviewers: dschuff, majnemer
Subscribers: jfb, sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D44090
llvm-svn: 333705
2018-06-01 06:25:54 +08:00
|
|
|
; CHECK-LABEL: test_cleanup:
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: try
|
|
|
|
; CHECK: call foo
|
2019-07-16 06:49:25 +08:00
|
|
|
; CHECK: catch $[[EXNREF:[0-9]+]]=
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: global.set __stack_pointer
|
|
|
|
; CHECK: i32.call $drop=, _ZN4TempD2Ev
|
2019-07-16 06:49:25 +08:00
|
|
|
; CHECK: rethrow $[[EXNREF]]
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: end_try
|
[WebAssembly] Support instruction selection for catching exceptions
Summary:
This lowers exception catching-related instructions:
1. Lowers `wasm.catch` intrinsic to `catch` instruction
2. Removes `catchpad` and `cleanuppad` instructions; they are not
necessary after isel phase. (`MachineBasicBlock::isEHFuncletEntry()` or
`MachineBasicBlock::isEHPad()` can be used instead.)
3. Lowers `catchret` and `cleanupret` instructions to pseudo `catchret`
and `cleanupret` instructions in isel, which will be replaced with other
instructions in `WebAssemblyExceptionPrepare` pass.
4. Adds 'WebAssemblyExceptionPrepare` pass, which is for running various
transformation for EH. Currently this pass only replaces `catchret` and
`cleanupret` instructions into appropriate wasm instructions to make
this patch successfully run until the end.
Currently this does not handle lowering of intrinsics related to LSDA
info generation (`wasm.landingpad.index` and `wasm.lsda`), because they
cannot be tested without implementing `EHStreamer`'s wasm-specific
handlers. They are marked as TODO, which is needed to make isel pass.
Also this does not generate `try` and `end_try` markers yet, which will
be handled in later patches.
This patch is based on the first wasm EH proposal.
(https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md)
Reviewers: dschuff, majnemer
Subscribers: jfb, sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D44090
llvm-svn: 333705
2018-06-01 06:25:54 +08:00
|
|
|
define void @test_cleanup() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
|
|
|
|
entry:
|
2019-02-26 11:29:59 +08:00
|
|
|
%t = alloca %struct.Temp, align 1
|
[WebAssembly] Support instruction selection for catching exceptions
Summary:
This lowers exception catching-related instructions:
1. Lowers `wasm.catch` intrinsic to `catch` instruction
2. Removes `catchpad` and `cleanuppad` instructions; they are not
necessary after isel phase. (`MachineBasicBlock::isEHFuncletEntry()` or
`MachineBasicBlock::isEHPad()` can be used instead.)
3. Lowers `catchret` and `cleanupret` instructions to pseudo `catchret`
and `cleanupret` instructions in isel, which will be replaced with other
instructions in `WebAssemblyExceptionPrepare` pass.
4. Adds 'WebAssemblyExceptionPrepare` pass, which is for running various
transformation for EH. Currently this pass only replaces `catchret` and
`cleanupret` instructions into appropriate wasm instructions to make
this patch successfully run until the end.
Currently this does not handle lowering of intrinsics related to LSDA
info generation (`wasm.landingpad.index` and `wasm.lsda`), because they
cannot be tested without implementing `EHStreamer`'s wasm-specific
handlers. They are marked as TODO, which is needed to make isel pass.
Also this does not generate `try` and `end_try` markers yet, which will
be handled in later patches.
This patch is based on the first wasm EH proposal.
(https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md)
Reviewers: dschuff, majnemer
Subscribers: jfb, sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D44090
llvm-svn: 333705
2018-06-01 06:25:54 +08:00
|
|
|
invoke void @foo()
|
|
|
|
to label %invoke.cont unwind label %ehcleanup
|
|
|
|
|
|
|
|
invoke.cont: ; preds = %entry
|
2019-02-26 11:29:59 +08:00
|
|
|
%call = call %struct.Temp* @_ZN4TempD2Ev(%struct.Temp* %t)
|
[WebAssembly] Support instruction selection for catching exceptions
Summary:
This lowers exception catching-related instructions:
1. Lowers `wasm.catch` intrinsic to `catch` instruction
2. Removes `catchpad` and `cleanuppad` instructions; they are not
necessary after isel phase. (`MachineBasicBlock::isEHFuncletEntry()` or
`MachineBasicBlock::isEHPad()` can be used instead.)
3. Lowers `catchret` and `cleanupret` instructions to pseudo `catchret`
and `cleanupret` instructions in isel, which will be replaced with other
instructions in `WebAssemblyExceptionPrepare` pass.
4. Adds 'WebAssemblyExceptionPrepare` pass, which is for running various
transformation for EH. Currently this pass only replaces `catchret` and
`cleanupret` instructions into appropriate wasm instructions to make
this patch successfully run until the end.
Currently this does not handle lowering of intrinsics related to LSDA
info generation (`wasm.landingpad.index` and `wasm.lsda`), because they
cannot be tested without implementing `EHStreamer`'s wasm-specific
handlers. They are marked as TODO, which is needed to make isel pass.
Also this does not generate `try` and `end_try` markers yet, which will
be handled in later patches.
This patch is based on the first wasm EH proposal.
(https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md)
Reviewers: dschuff, majnemer
Subscribers: jfb, sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D44090
llvm-svn: 333705
2018-06-01 06:25:54 +08:00
|
|
|
ret void
|
|
|
|
|
|
|
|
ehcleanup: ; preds = %entry
|
|
|
|
%0 = cleanuppad within none []
|
2019-02-26 11:29:59 +08:00
|
|
|
%call1 = call %struct.Temp* @_ZN4TempD2Ev(%struct.Temp* %t) [ "funclet"(token %0) ]
|
[WebAssembly] Support instruction selection for catching exceptions
Summary:
This lowers exception catching-related instructions:
1. Lowers `wasm.catch` intrinsic to `catch` instruction
2. Removes `catchpad` and `cleanuppad` instructions; they are not
necessary after isel phase. (`MachineBasicBlock::isEHFuncletEntry()` or
`MachineBasicBlock::isEHPad()` can be used instead.)
3. Lowers `catchret` and `cleanupret` instructions to pseudo `catchret`
and `cleanupret` instructions in isel, which will be replaced with other
instructions in `WebAssemblyExceptionPrepare` pass.
4. Adds 'WebAssemblyExceptionPrepare` pass, which is for running various
transformation for EH. Currently this pass only replaces `catchret` and
`cleanupret` instructions into appropriate wasm instructions to make
this patch successfully run until the end.
Currently this does not handle lowering of intrinsics related to LSDA
info generation (`wasm.landingpad.index` and `wasm.lsda`), because they
cannot be tested without implementing `EHStreamer`'s wasm-specific
handlers. They are marked as TODO, which is needed to make isel pass.
Also this does not generate `try` and `end_try` markers yet, which will
be handled in later patches.
This patch is based on the first wasm EH proposal.
(https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md)
Reviewers: dschuff, majnemer
Subscribers: jfb, sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D44090
llvm-svn: 333705
2018-06-01 06:25:54 +08:00
|
|
|
cleanupret from %0 unwind to caller
|
|
|
|
}
|
|
|
|
|
2019-02-26 11:29:59 +08:00
|
|
|
; Calling a function that may throw within a 'catch (...)' generates a
|
|
|
|
; temrinatepad, because __cxa_end_catch() also can throw within 'catch (...)'.
|
|
|
|
;
|
|
|
|
; void foo();
|
|
|
|
; void test_terminatepad() {
|
|
|
|
; try {
|
|
|
|
; foo();
|
|
|
|
; } catch (...) {
|
|
|
|
; foo();
|
|
|
|
; }
|
|
|
|
; }
|
|
|
|
|
2018-06-25 09:07:11 +08:00
|
|
|
; CHECK-LABEL: test_terminatepad
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: try
|
|
|
|
; CHECK: call foo
|
|
|
|
; CHECK: catch
|
|
|
|
; CHECK: i32.call $drop=, __cxa_begin_catch
|
2019-02-26 11:29:59 +08:00
|
|
|
; CHECK: try
|
|
|
|
; CHECK: call 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
|
|
|
; CHECK: catch
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: try
|
|
|
|
; CHECK: call __cxa_end_catch
|
|
|
|
; CHECK: catch
|
|
|
|
; CHECK: block i32
|
|
|
|
; CHECK: br_on_exn 0, __cpp_exception
|
|
|
|
; CHECK: call __clang_call_terminate, 0
|
|
|
|
; CHECK: unreachable
|
|
|
|
; CHECK: end_block
|
|
|
|
; CHECK: call __clang_call_terminate
|
|
|
|
; CHECK: unreachable
|
|
|
|
; CHECK: end_try
|
|
|
|
; CHECK: rethrow
|
2019-02-26 11:29:59 +08:00
|
|
|
; CHECK: end_try
|
2019-02-27 08:50:53 +08:00
|
|
|
; 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 @test_terminatepad() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
|
2018-06-25 09:07:11 +08:00
|
|
|
entry:
|
|
|
|
invoke void @foo()
|
|
|
|
to label %try.cont unwind label %catch.dispatch
|
|
|
|
|
[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
|
|
|
catch.dispatch: ; preds = %entry
|
|
|
|
%0 = catchswitch within none [label %catch.start] unwind to caller
|
2018-06-25 09:07:11 +08:00
|
|
|
|
|
|
|
catch.start: ; preds = %catch.dispatch
|
[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
|
|
|
%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) ]
|
|
|
|
invoke void @foo() [ "funclet"(token %1) ]
|
|
|
|
to label %invoke.cont1 unwind label %ehcleanup
|
2018-06-25 09:07:11 +08:00
|
|
|
|
[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
|
|
|
invoke.cont1: ; preds = %catch.start
|
|
|
|
call void @__cxa_end_catch() [ "funclet"(token %1) ]
|
|
|
|
catchret from %1 to label %try.cont
|
2018-06-25 09:07:11 +08:00
|
|
|
|
[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.cont: ; preds = %entry, %invoke.cont1
|
|
|
|
ret void
|
2018-06-25 09:07:11 +08:00
|
|
|
|
[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
|
|
|
ehcleanup: ; preds = %catch.start
|
|
|
|
%5 = cleanuppad within %1 []
|
|
|
|
invoke void @__cxa_end_catch() [ "funclet"(token %5) ]
|
|
|
|
to label %invoke.cont2 unwind label %terminate
|
2018-06-25 09:07:11 +08:00
|
|
|
|
[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
|
|
|
invoke.cont2: ; preds = %ehcleanup
|
|
|
|
cleanupret from %5 unwind to caller
|
2018-06-25 09:07:11 +08:00
|
|
|
|
|
|
|
terminate: ; preds = %ehcleanup
|
[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
|
|
|
%6 = cleanuppad within %5 []
|
|
|
|
%7 = call i8* @llvm.wasm.get.exception(token %6)
|
|
|
|
call void @__clang_call_terminate(i8* %7) [ "funclet"(token %6) ]
|
2018-06-25 09:07:11 +08:00
|
|
|
unreachable
|
|
|
|
}
|
|
|
|
|
2018-08-22 03:44:11 +08:00
|
|
|
; Tests prologues and epilogues are not generated within EH scopes.
|
|
|
|
; They should not be treated as funclets; BBs starting with a catch instruction
|
|
|
|
; should not have a prologue, and BBs ending with a catchret/cleanupret should
|
|
|
|
; not have an epilogue. This is separate from __stack_pointer restoring
|
|
|
|
; instructions after a catch instruction.
|
2019-02-26 11:29:59 +08:00
|
|
|
;
|
|
|
|
; void bar(int) noexcept;
|
|
|
|
; void test_no_prolog_epilog_in_ehpad() {
|
|
|
|
; int stack_var = 0;
|
|
|
|
; bar(stack_var);
|
|
|
|
; try {
|
|
|
|
; foo();
|
|
|
|
; } catch (int) {
|
|
|
|
; foo();
|
|
|
|
; }
|
|
|
|
; }
|
2018-08-22 03:44:11 +08:00
|
|
|
|
|
|
|
; CHECK-LABEL: test_no_prolog_epilog_in_ehpad
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: try
|
|
|
|
; CHECK: call foo
|
|
|
|
; CHECK: catch
|
|
|
|
; CHECK-NOT: global.get $push{{.+}}=, __stack_pointer
|
|
|
|
; CHECK: global.set __stack_pointer
|
|
|
|
; CHECK: block
|
2019-02-26 11:29:59 +08:00
|
|
|
; CHECK: block
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: br_if 0
|
|
|
|
; CHECK: i32.call $drop=, __cxa_begin_catch
|
|
|
|
; CHECK: try
|
|
|
|
; CHECK: call foo
|
|
|
|
; CHECK: catch
|
|
|
|
; CHECK-NOT: global.get $push{{.+}}=, __stack_pointer
|
|
|
|
; CHECK: global.set __stack_pointer
|
|
|
|
; CHECK: call __cxa_end_catch
|
|
|
|
; CHECK: rethrow
|
|
|
|
; CHECK-NOT: global.set __stack_pointer, $pop{{.+}}
|
|
|
|
; CHECK: end_try
|
2019-02-26 11:29:59 +08:00
|
|
|
; CHECK: end_block
|
[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
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: end_block
|
|
|
|
; CHECK-NOT: global.set __stack_pointer, $pop{{.+}}
|
|
|
|
; CHECK: call __cxa_end_catch
|
|
|
|
; CHECK: end_try
|
2018-08-22 03:44:11 +08:00
|
|
|
define void @test_no_prolog_epilog_in_ehpad() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
|
|
|
|
entry:
|
|
|
|
%stack_var = alloca i32, align 4
|
|
|
|
call void @bar(i32* %stack_var)
|
|
|
|
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*)]
|
|
|
|
%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 float*
|
|
|
|
%7 = load float, float* %6, align 4
|
|
|
|
invoke void @foo() [ "funclet"(token %1) ]
|
|
|
|
to label %invoke.cont1 unwind label %ehcleanup
|
|
|
|
|
|
|
|
invoke.cont1: ; preds = %catch
|
|
|
|
call void @__cxa_end_catch() [ "funclet"(token %1) ]
|
|
|
|
catchret from %1 to label %try.cont
|
|
|
|
|
|
|
|
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-22 03:44:11 +08:00
|
|
|
unreachable
|
|
|
|
|
|
|
|
try.cont: ; preds = %entry, %invoke.cont1
|
|
|
|
ret void
|
|
|
|
|
|
|
|
ehcleanup: ; preds = %catch
|
|
|
|
%8 = cleanuppad within %1 []
|
|
|
|
call void @__cxa_end_catch() [ "funclet"(token %8) ]
|
|
|
|
cleanupret from %8 unwind to caller
|
|
|
|
}
|
|
|
|
|
2018-08-23 05:13:49 +08:00
|
|
|
; When a function does not have stack-allocated objects, it does not need to
|
|
|
|
; store SP back to __stack_pointer global at the epilog.
|
2019-02-26 11:29:59 +08:00
|
|
|
;
|
|
|
|
; void foo();
|
|
|
|
; void test_no_sp_writeback() {
|
|
|
|
; try {
|
|
|
|
; foo();
|
|
|
|
; } catch (...) {
|
|
|
|
; }
|
|
|
|
; }
|
|
|
|
|
|
|
|
; CHECK-LABEL: test_no_sp_writeback
|
2019-02-27 08:50:53 +08:00
|
|
|
; CHECK: try
|
|
|
|
; CHECK: call foo
|
|
|
|
; CHECK: catch
|
|
|
|
; CHECK: i32.call $drop=, __cxa_begin_catch
|
|
|
|
; CHECK: call __cxa_end_catch
|
|
|
|
; CHECK: end_try
|
2019-02-26 11:29:59 +08:00
|
|
|
; CHECK-NOT: global.set __stack_pointer
|
|
|
|
; CHECK: return
|
|
|
|
define void @test_no_sp_writeback() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
|
2018-08-23 05:13:49 +08:00
|
|
|
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) #2 [ "funclet"(token %1) ]
|
|
|
|
call void @__cxa_end_catch() [ "funclet"(token %1) ]
|
|
|
|
catchret from %1 to label %try.cont
|
|
|
|
|
|
|
|
try.cont: ; preds = %entry, %catch.start
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
2019-02-26 12:08:49 +08:00
|
|
|
; When the result of @llvm.wasm.get.exception is not used. This is created to
|
|
|
|
; fix a bug in LateEHPrepare and this should not crash.
|
|
|
|
define void @test_get_exception_wo_use() 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)
|
|
|
|
catchret from %1 to label %try.cont
|
|
|
|
|
|
|
|
try.cont: ; preds = %entry, %catch.start
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
[WebAssembly] Support instruction selection for catching exceptions
Summary:
This lowers exception catching-related instructions:
1. Lowers `wasm.catch` intrinsic to `catch` instruction
2. Removes `catchpad` and `cleanuppad` instructions; they are not
necessary after isel phase. (`MachineBasicBlock::isEHFuncletEntry()` or
`MachineBasicBlock::isEHPad()` can be used instead.)
3. Lowers `catchret` and `cleanupret` instructions to pseudo `catchret`
and `cleanupret` instructions in isel, which will be replaced with other
instructions in `WebAssemblyExceptionPrepare` pass.
4. Adds 'WebAssemblyExceptionPrepare` pass, which is for running various
transformation for EH. Currently this pass only replaces `catchret` and
`cleanupret` instructions into appropriate wasm instructions to make
this patch successfully run until the end.
Currently this does not handle lowering of intrinsics related to LSDA
info generation (`wasm.landingpad.index` and `wasm.lsda`), because they
cannot be tested without implementing `EHStreamer`'s wasm-specific
handlers. They are marked as TODO, which is needed to make isel pass.
Also this does not generate `try` and `end_try` markers yet, which will
be handled in later patches.
This patch is based on the first wasm EH proposal.
(https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md)
Reviewers: dschuff, majnemer
Subscribers: jfb, sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D44090
llvm-svn: 333705
2018-06-01 06:25:54 +08:00
|
|
|
declare void @foo()
|
2018-08-22 03:44:11 +08:00
|
|
|
declare void @bar(i32*)
|
[WebAssembly] Support instruction selection for catching exceptions
Summary:
This lowers exception catching-related instructions:
1. Lowers `wasm.catch` intrinsic to `catch` instruction
2. Removes `catchpad` and `cleanuppad` instructions; they are not
necessary after isel phase. (`MachineBasicBlock::isEHFuncletEntry()` or
`MachineBasicBlock::isEHPad()` can be used instead.)
3. Lowers `catchret` and `cleanupret` instructions to pseudo `catchret`
and `cleanupret` instructions in isel, which will be replaced with other
instructions in `WebAssemblyExceptionPrepare` pass.
4. Adds 'WebAssemblyExceptionPrepare` pass, which is for running various
transformation for EH. Currently this pass only replaces `catchret` and
`cleanupret` instructions into appropriate wasm instructions to make
this patch successfully run until the end.
Currently this does not handle lowering of intrinsics related to LSDA
info generation (`wasm.landingpad.index` and `wasm.lsda`), because they
cannot be tested without implementing `EHStreamer`'s wasm-specific
handlers. They are marked as TODO, which is needed to make isel pass.
Also this does not generate `try` and `end_try` markers yet, which will
be handled in later patches.
This patch is based on the first wasm EH proposal.
(https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md)
Reviewers: dschuff, majnemer
Subscribers: jfb, sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D44090
llvm-svn: 333705
2018-06-01 06:25:54 +08:00
|
|
|
declare i32 @__gxx_wasm_personality_v0(...)
|
[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
|
|
|
declare void @llvm.wasm.throw(i32, i8*)
|
[WebAssembly] Support instruction selection for catching exceptions
Summary:
This lowers exception catching-related instructions:
1. Lowers `wasm.catch` intrinsic to `catch` instruction
2. Removes `catchpad` and `cleanuppad` instructions; they are not
necessary after isel phase. (`MachineBasicBlock::isEHFuncletEntry()` or
`MachineBasicBlock::isEHPad()` can be used instead.)
3. Lowers `catchret` and `cleanupret` instructions to pseudo `catchret`
and `cleanupret` instructions in isel, which will be replaced with other
instructions in `WebAssemblyExceptionPrepare` pass.
4. Adds 'WebAssemblyExceptionPrepare` pass, which is for running various
transformation for EH. Currently this pass only replaces `catchret` and
`cleanupret` instructions into appropriate wasm instructions to make
this patch successfully run until the end.
Currently this does not handle lowering of intrinsics related to LSDA
info generation (`wasm.landingpad.index` and `wasm.lsda`), because they
cannot be tested without implementing `EHStreamer`'s wasm-specific
handlers. They are marked as TODO, which is needed to make isel pass.
Also this does not generate `try` and `end_try` markers yet, which will
be handled in later patches.
This patch is based on the first wasm EH proposal.
(https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md)
Reviewers: dschuff, majnemer
Subscribers: jfb, sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D44090
llvm-svn: 333705
2018-06-01 06:25:54 +08:00
|
|
|
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()
|
[WebAssembly] Support instruction selection for catching exceptions
Summary:
This lowers exception catching-related instructions:
1. Lowers `wasm.catch` intrinsic to `catch` instruction
2. Removes `catchpad` and `cleanuppad` instructions; they are not
necessary after isel phase. (`MachineBasicBlock::isEHFuncletEntry()` or
`MachineBasicBlock::isEHPad()` can be used instead.)
3. Lowers `catchret` and `cleanupret` instructions to pseudo `catchret`
and `cleanupret` instructions in isel, which will be replaced with other
instructions in `WebAssemblyExceptionPrepare` pass.
4. Adds 'WebAssemblyExceptionPrepare` pass, which is for running various
transformation for EH. Currently this pass only replaces `catchret` and
`cleanupret` instructions into appropriate wasm instructions to make
this patch successfully run until the end.
Currently this does not handle lowering of intrinsics related to LSDA
info generation (`wasm.landingpad.index` and `wasm.lsda`), because they
cannot be tested without implementing `EHStreamer`'s wasm-specific
handlers. They are marked as TODO, which is needed to make isel pass.
Also this does not generate `try` and `end_try` markers yet, which will
be handled in later patches.
This patch is based on the first wasm EH proposal.
(https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md)
Reviewers: dschuff, majnemer
Subscribers: jfb, sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D44090
llvm-svn: 333705
2018-06-01 06:25:54 +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*)
|
2019-02-26 11:29:59 +08:00
|
|
|
declare %struct.Temp* @_ZN4TempD2Ev(%struct.Temp* returned)
|
2018-11-14 10:46:21 +08:00
|
|
|
|
|
|
|
; CHECK: __cpp_exception:
|
2018-12-11 09:11:04 +08:00
|
|
|
; CHECK: .eventtype __cpp_exception i32
|