diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -4265,6 +4265,17 @@ Check(F->hasPersonalityFn(), "CatchPadInst needs to be in a function with a personality.", &CPI); + // Only MSVC CXX catchpad handles alloca. + if (classifyEHPersonality(F->getPersonalityFn()) == EHPersonality::MSVC_CXX) { + Check(CPI.getNumOperands() == 4, "WinEH catchpad needs 4 operands.", &CPI); + Value *V = CPI.getArgOperand(2)->stripPointerCasts(); + if (auto *AI = dyn_cast(V)) + Check(AI->isStaticAlloca(), "WinEH needs static alloca", &CPI); + else + Check(isa(V), + "Catch object needs to be alloca or null ptr", &CPI); + } + Check(isa(CPI.getParentPad()), "CatchPadInst needs to be directly nested in a CatchSwitchInst.", CPI.getParentPad()); diff --git a/llvm/test/CodeGen/WinEH/wineh-cloning.ll b/llvm/test/CodeGen/WinEH/wineh-cloning.ll --- a/llvm/test/CodeGen/WinEH/wineh-cloning.ll +++ b/llvm/test/CodeGen/WinEH/wineh-cloning.ll @@ -20,7 +20,7 @@ catch.switch: %cs = catchswitch within none [label %catch] unwind to caller catch: - %cp = catchpad within %cs [] + %cp = catchpad within %cs [ptr null, i32 0, ptr null] br label %noreturn noreturn: ; %x use colors: {entry, cleanup} @@ -38,7 +38,7 @@ ; CHECK: catch.switch: ; CHECK: %cs = catchswitch within none [label %catch] unwind to caller ; CHECK: catch: -; CHECK: catchpad within %cs [] +; CHECK: catchpad within %cs [ptr null, i32 0, ptr null] ; CHECK-NEXT: call void @llvm.foo(i32 %x) ; CHECK: [[EntryCopy]]: ; CHECK: call void @llvm.foo(i32 %x) @@ -81,7 +81,7 @@ catch.switch: %cs = catchswitch within none [label %catch] unwind to caller catch: - catchpad within %cs [] + catchpad within %cs [ptr null, i32 0, ptr null] br label %shared cleanup: cleanuppad within none [] @@ -99,7 +99,7 @@ ; CHECK: invoke void @f() ; CHECK: to label %[[exit:[^ ]+]] unwind ; CHECK: catch: -; CHECK: catchpad within %cs [] +; CHECK: catchpad within %cs [ptr null, i32 0, ptr null] ; CHECK-NEXT: call void @llvm.bar() ; CHECK-NEXT: unreachable ; CHECK: cleanup: @@ -117,7 +117,7 @@ catch.switch: %cs = catchswitch within none [label %catch] unwind to caller catch: - catchpad within %cs [] + catchpad within %cs [ptr null, i32 0, ptr null] br label %shared shared: %x = call i32 @llvm.qux() @@ -149,7 +149,7 @@ ; CHECK: entry: ; CHECK: to label %[[shared_E:[^ ]+]] unwind label %catch.switch ; CHECK: catch: -; CHECK: catchpad within %cs [] +; CHECK: catchpad within %cs [ptr null, i32 0, ptr null] ; CHECK: [[x_C:%[^ ]+]] = call i32 @llvm.qux() ; CHECK: [[i_C:%[^ ]+]] = call i32 @llvm.qux() ; CHECK: [[zt_C:%[^ ]+]] = icmp eq i32 [[i_C]], 0 @@ -246,7 +246,7 @@ %cs = catchswitch within none [label %catch.body] unwind to caller catch.body: - %catch = catchpad within %cs [] + %catch = catchpad within %cs [ptr null, i32 0, ptr null] catchret from %catch to label %exit exit: ret void @@ -263,7 +263,7 @@ ; CHECK: outer: ; CHECK-NEXT: %cs = catchswitch within none [label %catch.body] unwind to caller ; CHECK: catch.body: -; CHECK-NEXT: %catch = catchpad within %cs [] +; CHECK-NEXT: %catch = catchpad within %cs [ptr null, i32 0, ptr null] ; CHECK-NEXT: catchret from %catch to label %exit ; CHECK: exit: ; CHECK-NEXT: ret void diff --git a/llvm/test/CodeGen/WinEH/wineh-demotion.ll b/llvm/test/CodeGen/WinEH/wineh-demotion.ll --- a/llvm/test/CodeGen/WinEH/wineh-demotion.ll +++ b/llvm/test/CodeGen/WinEH/wineh-demotion.ll @@ -41,7 +41,7 @@ %cs1 = catchswitch within none [label %catch] unwind to caller catch: - %cp = catchpad within %cs1 [] + %cp = catchpad within %cs1 [ptr null, i32 0, ptr null] ; CHECK: catch: ; CHECK: [[Reload:%[^ ]+]] = load i32, ptr [[Slot]] ; CHECK-NEXT: call void @h(i32 [[Reload]]) @@ -80,7 +80,7 @@ %cs1 = catchswitch within none [label %catch.inner] unwind label %merge.outer catch.inner: - %cpinner = catchpad within %cs1 [] + %cpinner = catchpad within %cs1 [ptr null, i32 0, ptr null] ; Need just one store here because only %y is affected ; CHECK: catch.inner: %z = call i32 @g() [ "funclet"(token %cpinner) ] @@ -100,9 +100,9 @@ %cs2 = catchswitch within none [label %catch.outer] unwind to caller catch.outer: - %cpouter = catchpad within %cs2 [] + %cpouter = catchpad within %cs2 [ptr null, i32 0, ptr null] ; CHECK: catch.outer: - ; CHECK: [[CatchPad:%[^ ]+]] = catchpad within %cs2 [] + ; CHECK: [[CatchPad:%[^ ]+]] = catchpad within %cs2 [ptr null, i32 0, ptr null] ; Need to load x and y from two different slots since they're both live ; and can have different values (if we came from catch.inner) ; CHECK-DAG: load i32, ptr [[Slot1]] @@ -147,7 +147,7 @@ %phi.inner = phi i32 [ %l, %left ], [ %r, %right ] %cs1 = catchswitch within none [label %catch.inner] unwind label %catchpad.outer catch.inner: - %cp1 = catchpad within %cs1 [] + %cp1 = catchpad within %cs1 [ptr null, i32 0, ptr null] catchret from %cp1 to label %join join: ; CHECK: join: @@ -167,7 +167,7 @@ ; CHECK: catch.outer: ; CHECK: [[Reload:%[^ ]+]] = load i32, ptr [[Slot]] ; CHECK: call void @h(i32 [[Reload]]) - %cp2 = catchpad within %cs2 [] + %cp2 = catchpad within %cs2 [ptr null, i32 0, ptr null] call void @h(i32 %phi.outer) [ "funclet"(token %cp2) ] catchret from %cp2 to label %exit exit: @@ -240,7 +240,7 @@ ; CHECK: catchpad within %cs1 ; CHECK: [[CatchReload:%[^ ]+]] = load i32, ptr [[CatchSlot]] ; CHECK: call void @h(i32 [[CatchReload]] - %cp2 = catchpad within %cs1 [] + %cp2 = catchpad within %cs1 [ptr null, i32 0, ptr null] call void @h(i32 %phi.catch) [ "funclet"(token %cp2) ] catchret from %cp2 to label %exit @@ -295,8 +295,8 @@ %cs1 = catchswitch within none [label %catch] unwind to caller catch: ; CHECK: catch: - ; CHECK-NEXT: %[[CatchPad:[^ ]+]] = catchpad within %cs1 [] - %cp = catchpad within %cs1 [] + ; CHECK-NEXT: %[[CatchPad:[^ ]+]] = catchpad within %cs1 [ptr null, i32 0, ptr null] + %cp = catchpad within %cs1 [ptr null, i32 0, ptr null] %b = call i1 @i() [ "funclet"(token %cp) ] br i1 %b, label %left, label %right left: diff --git a/llvm/test/CodeGen/WinEH/wineh-intrinsics.ll b/llvm/test/CodeGen/WinEH/wineh-intrinsics.ll --- a/llvm/test/CodeGen/WinEH/wineh-intrinsics.ll +++ b/llvm/test/CodeGen/WinEH/wineh-intrinsics.ll @@ -17,7 +17,7 @@ catchpad: %cs1 = catchswitch within none [label %do_catch] unwind to caller do_catch: - %catch = catchpad within %cs1 [i32 1] + %catch = catchpad within %cs1 [ptr null, i32 0, ptr null] %exn = call ptr @llvm.eh.exceptionpointer.p0(token %catch) call void (...) @f(ptr %exn) catchret from %catch to label %exit diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/catchpad-phi-cast.ll b/llvm/test/Transforms/CodeGenPrepare/X86/catchpad-phi-cast.ll --- a/llvm/test/Transforms/CodeGenPrepare/X86/catchpad-phi-cast.ll +++ b/llvm/test/Transforms/CodeGenPrepare/X86/catchpad-phi-cast.ll @@ -37,7 +37,7 @@ %cs1 = catchswitch within none [label %handler1] unwind to caller handler1: - %cp1 = catchpad within %cs1 [] + %cp1 = catchpad within %cs1 [ptr null, i32 0, ptr null] br label %catch.shared ; CHECK: handler1: ; CHECK-NEXT: catchpad within %cs1 @@ -46,7 +46,7 @@ %cs2 = catchswitch within none [label %handler2] unwind to caller handler2: - %cp2 = catchpad within %cs2 [] + %cp2 = catchpad within %cs2 [ptr null, i32 0, ptr null] br label %catch.shared ; CHECK: handler2: ; CHECK: catchpad within %cs2 @@ -78,7 +78,7 @@ %cs1 = catchswitch within none [label %catch] unwind to caller catch: - %cp1 = catchpad within %cs1 [] + %cp1 = catchpad within %cs1 [ptr null, i32 0, ptr null] tail call void @llvm.dbg.value(metadata ptr %p, i64 0, metadata !11, metadata !13), !dbg !14 call void @g(ptr %p) catchret from %cp1 to label %ret diff --git a/llvm/test/Transforms/DeadStoreElimination/multiblock-exceptions.ll b/llvm/test/Transforms/DeadStoreElimination/multiblock-exceptions.ll --- a/llvm/test/Transforms/DeadStoreElimination/multiblock-exceptions.ll +++ b/llvm/test/Transforms/DeadStoreElimination/multiblock-exceptions.ll @@ -22,7 +22,7 @@ ; CHECK: catch.dispatch: ; CHECK-NEXT: [[CS1:%.*]] = catchswitch within none [label %catch] unwind label [[CLEANUP:%.*]] ; CHECK: catch: -; CHECK-NEXT: [[C:%.*]] = catchpad within [[CS1]] [] +; CHECK-NEXT: [[C:%.*]] = catchpad within [[CS1]] [ptr null, i32 0, ptr null] ; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[SV]] ; CHECK-NEXT: br label [[EXIT]] ; CHECK: cleanup: @@ -48,7 +48,7 @@ %cs1 = catchswitch within none [label %catch] unwind label %cleanup catch: - %c = catchpad within %cs1 [] + %c = catchpad within %cs1 [ptr null, i32 0, ptr null] %lv = load i32, ptr %sv br label %exit diff --git a/llvm/test/Transforms/GVN/PRE/pre-load.ll b/llvm/test/Transforms/GVN/PRE/pre-load.ll --- a/llvm/test/Transforms/GVN/PRE/pre-load.ll +++ b/llvm/test/Transforms/GVN/PRE/pre-load.ll @@ -562,7 +562,7 @@ ; CHECK: catch.dispatch: ; CHECK-NEXT: [[CS1:%.*]] = catchswitch within none [label %catch] unwind label [[CLEANUP2:%.*]] ; CHECK: catch: -; CHECK-NEXT: [[C:%.*]] = catchpad within [[CS1]] [] +; CHECK-NEXT: [[C:%.*]] = catchpad within [[CS1]] [ptr null, i32 0, ptr null] ; CHECK-NEXT: catchret from [[C]] to label [[BLOCK2]] ; CHECK: cleanup: ; CHECK-NEXT: [[C1:%.*]] = cleanuppad within none [] @@ -589,7 +589,7 @@ %cs1 = catchswitch within none [label %catch] unwind label %cleanup2 catch: - %c = catchpad within %cs1 [] + %c = catchpad within %cs1 [ptr null, i32 0, ptr null] catchret from %c to label %block2 cleanup: diff --git a/llvm/test/Transforms/GlobalOpt/preallocated.ll b/llvm/test/Transforms/GlobalOpt/preallocated.ll --- a/llvm/test/Transforms/GlobalOpt/preallocated.ll +++ b/llvm/test/Transforms/GlobalOpt/preallocated.ll @@ -96,7 +96,7 @@ ; CHECK: contb: ; CHECK-NEXT: [[S:%.*]] = catchswitch within none [label %catch] unwind to caller ; CHECK: catch: -; CHECK-NEXT: [[P:%.*]] = catchpad within [[S]] [] +; CHECK-NEXT: [[P:%.*]] = catchpad within [[S]] [ptr null, i32 0, ptr null] ; CHECK-NEXT: catchret from [[P]] to label [[CONT:%.*]] ; CHECK: cont: ; CHECK-NEXT: ret i32 42 @@ -110,7 +110,7 @@ contb: %s = catchswitch within none [label %catch] unwind to caller catch: - %p = catchpad within %s [] + %p = catchpad within %s [ptr null, i32 0, ptr null] catchret from %p to label %cont cont: ret i32 42 diff --git a/llvm/test/Transforms/InstCombine/token.ll b/llvm/test/Transforms/InstCombine/token.ll --- a/llvm/test/Transforms/InstCombine/token.ll +++ b/llvm/test/Transforms/InstCombine/token.ll @@ -36,7 +36,7 @@ %cs = catchswitch within none [label %doit] unwind to caller doit: - %cl = catchpad within %cs [] + %cl = catchpad within %cs [ptr null, i32 0, ptr null] call void @g(i32 %phi) unreachable @@ -72,7 +72,7 @@ %cs = catchswitch within none [label %doit] unwind to caller doit: - %cl = catchpad within %cs [] + %cl = catchpad within %cs [ptr null, i32 0, ptr null] call void @g(i32 %phi) unreachable diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll --- a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll @@ -115,11 +115,11 @@ %catch = catchswitch within none [label %loop_catch_latch, label %loop_exit] unwind to caller loop_catch_latch: - %catchpad_latch = catchpad within %catch [] + %catchpad_latch = catchpad within %catch [ptr null, i32 0, ptr null] catchret from %catchpad_latch to label %loop_begin loop_exit: - %catchpad_exit = catchpad within %catch [] + %catchpad_exit = catchpad within %catch [ptr null, i32 0, ptr null] catchret from %catchpad_exit to label %exit exit: diff --git a/llvm/test/Verifier/preallocated-valid.ll b/llvm/test/Verifier/preallocated-valid.ll --- a/llvm/test/Verifier/preallocated-valid.ll +++ b/llvm/test/Verifier/preallocated-valid.ll @@ -67,7 +67,7 @@ contb: %s = catchswitch within none [label %catch] unwind to caller catch: - %p = catchpad within %s [] + %p = catchpad within %s [ptr null, i32 0, ptr null] call void @llvm.call.preallocated.teardown(token %cs) ret void }