From 222718fdd20545e90f46e93d76b58eeb3dd63773 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Tue, 26 Mar 2019 17:29:55 +0000 Subject: [PATCH] [WebAssembly] Fix a bug when mixing TRY/LOOP markers Summary: When TRY and LOOP markers are in the same BB and END_TRY and END_LOOP markers are in the same BB, END_TRY should be _before_ END_LOOP, because LOOP is always before TRY if they are in the same BB. (TRY is placed in the latest possible position, whereas LOOP is in the earliest possible position.) Reviewers: dschuff Subscribers: sunfish, sbc100, jgravelle-google, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59751 llvm-svn: 357008 --- .../Target/WebAssembly/WebAssemblyCFGStackify.cpp | 4 ++- llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll | 32 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp index b1a4795..7a7838a 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp @@ -579,7 +579,9 @@ void WebAssemblyCFGStackify::placeTryMarker(MachineBasicBlock &MBB) { // the END_TRY marker should go after that. Otherwise, the whole try-catch // is contained within this loop, so the END_TRY should go before that. if (MI.getOpcode() == WebAssembly::END_LOOP) { - if (EndToBegin[&MI]->getParent()->getNumber() >= Header->getNumber()) + // For a LOOP to be after TRY, LOOP's BB should be after TRY's BB; if they + // are in the same BB, LOOP is always before TRY. + if (EndToBegin[&MI]->getParent()->getNumber() > Header->getNumber()) BeforeSet.insert(&MI); #ifndef NDEBUG else diff --git a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll index f0f4934..a93babe 100644 --- a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll +++ b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll @@ -335,6 +335,38 @@ try.cont: ; preds = %catch.start, %bb4, ret void } +; Tests if try/end_try markers are placed correctly wrt loop/end_loop markers, +; when try and loop markers are in the same BB and end_try and end_loop are in +; another BB. +; CHECK: loop +; CHECK: try +; CHECK: call foo +; CHECK: catch +; CHECK: end_try +; CHECK: end_loop +define void @test4(i32* %p) personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { +entry: + store volatile i32 0, i32* %p + br label %loop + +loop: ; preds = %try.cont, %entry + store volatile i32 1, i32* %p + invoke void @foo() + to label %try.cont unwind label %catch.dispatch + +catch.dispatch: ; preds = %loop + %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, %loop + br label %loop +} + declare void @foo() declare void @bar() declare i32 @__gxx_wasm_personality_v0(...) -- 2.7.4