Index: lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp =================================================================== --- lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp +++ lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp @@ -222,18 +222,22 @@ const auto &TII = *MF.getSubtarget().getInstrInfo(); auto *EHInfo = MF.getWasmEHFuncInfo(); SmallVector ExtractInstrs; + SmallVector ToDelete; for (auto &MBB : MF) { for (auto &MI : MBB) { if (MI.getOpcode() == WebAssembly::EXTRACT_EXCEPTION_I32) { if (MI.getOperand(0).isDead()) - MI.eraseFromParent(); + ToDelete.push_back(&MI); else ExtractInstrs.push_back(&MI); } } } + bool Changed = !ToDelete.empty() || !ExtractInstrs.empty(); + for (auto *MI : ToDelete) + MI->eraseFromParent(); if (ExtractInstrs.empty()) - return false; + return Changed; // Find terminate pads. SmallSet TerminatePads; Index: test/CodeGen/WebAssembly/exception.ll =================================================================== --- test/CodeGen/WebAssembly/exception.ll +++ test/CodeGen/WebAssembly/exception.ll @@ -340,6 +340,26 @@ ret void } +; When the result of @llvm.wasm.get.exception is not used. This is created to +; fix a bug in LateEHPrepare and this should not crash. +define void @test_get_exception_wo_use() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { +entry: + invoke void @foo() + to label %try.cont unwind label %catch.dispatch + +catch.dispatch: ; preds = %entry + %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 = %entry, %catch.start + ret void +} + declare void @foo() declare void @bar(i32*) declare i32 @__gxx_wasm_personality_v0(...)