From 831efe0e0f0ce56b63fb6a07e2cc4844e7c47a34 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Sun, 11 Aug 2019 06:24:07 +0000 Subject: [PATCH] Fix __clang_call_termiante's argument for foreign exceptions Summary: When exceptions are repeatedly thrown in the middle of handling another exception, we call `__clang_call_terminate` with the exception pointer (i32) as an argument. But in case of foreign exceptions, we don't have the pointer, so we call the function with 0. (This requires `__clang_call_terminate` can deal with 0 argument, which will be done later) But previously the 0 argument was not added as a `i32.const 0` but an immediate by mistake, causing the `call` instruction to take not an i32 but rather an exnref, because an `exnref` is left on top of the value stack if `br_on_exn` is not taken. ``` block i32 br_on_exn 0, __cpp_exception ;; exnref is on top of stack now i32.const 0 ;; This was missing! call __clang_call_terminate unreachable end call __clang_call_terminate ;; This takes i32 extracted by br_on_exn ``` Reviewers: dschuff Subscribers: sbc100, jgravelle-google, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D65475 llvm-svn: 368527 --- llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp | 5 ++++- llvm/test/CodeGen/WebAssembly/exception.ll | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp index e92b344..fda116d 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp @@ -233,6 +233,7 @@ bool WebAssemblyLateEHPrepare::removeUnnecessaryUnreachables( // it. The pseudo instruction will be deleted later. bool WebAssemblyLateEHPrepare::addExceptionExtraction(MachineFunction &MF) { const auto &TII = *MF.getSubtarget().getInstrInfo(); + MachineRegisterInfo &MRI = MF.getRegInfo(); auto *EHInfo = MF.getWasmEHFuncInfo(); SmallVector ExtractInstrs; SmallVector ToDelete; @@ -339,9 +340,11 @@ bool WebAssemblyLateEHPrepare::addExceptionExtraction(MachineFunction &MF) { WebAssembly::ClangCallTerminateFn); assert(ClangCallTerminateFn && "There is no __clang_call_terminate() function"); + unsigned Reg = MRI.createVirtualRegister(&WebAssembly::I32RegClass); + BuildMI(ElseMBB, DL, TII.get(WebAssembly::CONST_I32), Reg).addImm(0); BuildMI(ElseMBB, DL, TII.get(WebAssembly::CALL_VOID)) .addGlobalAddress(ClangCallTerminateFn) - .addImm(0); + .addReg(Reg); BuildMI(ElseMBB, DL, TII.get(WebAssembly::UNREACHABLE)); } else { diff --git a/llvm/test/CodeGen/WebAssembly/exception.ll b/llvm/test/CodeGen/WebAssembly/exception.ll index fc61f40..af470b2 100644 --- a/llvm/test/CodeGen/WebAssembly/exception.ll +++ b/llvm/test/CodeGen/WebAssembly/exception.ll @@ -138,7 +138,8 @@ ehcleanup: ; preds = %entry ; CHECK: catch ; CHECK: block i32 ; CHECK: br_on_exn 0, __cpp_exception -; CHECK: call __clang_call_terminate, 0 +; CHECK: i32.const ${{.*}}=, 0 +; CHECK: call __clang_call_terminate ; CHECK: unreachable ; CHECK: end_block ; CHECK: call __clang_call_terminate -- 2.7.4