llvm.org GIT mirror llvm / 7741851
Adding support for llvm.eh.begincatch and llvm.eh.endcatch intrinsics and beginning the documentation of native Windows exception handling. Differential Revision: http://reviews.llvm.org/D7398 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228733 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Kaylor 4 years ago
6 changed file(s) with 757 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
6262 handling at the expense of slower execution when no exceptions are thrown. As
6363 exceptions are, by their nature, intended for uncommon code paths, DWARF
6464 exception handling is generally preferred to SJLJ.
65
66 Windows Runtime Exception Handling
67 -----------------------------------
68
69 Windows runtime based exception handling uses the same basic IR structure as
70 Itanium ABI based exception handling, but it relies on the personality
71 functions provided by the native Windows runtime library, ``__CxxFrameHandler3``
72 for C++ exceptions: ``__C_specific_handler`` for 64-bit SEH or
73 ``_frame_handler3/4`` for 32-bit SEH. This results in a very different
74 execution model and requires some minor modifications to the initial IR
75 representation and a significant restructuring just before code generation.
76
77 General information about the Windows x64 exception handling mechanism can be
78 found at `MSDN Exception Handling (x64)
79 _`.
6580
6681 Overview
6782 --------
305320 the `resume instruction `_ if none of the conditions
306321 match.
307322
323 C++ Exception Handling using the Windows Runtime
324 =================================================
325
326 (Note: Windows C++ exception handling support is a work in progress and is
327 not yet fully implemented. The text below describes how it will work
328 when completed.)
329
330 The Windows runtime function for C++ exception handling uses a mutli-phase
331 approach. When an exception occurs it searches the current callstack for a
332 frame that has a handler for the exception. If a handler is found, it then
333 calls the cleanup handler for each frame above the handler which has a
334 cleanup handler before calling the catch handler. These calls are all made
335 from a stack context different from the original frame in which the handler
336 is defined. Therefore, it is necessary to outline these handlers from their
337 original context before code generation.
338
339 Catch handlers are called with a pointer to the handler itself as the first
340 argument and a pointer to the parent function's stack frame as the second
341 argument. The catch handler uses the `llvm.recoverframe
342 `_ to get a
343 pointer to a frame allocation block that is created in the parent frame using
344 the `llvm.allocateframe
345 `_ intrinsic.
346 The ``WinEHPrepare`` pass will have created a structure definition for the
347 contents of this block. The first two members of the structure will always be
348 (1) a 32-bit integer that the runtime uses to track the exception state of the
349 parent frame for the purposes of handling chained exceptions and (2) a pointer
350 to the object associated with the exception (roughly, the parameter of the
351 catch clause). These two members will be followed by any frame variables from
352 the parent function which must be accessed in any of the functions unwind or
353 catch handlers. The catch handler returns the address at which execution
354 should continue.
355
356 Cleanup handlers perform any cleanup necessary as the frame goes out of scope,
357 such as calling object destructors. The runtime handles the actual unwinding
358 of the stack. If an exception occurs in a cleanup handler the runtime manages
359 termination of the process. Cleanup handlers are called with the same arguments
360 as catch handlers (a pointer to the handler and a pointer to the parent stack
361 frame) and use the same mechanism described above to access frame variables
362 in the parent function. Cleanup handlers do not return a value.
363
364 The IR generated for Windows runtime based C++ exception handling is initially
365 very similar to the ``landingpad`` mechanism described above. Calls to
366 libc++abi functions (such as ``__cxa_begin_catch``/``__cxa_end_catch`` and
367 ``__cxa_throw_exception`` are replaced with calls to intrinsics or Windows
368 runtime functions (such as ``llvm.eh.begincatch``/``llvm.eh.endcatch`` and
369 ``__CxxThrowException``).
370
371 During the WinEHPrepare pass, the handler functions are outlined into handler
372 functions and the original landing pad code is replaced with a call to the
373 ``llvm.eh.actions`` intrinsic that describes the order in which handlers will
374 be processed from the logical location of the landing pad and an indirect
375 branch to the return value of the ``llvm.eh.actions`` intrinsic. The
376 ``llvm.eh.actions`` intrinsic is defined as returning the address at which
377 execution will continue. This is a temporary construct which will be removed
378 before code generation, but it allows for the accurate tracking of control
379 flow until then.
380
381 A typical landing pad will look like this after outlining:
382
383 .. code-block:: llvm
384
385 lpad:
386 %vals = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
387 cleanup
388 catch i8* bitcast (i8** @_ZTIi to i8*)
389 catch i8* bitcast (i8** @_ZTIf to i8*)
390 %recover = call i8* (...)* @llvm.eh.actions(
391 i32 3, i8* bitcast (i8** @_ZTIi to i8*), i8* (i8*, i8*)* @_Z4testb.catch.1)
392 i32 2, i8* null, void (i8*, i8*)* @_Z4testb.cleanup.1)
393 i32 1, i8* bitcast (i8** @_ZTIf to i8*), i8* (i8*, i8*)* @_Z4testb.catch.0)
394 i32 0, i8* null, void (i8*, i8*)* @_Z4testb.cleanup.0)
395 indirectbr i8* %recover, [label %try.cont1, label %try.cont2]
396
397 In this example, the landing pad represents an exception handling context with
398 two catch handlers and a cleanup handler that have been outlined. If an
399 exception is thrown with a type that matches ``_ZTIi``, the ``_Z4testb.catch.1``
400 handler will be called an no clean-up is needed. If an exception is thrown
401 with a type that matches ``_ZTIf``, first the ``_Z4testb.cleanup.1`` handler
402 will be called to perform unwind-related cleanup, then the ``_Z4testb.catch.1``
403 handler will be called. If an exception is throw which does not match either
404 of these types and the exception is handled by another frame further up the
405 call stack, first the ``_Z4testb.cleanup.1`` handler will be called, then the
406 ``_Z4testb.cleanup.0`` handler (which corresponds to a different scope) will be
407 called, and exception handling will continue at the next frame in the call
408 stack will be called. One of the catch handlers will return the address of
409 ``%try.cont1`` in the parent function and the other will return the address of
410 ``%try.cont2``, meaning that execution continues at one of those blocks after
411 an exception is caught.
412
413
308414 Exception Handling Intrinsics
309415 =============================
310416
327433 ``landingpad`` instruction. The single argument is a reference to a type info.
328434
329435 Uses of this intrinsic are generated by the C++ front-end.
436
437 .. _llvm.eh.begincatch:
438
439 ``llvm.eh.begincatch``
440 ----------------------
441
442 .. code-block:: llvm
443
444 i8* @llvm.eh.begincatch(i8* %exn)
445
446
447 This intrinsic marks the beginning of catch handling code within the blocks
448 following a ``landingpad`` instruction. The exact behavior of this function
449 depends on the compilation target and the personality function associated
450 with the ``landingpad`` instruction.
451
452 The argument to this intrinsic is a pointer that was previously extracted from
453 the aggregate return value of the ``landingpad`` instruction. The return
454 value of the intrinsic is a pointer to the exception object to be used by the
455 catch code. This pointer is returned as an ``i8*`` value, but the actual type
456 of the object will depend on the exception that was thrown.
457
458 Uses of this intrinsic are generated by the C++ front-end. Many targets will
459 use implementation-specific functions (such as ``__cxa_begin_catch``) instead
460 of this intrinsic. The intrinsic is provided for targets that require a more
461 abstract interface.
462
463 When used in the native Windows C++ exception handling implementation, this
464 intrinsic serves as a placeholder to delimit code before a catch handler is
465 outlined. When the handler is is outlined, this intrinsic will be replaced
466 by instructions that retrieve the exception object pointer from the frame
467 allocation block.
468
469
470 .. _llvm.eh.endcatch:
471
472 ``llvm.eh.endcatch``
473 ----------------------
474
475 .. code-block:: llvm
476
477 void @llvm.eh.endcatch()
478
479
480 This intrinsic marks the end of catch handling code within the current block,
481 which will be a successor of a block which called ``llvm.eh.begincatch''.
482 The exact behavior of this function depends on the compilation target and the
483 personality function associated with the corresponding ``landingpad``
484 instruction.
485
486 There may be more than one call to ``llvm.eh.endcatch`` for any given call to
487 ``llvm.eh.begincatch`` with each ``llvm.eh.endcatch`` call corresponding to the
488 end of a different control path. All control paths following a call to
489 ``llvm.eh.begincatch`` must reach a call to ``llvm.eh.endcatch``.
490
491 Uses of this intrinsic are generated by the C++ front-end. Many targets will
492 use implementation-specific functions (such as ``__cxa_begin_catch``) instead
493 of this intrinsic. The intrinsic is provided for targets that require a more
494 abstract interface.
495
496 When used in the native Windows C++ exception handling implementation, this
497 intrinsic serves as a placeholder to delimit code before a catch handler is
498 outlined. After the handler is outlined, this intrinsic is simply removed.
499
330500
331501 SJLJ Intrinsics
332502 ---------------
410410 def int_eh_return_i32 : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty]>;
411411 def int_eh_return_i64 : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty]>;
412412
413 // eh.begincatch takes a pointer returned by a landingpad instruction and
414 // returns the exception object pointer for the exception to be handled.
415 def int_eh_begincatch : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty]>;
416 def int_eh_endcatch : Intrinsic<[], []>;
417
413418 // __builtin_unwind_init is an undocumented GCC intrinsic that causes all
414419 // callee-saved registers to be saved and restored (regardless of whether they
415420 // are used) in the calling function. It is used by libgcc_eh.
3434 //===----------------------------------------------------------------------===//
3535
3636 #include "llvm/Analysis/Lint.h"
37 #include "llvm/ADT/SmallSet.h"
3738 #include "llvm/ADT/STLExtras.h"
3839 #include "llvm/Analysis/AliasAnalysis.h"
3940 #include "llvm/Analysis/AssumptionCache.h"
7273 void visitMemoryReference(Instruction &I, Value *Ptr,
7374 uint64_t Size, unsigned Align,
7475 Type *Ty, unsigned Flags);
76 void visitEHBeginCatch(IntrinsicInst *II);
77 void visitEHEndCatch(IntrinsicInst *II);
7578
7679 void visitCallInst(CallInst &I);
7780 void visitInvokeInst(InvokeInst &I);
345348 visitMemoryReference(I, CS.getArgument(0), AliasAnalysis::UnknownSize,
346349 0, nullptr, MemRef::Read | MemRef::Write);
347350 break;
351
352 case Intrinsic::eh_begincatch:
353 visitEHBeginCatch(II);
354 break;
355 case Intrinsic::eh_endcatch:
356 visitEHEndCatch(II);
357 break;
348358 }
349359 }
350360
506516 dyn_cast(findValue(I.getOperand(1), /*OffsetOk=*/false)))
507517 Assert1(CI->getValue().ult(cast(I.getType())->getBitWidth()),
508518 "Undefined result: Shift count out of range", &I);
519 }
520
521 static bool
522 allPredsCameFromLandingPad(BasicBlock *BB,
523 SmallSet &VisitedBlocks) {
524 VisitedBlocks.insert(BB);
525 if (BB->isLandingPad())
526 return true;
527 // If we find a block with no predecessors, the search failed.
528 if (pred_empty(BB))
529 return false;
530 for (BasicBlock *Pred : predecessors(BB)) {
531 if (VisitedBlocks.count(Pred))
532 continue;
533 if (!allPredsCameFromLandingPad(Pred, VisitedBlocks))
534 return false;
535 }
536 return true;
537 }
538
539 static bool
540 allSuccessorsReachEndCatch(BasicBlock *BB, BasicBlock::iterator InstBegin,
541 IntrinsicInst **SecondBeginCatch,
542 SmallSet &VisitedBlocks) {
543 VisitedBlocks.insert(BB);
544 for (BasicBlock::iterator I = InstBegin, E = BB->end(); I != E; ++I) {
545 IntrinsicInst *IC = dyn_cast(I);
546 if (IC && IC->getIntrinsicID() == Intrinsic::eh_endcatch)
547 return true;
548 // If we find another begincatch while looking for an endcatch,
549 // that's also an error.
550 if (IC && IC->getIntrinsicID() == Intrinsic::eh_begincatch) {
551 *SecondBeginCatch = IC;
552 return false;
553 }
554 }
555
556 // If we reach a block with no successors while searching, the
557 // search has failed.
558 if (succ_empty(BB))
559 return false;
560 // Otherwise, search all of the successors.
561 for (BasicBlock *Succ : successors(BB)) {
562 if (VisitedBlocks.count(Succ))
563 continue;
564 if (!allSuccessorsReachEndCatch(Succ, Succ->begin(), SecondBeginCatch,
565 VisitedBlocks))
566 return false;
567 }
568 return true;
569 }
570
571 void Lint::visitEHBeginCatch(IntrinsicInst *II) {
572 // The checks in this function make a potentially dubious assumption about
573 // the CFG, namely that any block involved in a catch is only used for the
574 // catch. This will very likely be true of IR generated by a front end,
575 // but it may cease to be true, for example, if the IR is run through a
576 // pass which combines similar blocks.
577 //
578 // In general, if we encounter a block the isn't dominated by the catch
579 // block while we are searching the catch block's successors for a call
580 // to end catch intrinsic, then it is possible that it will be legal for
581 // a path through this block to never reach a call to llvm.eh.endcatch.
582 // An analogous statement could be made about our search for a landing
583 // pad among the catch block's predecessors.
584 //
585 // What is actually required is that no path is possible at runtime that
586 // reaches a call to llvm.eh.begincatch without having previously visited
587 // a landingpad instruction and that no path is possible at runtime that
588 // calls llvm.eh.begincatch and does not subsequently call llvm.eh.endcatch
589 // (mentally adjusting for the fact that in reality these calls will be
590 // removed before code generation).
591 //
592 // Because this is a lint check, we take a pessimistic approach and warn if
593 // the control flow is potentially incorrect.
594
595 SmallSet VisitedBlocks;
596 BasicBlock *CatchBB = II->getParent();
597
598 // The begin catch must occur in a landing pad block or all paths
599 // to it must have come from a landing pad.
600 Assert1(allPredsCameFromLandingPad(CatchBB, VisitedBlocks),
601 "llvm.eh.begincatch may be reachable without passing a landingpad",
602 II);
603
604 // Reset the visited block list.
605 VisitedBlocks.clear();
606
607 IntrinsicInst *SecondBeginCatch = nullptr;
608
609 // This has to be called before it is asserted. Otherwise, the first assert
610 // below can never be hit.
611 bool EndCatchFound = allSuccessorsReachEndCatch(
612 CatchBB, std::next(static_cast(II)),
613 &SecondBeginCatch, VisitedBlocks);
614 Assert2(
615 SecondBeginCatch == nullptr,
616 "llvm.eh.begincatch may be called a second time before llvm.eh.endcatch",
617 II, SecondBeginCatch);
618 Assert1(EndCatchFound,
619 "Some paths from llvm.eh.begincatch may not reach llvm.eh.endcatch",
620 II);
621 }
622
623 static bool allPredCameFromBeginCatch(
624 BasicBlock *BB, BasicBlock::reverse_iterator InstRbegin,
625 IntrinsicInst **SecondEndCatch, SmallSet &VisitedBlocks) {
626 VisitedBlocks.insert(BB);
627 // Look for a begincatch in this block.
628 for (BasicBlock::reverse_iterator RI = InstRbegin, RE = BB->rend(); RI != RE;
629 ++RI) {
630 IntrinsicInst *IC = dyn_cast(&*RI);
631 if (IC && IC->getIntrinsicID() == Intrinsic::eh_begincatch)
632 return true;
633 // If we find another end catch before we find a begin catch, that's
634 // an error.
635 if (IC && IC->getIntrinsicID() == Intrinsic::eh_endcatch) {
636 *SecondEndCatch = IC;
637 return false;
638 }
639 // If we encounter a landingpad instruction, the search failed.
640 if (isa(*RI))
641 return false;
642 }
643 // If while searching we find a block with no predeccesors,
644 // the search failed.
645 if (pred_empty(BB))
646 return false;
647 // Search any predecessors we haven't seen before.
648 for (BasicBlock *Pred : predecessors(BB)) {
649 if (VisitedBlocks.count(Pred))
650 continue;
651 if (!allPredCameFromBeginCatch(Pred, Pred->rbegin(), SecondEndCatch,
652 VisitedBlocks))
653 return false;
654 }
655 return true;
656 }
657
658 void Lint::visitEHEndCatch(IntrinsicInst *II) {
659 // The check in this function makes a potentially dubious assumption about
660 // the CFG, namely that any block involved in a catch is only used for the
661 // catch. This will very likely be true of IR generated by a front end,
662 // but it may cease to be true, for example, if the IR is run through a
663 // pass which combines similar blocks.
664 //
665 // In general, if we encounter a block the isn't post-dominated by the
666 // end catch block while we are searching the end catch block's predecessors
667 // for a call to the begin catch intrinsic, then it is possible that it will
668 // be legal for a path to reach the end catch block without ever having
669 // called llvm.eh.begincatch.
670 //
671 // What is actually required is that no path is possible at runtime that
672 // reaches a call to llvm.eh.endcatch without having previously visited
673 // a call to llvm.eh.begincatch (mentally adjusting for the fact that in
674 // reality these calls will be removed before code generation).
675 //
676 // Because this is a lint check, we take a pessimistic approach and warn if
677 // the control flow is potentially incorrect.
678
679 BasicBlock *EndCatchBB = II->getParent();
680
681 // Alls paths to the end catch call must pass through a begin catch call.
682
683 // If llvm.eh.begincatch wasn't called in the current block, we'll use this
684 // lambda to recursively look for it in predecessors.
685 SmallSet VisitedBlocks;
686 IntrinsicInst *SecondEndCatch = nullptr;
687
688 // This has to be called before it is asserted. Otherwise, the first assert
689 // below can never be hit.
690 bool BeginCatchFound =
691 allPredCameFromBeginCatch(EndCatchBB, BasicBlock::reverse_iterator(II),
692 &SecondEndCatch, VisitedBlocks);
693 Assert2(
694 SecondEndCatch == nullptr,
695 "llvm.eh.endcatch may be called a second time after llvm.eh.begincatch",
696 II, SecondEndCatch);
697 Assert1(
698 BeginCatchFound,
699 "llvm.eh.endcatch may be reachable without passing llvm.eh.begincatch",
700 II);
509701 }
510702
511703 static bool isZero(Value *V, const DataLayout *DL, DominatorTree *DT,
56695669
56705670 return nullptr;
56715671 }
5672 case Intrinsic::eh_begincatch:
5673 case Intrinsic::eh_endcatch:
5674 llvm_unreachable("begin/end catch intrinsics not lowered in codegen");
56725675 }
56735676 }
56745677
0 ; RUN: opt -lint -disable-output < %s
1
2 ; This test is meant to prove that the verifier does not report errors for correct
3 ; use of the llvm.eh.begincatch and llvm.eh.endcatch intrinsics.
4
5 target triple = "x86_64-pc-windows-msvc"
6
7 declare i8* @llvm.eh.begincatch(i8*)
8
9 declare void @llvm.eh.endcatch()
10
11 @_ZTIi = external constant i8*
12
13 ; Function Attrs: uwtable
14 define void @test_ref_clean() {
15 entry:
16 invoke void @_Z9may_throwv()
17 to label %try.cont unwind label %lpad
18
19 lpad: ; preds = %entry
20 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
21 catch i8* bitcast (i8** @_ZTIi to i8*)
22 %exn = extractvalue { i8*, i32 } %0, 0
23 %sel = extractvalue { i8*, i32 } %0, 1
24 %1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
25 %matches = icmp eq i32 %sel, %1
26 br i1 %matches, label %catch, label %eh.resume
27
28 catch: ; preds = %lpad
29 %2 = call i8* @llvm.eh.begincatch(i8* %exn)
30 call void @_Z10handle_intv()
31 br label %invoke.cont2
32
33 invoke.cont2: ; preds = %catch
34 call void @llvm.eh.endcatch()
35 br label %try.cont
36
37 try.cont: ; preds = %invoke.cont2, %entry
38 ret void
39
40 eh.resume: ; preds = %catch.dispatch
41 resume { i8*, i32 } %0
42 }
43
44 ; Function Attrs: uwtable
45 define void @test_ref_clean_multibranch() {
46 entry:
47 invoke void @_Z9may_throwv()
48 to label %invoke.cont unwind label %lpad
49
50 invoke.cont:
51 invoke void @_Z9may_throwv()
52 to label %invoke.cont unwind label %lpad1
53
54 lpad: ; preds = %entry
55 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
56 catch i8* bitcast (i8** @_ZTIi to i8*)
57 %exn = extractvalue { i8*, i32 } %0, 0
58 %sel = extractvalue { i8*, i32 } %0, 1
59 %1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
60 %matches = icmp eq i32 %sel, %1
61 br i1 %matches, label %catch, label %eh.resume
62
63 invoke void @_Z9may_throwv()
64 to label %try.cont unwind label %lpad
65
66 lpad1: ; preds = %entry
67 %l1.0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
68 cleanup
69 catch i8* bitcast (i8** @_ZTIi to i8*)
70 %exn1 = extractvalue { i8*, i32 } %l1.0, 0
71 %sel1 = extractvalue { i8*, i32 } %l1.0, 1
72 %l1.1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
73 %matchesl1 = icmp eq i32 %sel1, %l1.1
74 br i1 %matchesl1, label %catch, label %eh.resume
75
76 catch: ; preds = %lpad, %lpad1
77 %exn2 = phi i8* [%exn, %lpad], [%exn1, %lpad1]
78 %sel2 = phi i32 [%sel, %lpad], [%sel1, %lpad1]
79 %3 = call i8* @llvm.eh.begincatch(i8* %exn2)
80 call void @_Z10handle_intv()
81 %matches1 = icmp eq i32 %sel2, 0
82 br i1 %matches1, label %invoke.cont2, label %invoke.cont3
83
84 invoke.cont2: ; preds = %catch
85 call void @llvm.eh.endcatch()
86 br label %try.cont
87
88 invoke.cont3: ; preds = %catch
89 call void @llvm.eh.endcatch()
90 br label %eh.resume
91
92 try.cont: ; preds = %invoke.cont2, %entry
93 ret void
94
95 eh.resume: ; preds = %catch.dispatch
96 %lpad.val = insertvalue { i8*, i32 } undef, i32 0, 1
97 resume { i8*, i32 } %lpad.val
98 }
99
100 declare void @_Z9may_throwv()
101
102 declare i32 @__CxxFrameHandler3(...)
103
104 ; Function Attrs: nounwind readnone
105 declare i32 @llvm.eh.typeid.for(i8*)
106
107 declare void @_Z10handle_intv()
108
0 ; RUN: opt -lint -disable-output < %s 2>&1 | FileCheck %s
1
2 ; This test is meant to prove that the Verifier is able to identify a variety
3 ; of errors with the llvm.eh.begincatch and llvm.eh.endcatch intrinsics.
4 ; See cppeh-catch-intrinsics-clean for correct uses.
5
6 target triple = "x86_64-pc-windows-msvc"
7
8 declare i8* @llvm.eh.begincatch(i8*)
9
10 declare void @llvm.eh.endcatch()
11
12 @_ZTIi = external constant i8*
13
14 ; Function Attrs: uwtable
15 define void @test_missing_endcatch() {
16 ; CHECK: Some paths from llvm.eh.begincatch may not reach llvm.eh.endcatch
17 ; CHECK-NEXT: %2 = call i8* @llvm.eh.begincatch(i8* %exn)
18 entry:
19 invoke void @_Z9may_throwv()
20 to label %try.cont unwind label %lpad
21
22 lpad: ; preds = %entry
23 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
24 catch i8* bitcast (i8** @_ZTIi to i8*)
25 %exn = extractvalue { i8*, i32 } %0, 0
26 %sel = extractvalue { i8*, i32 } %0, 1
27 %1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
28 %matches = icmp eq i32 %sel, %1
29 br i1 %matches, label %catch, label %eh.resume
30
31 catch: ; preds = %lpad
32 %2 = call i8* @llvm.eh.begincatch(i8* %exn)
33 call void @_Z10handle_intv()
34 br label %invoke.cont2
35
36 invoke.cont2: ; preds = %catch
37 br label %try.cont
38
39 try.cont: ; preds = %invoke.cont2, %entry
40 ret void
41
42 eh.resume: ; preds = %catch.dispatch
43 resume { i8*, i32 } %0
44 }
45
46 ; Function Attrs: uwtable
47 define void @test_missing_begincatch() {
48 ; CHECK: llvm.eh.endcatch may be reachable without passing llvm.eh.begincatch
49 ; CHECK-NEXT: call void @llvm.eh.endcatch()
50 entry:
51 invoke void @_Z9may_throwv()
52 to label %try.cont unwind label %lpad
53
54 lpad: ; preds = %entry
55 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
56 catch i8* bitcast (i8** @_ZTIi to i8*)
57 %exn = extractvalue { i8*, i32 } %0, 0
58 %sel = extractvalue { i8*, i32 } %0, 1
59 %1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
60 %matches = icmp eq i32 %sel, %1
61 br i1 %matches, label %catch, label %eh.resume
62
63 catch: ; preds = %lpad
64 call void @_Z10handle_intv()
65 br label %invoke.cont2
66
67 invoke.cont2: ; preds = %catch
68 call void @llvm.eh.endcatch()
69 br label %try.cont
70
71 try.cont: ; preds = %invoke.cont2, %entry
72 ret void
73
74 eh.resume: ; preds = %catch.dispatch
75 resume { i8*, i32 } %0
76 }
77
78 ; Function Attrs: uwtable
79 define void @test_multiple_begin() {
80 ; CHECK: llvm.eh.begincatch may be called a second time before llvm.eh.endcatch
81 ; CHECK-NEXT: %2 = call i8* @llvm.eh.begincatch(i8* %exn)
82 ; CHECK-NEXT: %3 = call i8* @llvm.eh.begincatch(i8* %exn)
83 entry:
84 invoke void @_Z9may_throwv()
85 to label %try.cont unwind label %lpad
86
87 lpad: ; preds = %entry
88 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
89 catch i8* bitcast (i8** @_ZTIi to i8*)
90 %exn = extractvalue { i8*, i32 } %0, 0
91 %sel = extractvalue { i8*, i32 } %0, 1
92 %1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
93 %matches = icmp eq i32 %sel, %1
94 br i1 %matches, label %catch, label %eh.resume
95
96 catch: ; preds = %lpad
97 %2 = call i8* @llvm.eh.begincatch(i8* %exn)
98 call void @_Z10handle_intv()
99 br label %invoke.cont2
100
101 invoke.cont2: ; preds = %catch
102 %3 = call i8* @llvm.eh.begincatch(i8* %exn)
103 call void @llvm.eh.endcatch()
104 br label %try.cont
105
106 try.cont: ; preds = %invoke.cont2, %entry
107 ret void
108
109 eh.resume: ; preds = %catch.dispatch
110 resume { i8*, i32 } %0
111 }
112
113 ; Function Attrs: uwtable
114 define void @test_multiple_end() {
115 ; CHECK: llvm.eh.endcatch may be called a second time after llvm.eh.begincatch
116 ; CHECK-NEXT: call void @llvm.eh.endcatch()
117 ; CHECK-NEXT: call void @llvm.eh.endcatch()
118 entry:
119 invoke void @_Z9may_throwv()
120 to label %try.cont unwind label %lpad
121
122 lpad: ; preds = %entry
123 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
124 catch i8* bitcast (i8** @_ZTIi to i8*)
125 %exn = extractvalue { i8*, i32 } %0, 0
126 %sel = extractvalue { i8*, i32 } %0, 1
127 %1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
128 %matches = icmp eq i32 %sel, %1
129 br i1 %matches, label %catch, label %eh.resume
130
131 catch: ; preds = %lpad
132 %2 = call i8* @llvm.eh.begincatch(i8* %exn)
133 call void @_Z10handle_intv()
134 call void @llvm.eh.endcatch()
135 br label %invoke.cont2
136
137 invoke.cont2: ; preds = %catch
138 call void @llvm.eh.endcatch()
139 br label %try.cont
140
141 try.cont: ; preds = %invoke.cont2, %entry
142 ret void
143
144 eh.resume: ; preds = %catch.dispatch
145 resume { i8*, i32 } %0
146 }
147
148
149 ; Function Attrs: uwtable
150 define void @test_begincatch_without_lpad() {
151 ; CHECK: llvm.eh.begincatch may be reachable without passing a landingpad
152 ; CHECK-NEXT: %0 = call i8* @llvm.eh.begincatch(i8* %exn)
153 entry:
154 %exn = alloca i8
155 %0 = call i8* @llvm.eh.begincatch(i8* %exn)
156 call void @_Z10handle_intv()
157 br label %invoke.cont2
158
159 invoke.cont2: ; preds = %catch
160 call void @llvm.eh.endcatch()
161 br label %try.cont
162
163 try.cont: ; preds = %invoke.cont2, %entry
164 ret void
165 }
166
167 ; Function Attrs: uwtable
168 define void @test_branch_to_begincatch_with_no_lpad(i32 %fake.sel) {
169 ; CHECK: llvm.eh.begincatch may be reachable without passing a landingpad
170 ; CHECK-NEXT: %3 = call i8* @llvm.eh.begincatch(i8* %exn2)
171 entry:
172 %fake.exn = alloca i8
173 invoke void @_Z9may_throwv()
174 to label %catch unwind label %lpad
175
176 lpad: ; preds = %entry
177 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
178 catch i8* bitcast (i8** @_ZTIi to i8*)
179 %exn = extractvalue { i8*, i32 } %0, 0
180 %sel = extractvalue { i8*, i32 } %0, 1
181 %1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
182 %matches = icmp eq i32 %sel, %1
183 br i1 %matches, label %catch, label %eh.resume
184
185 invoke void @_Z9may_throwv()
186 to label %try.cont unwind label %lpad
187
188 catch: ; preds = %lpad, %entry
189 %exn2 = phi i8* [%exn, %lpad], [%fake.exn, %entry]
190 %sel2 = phi i32 [%sel, %lpad], [%fake.sel, %entry]
191 %3 = call i8* @llvm.eh.begincatch(i8* %exn2)
192 call void @_Z10handle_intv()
193 %matches1 = icmp eq i32 %sel2, 0
194 br i1 %matches1, label %invoke.cont2, label %invoke.cont3
195
196 invoke.cont2: ; preds = %catch
197 call void @llvm.eh.endcatch()
198 br label %try.cont
199
200 invoke.cont3: ; preds = %catch
201 call void @llvm.eh.endcatch()
202 br label %eh.resume
203
204 try.cont: ; preds = %invoke.cont2
205 ret void
206
207 eh.resume: ; preds = %catch.dispatch
208 %lpad.val = insertvalue { i8*, i32 } undef, i32 0, 1
209 resume { i8*, i32 } %lpad.val
210 }
211
212 ; Function Attrs: uwtable
213 define void @test_branch_missing_endcatch() {
214 ; CHECK: Some paths from llvm.eh.begincatch may not reach llvm.eh.endcatch
215 ; CHECK-NEXT: %3 = call i8* @llvm.eh.begincatch(i8* %exn2)
216 entry:
217 invoke void @_Z9may_throwv()
218 to label %invoke.cont unwind label %lpad
219
220 invoke.cont:
221 invoke void @_Z9may_throwv()
222 to label %invoke.cont unwind label %lpad1
223
224 lpad: ; preds = %entry
225 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
226 catch i8* bitcast (i8** @_ZTIi to i8*)
227 %exn = extractvalue { i8*, i32 } %0, 0
228 %sel = extractvalue { i8*, i32 } %0, 1
229 %1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
230 %matches = icmp eq i32 %sel, %1
231 br i1 %matches, label %catch, label %eh.resume
232
233 invoke void @_Z9may_throwv()
234 to label %try.cont unwind label %lpad
235
236 lpad1: ; preds = %entry
237 %l1.0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
238 cleanup
239 catch i8* bitcast (i8** @_ZTIi to i8*)
240 %exn1 = extractvalue { i8*, i32 } %l1.0, 0
241 %sel1 = extractvalue { i8*, i32 } %l1.0, 1
242 %l1.1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
243 %matchesl1 = icmp eq i32 %sel1, %l1.1
244 br i1 %matchesl1, label %catch, label %eh.resume
245
246 catch: ; preds = %lpad, %lpad1
247 %exn2 = phi i8* [%exn, %lpad], [%exn1, %lpad1]
248 %sel2 = phi i32 [%sel, %lpad], [%sel1, %lpad1]
249 %3 = call i8* @llvm.eh.begincatch(i8* %exn2)
250 call void @_Z10handle_intv()
251 %matches1 = icmp eq i32 %sel2, 0
252 br i1 %matches1, label %invoke.cont2, label %invoke.cont3
253
254 invoke.cont2: ; preds = %catch
255 call void @llvm.eh.endcatch()
256 br label %try.cont
257
258 invoke.cont3: ; preds = %catch
259 br label %eh.resume
260
261 try.cont: ; preds = %invoke.cont2, %entry
262 ret void
263
264 eh.resume: ; preds = %catch.dispatch
265 %lpad.val = insertvalue { i8*, i32 } undef, i32 0, 1
266 resume { i8*, i32 } %lpad.val
267 }
268
269 declare void @_Z9may_throwv()
270
271 declare i32 @__CxxFrameHandler3(...)
272
273 ; Function Attrs: nounwind readnone
274 declare i32 @llvm.eh.typeid.for(i8*)
275
276 declare void @_Z10handle_intv()
277