Index: lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp =================================================================== --- lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp +++ lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp @@ -594,11 +594,22 @@ TII.get(WebAssembly::END_TRY)); registerTryScope(Begin, End, &MBB); - // Track the farthest-spanning scope that ends at this point. - int Number = Cont->getNumber(); - if (!ScopeTops[Number] || - ScopeTops[Number]->getNumber() > Header->getNumber()) - ScopeTops[Number] = Header; + // Track the farthest-spanning scope that ends at this point. We create two + // mappings: (BB with 'end_try' -> BB with 'try') and (BB with 'catch' -> BB + // with 'try'). We need to create 'catch' -> 'try' mapping here too because + // markers should not span across 'catch'. For example, this should not + // happen: + // + // try + // block --| (X) + // catch | + // end_block --| + // end_try + for (int Number : {Cont->getNumber(), MBB.getNumber()}) { + if (!ScopeTops[Number] || + ScopeTops[Number]->getNumber() > Header->getNumber()) + ScopeTops[Number] = Header; + } } void WebAssemblyCFGStackify::removeUnnecessaryInstrs(MachineFunction &MF) { Index: test/CodeGen/WebAssembly/cfg-stackify-eh.ll =================================================================== --- test/CodeGen/WebAssembly/cfg-stackify-eh.ll +++ test/CodeGen/WebAssembly/cfg-stackify-eh.ll @@ -88,7 +88,44 @@ ; } ; CHECK-LABEL: test1 -; TODO Fill in check lines +; 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 +; CHECK: br 2 # 2: down to label10 +; CHECK: catch +; CHECK: call __cxa_end_catch +; CHECK: rethrow # down to catch3 +; CHECK: end_try +; CHECK: end_block # label11: +; CHECK: call __cxa_rethrow +; CHECK: unreachable +; CHECK: catch {{.*}} # catch3: +; CHECK: call __cxa_end_catch +; CHECK: rethrow # to caller +; CHECK: end_try # label10: +; CHECK: call __cxa_end_catch +; CHECK: br 2 # 2: down to label6 +; CHECK: end_try +; CHECK: end_block # label7: +; CHECK: call __cxa_rethrow +; CHECK: unreachable +; CHECK: end_block # label6: +; CHECK: call __cxa_end_catch +; CHECK: end_try define void @test1() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { entry: invoke void @foo()