[llvm] f4eb722 - CodeGen: Derive WinEHPrepare PHI demotion from the personality (#225676)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 24 01:40:25 PDT 2026


Author: Matt Arsenault
Date: 2026-09-24T10:40:18+02:00
New Revision: f4eb722b0c41a8ac1a239edc8384f8577a1abed4

URL: https://github.com/llvm/llvm-project/commit/f4eb722b0c41a8ac1a239edc8384f8577a1abed4
DIFF: https://github.com/llvm/llvm-project/commit/f4eb722b0c41a8ac1a239edc8384f8577a1abed4.diff

LOG: CodeGen: Derive WinEHPrepare PHI demotion from the personality (#225676)

Previously WinEHPrepare had a catchswitch-only pass option which was
set based on the exception model in the pass config. The only special
case using it was for Wasm EH, which reuses the Windows EH instruction but
does not outline funclets so only needs the catchwitch dispatch phi handling.
Instead check the properties of the personality function inside the pass, so the
pass config is less dependent on knowing the exception model.

Also, make sure the pass is a nop for dwarf EH which appears to be untested.

Co-authored-by: Claude (Claude-Opus-4.8) <noreply at anthropic.com>

Added: 
    llvm/test/CodeGen/WebAssembly/wineh-prepare-wasm-personality.ll
    llvm/test/CodeGen/X86/wineh-prepare-dwarf-personality.ll

Modified: 
    llvm/include/llvm/CodeGen/Passes.h
    llvm/include/llvm/CodeGen/WinEHPrepare.h
    llvm/lib/CodeGen/TargetPassConfig.cpp
    llvm/lib/CodeGen/WinEHPrepare.cpp
    llvm/lib/Passes/CodeGenPassBuilder.cpp
    llvm/lib/Passes/PassBuilder.cpp
    llvm/lib/Passes/PassRegistry.def
    llvm/test/CodeGen/WebAssembly/wasm-eh-prepare.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h
index 861ca5aeeb852..f48cab3e3af7c 100644
--- a/llvm/include/llvm/CodeGen/Passes.h
+++ b/llvm/include/llvm/CodeGen/Passes.h
@@ -422,7 +422,7 @@ LLVM_ABI FunctionPass *createDwarfEHPass(CodeGenOptLevel OptLevel);
 
 /// createWinEHPass - Prepares personality functions used by MSVC on Windows,
 /// in addition to the Itanium LSDA based personalities.
-LLVM_ABI FunctionPass *createWinEHPass(bool DemoteCatchSwitchPHIOnly = false);
+LLVM_ABI FunctionPass *createWinEHPass();
 
 /// createSjLjEHPreparePass - This pass adapts exception handling code to use
 /// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.

diff  --git a/llvm/include/llvm/CodeGen/WinEHPrepare.h b/llvm/include/llvm/CodeGen/WinEHPrepare.h
index 293d6c0bb4ed9..9f561b6a4c50b 100644
--- a/llvm/include/llvm/CodeGen/WinEHPrepare.h
+++ b/llvm/include/llvm/CodeGen/WinEHPrepare.h
@@ -14,11 +14,8 @@
 namespace llvm {
 
 class WinEHPreparePass : public RequiredPassInfoMixin<WinEHPreparePass> {
-  bool DemoteCatchSwitchPHIOnly;
-
 public:
-  WinEHPreparePass(bool DemoteCatchSwitchPHIOnly_ = false)
-      : DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly_) {}
+  WinEHPreparePass() = default;
   LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
 };
 

diff  --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp
index ca67084100254..ac9dc278dafcf 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -956,8 +956,9 @@ void TargetPassConfig::addPassesToHandleExceptions() {
     // Wasm EH uses Windows EH instructions, but it does not need to demote PHIs
     // on catchpads and cleanuppads because it does not outline them into
     // funclets. Catchswitch blocks are not lowered in SelectionDAG, so we
-    // should remove PHIs there.
-    addPass(createWinEHPass(/*DemoteCatchSwitchPHIOnly=*/true));
+    // should remove PHIs there. WinEHPrepare derives this from the Wasm
+    // personality, so no explicit flag is needed here.
+    addPass(createWinEHPass());
     break;
   case ExceptionHandling::Default:
   case ExceptionHandling::None:

diff  --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp
index 40cb11cbeb0de..3408aa7720488 100644
--- a/llvm/lib/CodeGen/WinEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -53,18 +53,10 @@ static cl::opt<bool> DisableCleanups(
     cl::desc("Do not remove implausible terminators or other similar cleanups"),
     cl::init(false));
 
-// TODO: Remove this option when we fully migrate to new pass manager
-static cl::opt<bool> DemoteCatchSwitchPHIOnlyOpt(
-    "demote-catchswitch-only", cl::Hidden,
-    cl::desc("Demote catchswitch BBs only (for wasm EH)"), cl::init(false));
-
 namespace {
 
 class WinEHPrepareImpl {
 public:
-  WinEHPrepareImpl(bool DemoteCatchSwitchPHIOnly)
-      : DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {}
-
   bool runOnFunction(Function &Fn);
 
 private:
@@ -84,7 +76,8 @@ class WinEHPrepareImpl {
   bool cleanupPreparedFunclets(Function &F);
   void verifyPreparedFunclets(Function &F);
 
-  bool DemoteCatchSwitchPHIOnly;
+  // True for Wasm C++ personalities.
+  bool DemoteCatchSwitchPHIOnly = false;
 
   // All fields are reset by runOnFunction.
   EHPersonality Personality = EHPersonality::Unknown;
@@ -95,20 +88,17 @@ class WinEHPrepareImpl {
 };
 
 class WinEHPrepare : public FunctionPass {
-  bool DemoteCatchSwitchPHIOnly;
-
 public:
   static char ID; // Pass identification, replacement for typeid.
 
-  WinEHPrepare(bool DemoteCatchSwitchPHIOnly = false)
-      : FunctionPass(ID), DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {}
+  WinEHPrepare() : FunctionPass(ID) {}
 
   StringRef getPassName() const override {
     return "Windows exception handling preparation";
   }
 
   bool runOnFunction(Function &Fn) override {
-    return WinEHPrepareImpl(DemoteCatchSwitchPHIOnly).runOnFunction(Fn);
+    return WinEHPrepareImpl().runOnFunction(Fn);
   }
 };
 
@@ -116,7 +106,7 @@ class WinEHPrepare : public FunctionPass {
 
 PreservedAnalyses WinEHPreparePass::run(Function &F,
                                         FunctionAnalysisManager &) {
-  bool Changed = WinEHPrepareImpl(DemoteCatchSwitchPHIOnly).runOnFunction(F);
+  bool Changed = WinEHPrepareImpl().runOnFunction(F);
   return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
 }
 
@@ -124,9 +114,7 @@ char WinEHPrepare::ID = 0;
 INITIALIZE_PASS(WinEHPrepare, DEBUG_TYPE, "Prepare Windows exceptions", false,
                 false)
 
-FunctionPass *llvm::createWinEHPass(bool DemoteCatchSwitchPHIOnly) {
-  return new WinEHPrepare(DemoteCatchSwitchPHIOnly);
-}
+FunctionPass *llvm::createWinEHPass() { return new WinEHPrepare(); }
 
 bool WinEHPrepareImpl::runOnFunction(Function &Fn) {
   if (!Fn.hasPersonalityFn())
@@ -139,6 +127,11 @@ bool WinEHPrepareImpl::runOnFunction(Function &Fn) {
   if (!isScopedEHPersonality(Personality))
     return false;
 
+  // Funclet personalities outline catch/cleanup bodies, so every funclet PHI
+  // must be demoted. A scoped-but-non-funclet personality (Wasm) keeps its pads
+  // inline and only needs the catchswitch dispatch PHIs demoted.
+  DemoteCatchSwitchPHIOnly = !isFuncletEHPersonality(Personality);
+
   DL = &Fn.getDataLayout();
   return prepareExplicitEH(Fn);
 }
@@ -1245,8 +1238,7 @@ bool WinEHPrepareImpl::prepareExplicitEH(Function &F) {
   Changed |= cloneCommonBlocks(F);
 
   if (!DisableDemotion)
-    Changed |= demotePHIsOnFunclets(F, DemoteCatchSwitchPHIOnly ||
-                                           DemoteCatchSwitchPHIOnlyOpt);
+    Changed |= demotePHIsOnFunclets(F, DemoteCatchSwitchPHIOnly);
 
   if (!DisableCleanups) {
     assert(!verifyFunction(F, &dbgs()));

diff  --git a/llvm/lib/Passes/CodeGenPassBuilder.cpp b/llvm/lib/Passes/CodeGenPassBuilder.cpp
index a24323d816caa..9c9be1853c833 100644
--- a/llvm/lib/Passes/CodeGenPassBuilder.cpp
+++ b/llvm/lib/Passes/CodeGenPassBuilder.cpp
@@ -469,7 +469,7 @@ void CodeGenPassBuilder::addPassesToHandleExceptions(PassManagerWrapper &PMW) {
     // on catchpads and cleanuppads because it does not outline them into
     // funclets. Catchswitch blocks are not lowered in SelectionDAG, so we
     // should remove PHIs there.
-    addFunctionPass(WinEHPreparePass(/*DemoteCatchSwitchPHIOnly=*/false), PMW);
+    addFunctionPass(WinEHPreparePass(), PMW);
     break;
   case ExceptionHandling::Default:
   case ExceptionHandling::None:

diff  --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 858c76706427e..172533cf66a24 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -1617,11 +1617,6 @@ parseStructuralHashPrinterPassOptions(StringRef Params) {
       inconvertibleErrorCode());
 }
 
-Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
-  return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
-                                            "WinEHPreparePass");
-}
-
 Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
   GlobalMergeOptions Result;
   while (!Params.empty()) {

diff  --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 33c9e19988d7a..af4ce5029551d 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -574,6 +574,7 @@ FUNCTION_PASS("view-dom", DomViewer())
 FUNCTION_PASS("view-dom-only", DomOnlyViewer())
 FUNCTION_PASS("view-post-dom", PostDomViewer())
 FUNCTION_PASS("view-post-dom-only", PostDomOnlyViewer())
+FUNCTION_PASS("win-eh-prepare", WinEHPreparePass())
 FUNCTION_PASS("wasm-eh-prepare", WasmEHPreparePass())
 #undef FUNCTION_PASS
 
@@ -735,12 +736,6 @@ FUNCTION_PASS_WITH_PARAMS(
       return StructurizeCFGPass(SkipUniformRegions);
     },
     parseStructurizeCFGPassOptions, "skip-uniform-regions")
-FUNCTION_PASS_WITH_PARAMS(
-    "win-eh-prepare", "WinEHPreparePass",
-    [](bool DemoteCatchSwitchPHIOnly) {
-      return WinEHPreparePass(DemoteCatchSwitchPHIOnly);
-    },
-    parseWinEHPrepareOptions, "demote-catchswitch-only")
 FUNCTION_PASS_WITH_PARAMS(
     "bounds-checking", "BoundsCheckingPass",
     [](BoundsCheckingPass::Options Options) {

diff  --git a/llvm/test/CodeGen/WebAssembly/wasm-eh-prepare.ll b/llvm/test/CodeGen/WebAssembly/wasm-eh-prepare.ll
index 8e9ab3ac6cab0..4277bc8ae6692 100644
--- a/llvm/test/CodeGen/WebAssembly/wasm-eh-prepare.ll
+++ b/llvm/test/CodeGen/WebAssembly/wasm-eh-prepare.ll
@@ -1,7 +1,7 @@
-; RUN: opt < %s -win-eh-prepare -demote-catchswitch-only -wasm-eh-prepare -S | FileCheck %s
-; RUN: opt < %s -win-eh-prepare -demote-catchswitch-only -wasm-eh-prepare -S --mattr=+atomics,+bulk-memory | FileCheck %s
-; RUN: opt < %s -passes='win-eh-prepare<demote-catchswitch-only>,wasm-eh-prepare' -S | FileCheck %s
-; RUN: opt < %s -passes='win-eh-prepare<demote-catchswitch-only>,wasm-eh-prepare' -S --mattr=+atomics,+bulk-memory | FileCheck %s
+; RUN: opt < %s -win-eh-prepare -wasm-eh-prepare -S | FileCheck %s
+; RUN: opt < %s -win-eh-prepare -wasm-eh-prepare -S --mattr=+atomics,+bulk-memory | FileCheck %s
+; RUN: opt < %s -passes='win-eh-prepare,wasm-eh-prepare' -S | FileCheck %s
+; RUN: opt < %s -passes='win-eh-prepare,wasm-eh-prepare' -S --mattr=+atomics,+bulk-memory | FileCheck %s
 ; RUN: llc < %s -exception-model=wasm -mattr=+exception-handling -stop-after=wasm-eh-prepare | FileCheck %s
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"

diff  --git a/llvm/test/CodeGen/WebAssembly/wineh-prepare-wasm-personality.ll b/llvm/test/CodeGen/WebAssembly/wineh-prepare-wasm-personality.ll
new file mode 100644
index 0000000000000..53bde9cd9b8fd
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/wineh-prepare-wasm-personality.ll
@@ -0,0 +1,111 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -win-eh-prepare -S | FileCheck %s
+; RUN: opt < %s -passes=win-eh-prepare -S | FileCheck %s
+
+; WinEHPrepare derives the PHI-demotion mode from the personality: the
+; Wasm C++ personality does not outline funclets, so only catchswitch
+; PHIs are demoted.
+
+target triple = "wasm32-unknown-unknown"
+
+define void @wasm_phi() personality ptr @__gxx_wasm_personality_v0 {
+; CHECK-LABEL: define void @wasm_phi() personality ptr @__gxx_wasm_personality_v0 {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    [[NUM_1_WINEH_SPILLSLOT:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    invoke void @foo()
+; CHECK-NEXT:            to label %[[INVOKE_CONT:.*]] unwind label %[[EHCLEANUP:.*]]
+; CHECK:       [[INVOKE_CONT]]:
+; CHECK-NEXT:    invoke void @foo()
+; CHECK-NEXT:            to label %[[INVOKE_CONT1:.*]] unwind label %[[EHCLEANUP]]
+; CHECK:       [[INVOKE_CONT1]]:
+; CHECK-NEXT:    br label %[[TRY_CONT:.*]]
+; CHECK:       [[EHCLEANUP]]:
+; CHECK-NEXT:    [[NUM_0:%.*]] = phi i32 [ 2, %[[INVOKE_CONT]] ], [ 1, %[[ENTRY]] ]
+; CHECK-NEXT:    [[PAD:%.*]] = cleanuppad within none []
+; CHECK-NEXT:    cleanupret from [[PAD]] unwind label %[[CATCH_DISPATCH:.*]]
+; CHECK:       [[CATCH_DISPATCH]]:
+; CHECK-NEXT:    [[CS:%.*]] = catchswitch within none [label %[[CATCH_START:.*]]] unwind to caller
+; CHECK:       [[CATCH_START]]:
+; CHECK-NEXT:    [[CP:%.*]] = catchpad within [[CS]] [ptr null]
+; CHECK-NEXT:    [[EXN:%.*]] = call ptr @llvm.wasm.get.exception(token [[CP]])
+; CHECK-NEXT:    [[SEL:%.*]] = call i32 @llvm.wasm.get.ehselector(token [[CP]])
+; CHECK-NEXT:    call void @bar(i32 [[NUM_0]]) [ "funclet"(token [[CP]]) ]
+; CHECK-NEXT:    catchret from [[CP]] to label %[[TRY_CONT]]
+; CHECK:       [[TRY_CONT]]:
+; CHECK-NEXT:    store i32 1, ptr [[NUM_1_WINEH_SPILLSLOT]], align 4
+; CHECK-NEXT:    invoke void @foo()
+; CHECK-NEXT:            to label %[[INVOKE_CONT3:.*]] unwind label %[[CATCH_DISPATCH5:.*]]
+; CHECK:       [[INVOKE_CONT3]]:
+; CHECK-NEXT:    store i32 2, ptr [[NUM_1_WINEH_SPILLSLOT]], align 4
+; CHECK-NEXT:    invoke void @foo()
+; CHECK-NEXT:            to label %[[TRY_CONT10:.*]] unwind label %[[CATCH_DISPATCH5]]
+; CHECK:       [[CATCH_DISPATCH5]]:
+; CHECK-NEXT:    [[CS2:%.*]] = catchswitch within none [label %[[CATCH_START6:.*]]] unwind to caller
+; CHECK:       [[CATCH_START6]]:
+; CHECK-NEXT:    [[CP2:%.*]] = catchpad within [[CS2]] [ptr null]
+; CHECK-NEXT:    [[EXN2:%.*]] = call ptr @llvm.wasm.get.exception(token [[CP2]])
+; CHECK-NEXT:    [[SEL2:%.*]] = call i32 @llvm.wasm.get.ehselector(token [[CP2]])
+; CHECK-NEXT:    [[NUM_1_WINEH_RELOAD:%.*]] = load i32, ptr [[NUM_1_WINEH_SPILLSLOT]], align 4
+; CHECK-NEXT:    call void @bar(i32 [[NUM_1_WINEH_RELOAD]]) [ "funclet"(token [[CP2]]) ]
+; CHECK-NEXT:    catchret from [[CP2]] to label %[[TRY_CONT10]]
+; CHECK:       [[TRY_CONT10]]:
+; CHECK-NEXT:    ret void
+;
+entry:
+  invoke void @foo()
+  to label %invoke.cont unwind label %ehcleanup
+
+invoke.cont:                                      ; preds = %entry
+  invoke void @foo()
+  to label %invoke.cont1 unwind label %ehcleanup
+
+invoke.cont1:                                     ; preds = %invoke.cont
+  br label %try.cont
+
+; The phi before the cleanuppad must be preserved.
+ehcleanup:                                        ; preds = %invoke.cont, %entry
+  %num.0 = phi i32 [ 2, %invoke.cont ], [ 1, %entry ]
+  %pad = cleanuppad within none []
+  cleanupret from %pad unwind label %catch.dispatch
+
+catch.dispatch:                                   ; preds = %ehcleanup
+  %cs = catchswitch within none [label %catch.start] unwind to caller
+
+catch.start:                                      ; preds = %catch.dispatch
+  %cp = catchpad within %cs [ptr null]
+  %exn = call ptr @llvm.wasm.get.exception(token %cp)
+  %sel = call i32 @llvm.wasm.get.ehselector(token %cp)
+  call void @bar(i32 %num.0) [ "funclet"(token %cp) ]
+  catchret from %cp to label %try.cont
+
+try.cont:                                         ; preds = %catch.start, %invoke.cont1
+  invoke void @foo()
+  to label %invoke.cont3 unwind label %catch.dispatch5
+
+invoke.cont3:                                     ; preds = %try.cont
+  invoke void @foo()
+  to label %try.cont10 unwind label %catch.dispatch5
+
+; The phi before the catchswitch is demoted
+catch.dispatch5:                                  ; preds = %invoke.cont3, %try.cont
+  %num.1 = phi i32 [ 2, %invoke.cont3 ], [ 1, %try.cont ]
+  %cs2 = catchswitch within none [label %catch.start6] unwind to caller
+
+catch.start6:                                     ; preds = %catch.dispatch5
+  %cp2 = catchpad within %cs2 [ptr null]
+  %exn2 = call ptr @llvm.wasm.get.exception(token %cp2)
+  %sel2 = call i32 @llvm.wasm.get.ehselector(token %cp2)
+  call void @bar(i32 %num.1) [ "funclet"(token %cp2) ]
+  catchret from %cp2 to label %try.cont10
+
+try.cont10:                                       ; preds = %invoke.cont3, %catch.start6
+  ret void
+}
+
+declare void @foo()
+declare void @bar(i32)
+declare i32 @__gxx_wasm_personality_v0(ptr)
+declare ptr @llvm.wasm.get.exception(token) #0
+declare i32 @llvm.wasm.get.ehselector(token) #0
+
+attributes #0 = { nounwind }

diff  --git a/llvm/test/CodeGen/X86/wineh-prepare-dwarf-personality.ll b/llvm/test/CodeGen/X86/wineh-prepare-dwarf-personality.ll
new file mode 100644
index 0000000000000..fa7dca013817e
--- /dev/null
+++ b/llvm/test/CodeGen/X86/wineh-prepare-dwarf-personality.ll
@@ -0,0 +1,54 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -win-eh-prepare -S | FileCheck %s
+; RUN: opt < %s -passes=win-eh-prepare -S | FileCheck %s
+
+; On a Dwarf EH target the personality is not scope-based, so
+; WinEHPrepare is a no-op.
+
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @dwarf_phi(i1 %c) personality ptr @__gxx_personality_v0 {
+; CHECK-LABEL: define i32 @dwarf_phi(
+; CHECK-SAME: i1 [[C:%.*]]) personality ptr @__gxx_personality_v0 {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    br i1 [[C]], label %[[LEFT:.*]], label %[[RIGHT:.*]]
+; CHECK:       [[LEFT]]:
+; CHECK-NEXT:    invoke void @foo()
+; CHECK-NEXT:            to label %[[CONT:.*]] unwind label %[[LPAD:.*]]
+; CHECK:       [[RIGHT]]:
+; CHECK-NEXT:    invoke void @foo()
+; CHECK-NEXT:            to label %[[CONT]] unwind label %[[LPAD]]
+; CHECK:       [[LPAD]]:
+; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, %[[LEFT]] ], [ 1, %[[RIGHT]] ]
+; CHECK-NEXT:    [[LP:%.*]] = landingpad { ptr, i32 }
+; CHECK-NEXT:            cleanup
+; CHECK-NEXT:    call void @bar(i32 [[P]])
+; CHECK-NEXT:    resume { ptr, i32 } [[LP]]
+; CHECK:       [[CONT]]:
+; CHECK-NEXT:    ret i32 0
+;
+entry:
+  br i1 %c, label %left, label %right
+
+left:                                             ; preds = %entry
+  invoke void @foo()
+  to label %cont unwind label %lpad
+
+right:                                            ; preds = %entry
+  invoke void @foo()
+  to label %cont unwind label %lpad
+
+lpad:                                             ; preds = %left, %right
+  %p = phi i32 [ 0, %left ], [ 1, %right ]
+  %lp = landingpad { ptr, i32 }
+  cleanup
+  call void @bar(i32 %p)
+  resume { ptr, i32 } %lp
+
+cont:                                             ; preds = %left, %right
+  ret i32 0
+}
+
+declare void @foo()
+declare void @bar(i32)
+declare i32 @__gxx_personality_v0(...)


        


More information about the llvm-commits mailing list