diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td | 8 | ||||
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp | 19 |
2 files changed, 21 insertions, 6 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td index d44458f790a..574cb09ff33 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td @@ -144,7 +144,13 @@ defm THROW : I<(outs), (ins event_op:$tag, variable_ops), (outs), (ins event_op:$tag), [(WebAssemblythrow (WebAssemblywrapper texternalsym:$tag))], "throw \t$tag", "throw \t$tag", 0x08>; -defm RETHROW : NRI<(outs), (ins), [(int_wasm_rethrow)], "rethrow", 0x09>; +defm RETHROW : I<(outs), (ins EXCEPT_REF:$exn), (outs), (ins), + [], "rethrow \t$exn", "rethrow", 0x09>; +// Pseudo instruction to be the lowering target of int_wasm_rethrow_in_catch +// intrinsic. Will be converted to the real rethrow instruction later. +let isPseudo = 1 in +defm RETHROW_IN_CATCH : NRI<(outs), (ins), [(int_wasm_rethrow_in_catch)], + "rethrow_in_catch", 0>; } // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 // Region within which an exception is caught: try / end_try diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp index 5b6fdb86c6d..f365aa73792 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp @@ -161,9 +161,17 @@ bool WebAssemblyLateEHPrepare::replaceFuncletReturns(MachineFunction &MF) { Changed = true; break; } - case WebAssembly::CLEANUPRET: { - // Replace a cleanupret with a rethrow - BuildMI(MBB, TI, TI->getDebugLoc(), TII.get(WebAssembly::RETHROW)); + case WebAssembly::CLEANUPRET: + case WebAssembly::RETHROW_IN_CATCH: { + // Replace a cleanupret/rethrow_in_catch with a rethrow + auto *EHPad = getMatchingEHPad(TI); + auto CatchPos = EHPad->begin(); + if (CatchPos->isEHLabel()) // EH pad starts with an EH label + ++CatchPos; + MachineInstr *Catch = &*CatchPos; + unsigned ExnReg = Catch->getOperand(0).getReg(); + BuildMI(MBB, TI, TI->getDebugLoc(), TII.get(WebAssembly::RETHROW)) + .addReg(ExnReg); TI->eraseFromParent(); Changed = true; break; @@ -191,7 +199,8 @@ bool WebAssemblyLateEHPrepare::removeUnnecessaryUnreachables( SmallVector<MachineBasicBlock *, 8> Succs(MBB.succ_begin(), MBB.succ_end()); for (auto *Succ : Succs) - MBB.removeSuccessor(Succ); + if (!Succ->isEHPad()) + MBB.removeSuccessor(Succ); eraseDeadBBsAndChildren(Succs); } } @@ -337,7 +346,7 @@ bool WebAssemblyLateEHPrepare::addExceptionExtraction(MachineFunction &MF) { BuildMI(ElseMBB, DL, TII.get(WebAssembly::UNREACHABLE)); } else { - BuildMI(ElseMBB, DL, TII.get(WebAssembly::RETHROW)); + BuildMI(ElseMBB, DL, TII.get(WebAssembly::RETHROW)).addReg(ExnReg); if (EHInfo->hasEHPadUnwindDest(EHPad)) ElseMBB->addSuccessor(EHInfo->getEHPadUnwindDest(EHPad)); } |