diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp @@ -212,7 +212,7 @@ while (InsertPos != MBB.end() && InsertPos->isEHLabel()) InsertPos++; // This runs after hoistCatches(), so we assume that if there is a catch, - // that should be the non-EH label first instruction in an EH pad. + // that should be the first non-EH-label instruction in an EH pad. if (InsertPos == MBB.end() || !WebAssembly::isCatch(InsertPos->getOpcode())) { Changed = true; @@ -383,10 +383,13 @@ // with leaf functions, and we don't restore __stack_pointer in leaf // functions anyway. auto InsertPos = MBB.begin(); - if (InsertPos->isEHLabel()) // EH pad starts with an EH label - ++InsertPos; - if (WebAssembly::isCatch(InsertPos->getOpcode())) - ++InsertPos; + // Skip EH_LABELs in the beginning of an EH pad if present. + while (InsertPos != MBB.end() && InsertPos->isEHLabel()) + InsertPos++; + assert(InsertPos != MBB.end() && + WebAssembly::isCatch(InsertPos->getOpcode()) && + "catch/catch_all should be present in every EH pad at this point"); + ++InsertPos; // Skip the catch instruction FrameLowering->writeSPToGlobal(FrameLowering->getSPReg(MF), MF, MBB, InsertPos, MBB.begin()->getDebugLoc()); } diff --git a/llvm/test/CodeGen/WebAssembly/exception.mir b/llvm/test/CodeGen/WebAssembly/exception.mir --- a/llvm/test/CodeGen/WebAssembly/exception.mir +++ b/llvm/test/CodeGen/WebAssembly/exception.mir @@ -24,6 +24,8 @@ name: eh_label_test liveins: - { reg: '$arguments' } +frameInfo: + hasCalls: true body: | bb.0: ; TRY should be before EH_LABEL wrappers of throwing calls @@ -41,10 +43,15 @@ bb.1 (landing-pad): ; predecessors: %bb.0 successors: %bb.2 - ; CATCH_ALL should be after an EH_LABEL at the beginning of an EH pad + ; CATCH_ALL should be after EH_LABELs in the beginning of an EH pad. + ; (Sometimes there are multiple EH_LABELs in an EH pad. This test tests + ; that.) GLOBAL_SET should follow right after that. ; CHECK: bb.1 ; CHECK: EH_LABEL + ; CHECK: EH_LABEL ; CHECK-NEXT: CATCH_ALL + ; CHECK-NEXT: GLOBAL_SET_I32 + EH_LABEL EH_LABEL CATCHRET %bb.2, %bb.1, implicit-def dead $arguments