llvm.org GIT mirror llvm / de34956
[WinEH] Demote values and phis live across exception handlers up front In particular, this handles SSA values that are live *out* of a handler. The existing code only handles values that are live *in* to a handler. It also handles phi nodes in the block where normal control should resume after the end of a catch handler. When EH return points have phi nodes, we need to split the return edge. It is impossible for phi elimination to emit copies in the previous block if that block gets outlined. The indirectbr that we leave in the function is only notional, and is eliminated from the MachineFunction CFG early on. Reviewers: majnemer, andrew.w.kaylor Differential Revision: http://reviews.llvm.org/D9158 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235545 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 5 years ago
6 changed file(s) with 469 addition(s) and 132 deletion(s). Raw diff Collapse all Expand all
1717 #include "llvm/ADT/MapVector.h"
1818 #include "llvm/ADT/STLExtras.h"
1919 #include "llvm/ADT/SmallSet.h"
20 #include "llvm/ADT/SetVector.h"
2021 #include "llvm/ADT/TinyPtrVector.h"
2122 #include "llvm/Analysis/LibCallSemantics.h"
2223 #include "llvm/CodeGen/WinEHFuncInfo.h"
8586 bool prepareExceptionHandlers(Function &F,
8687 SmallVectorImpl &LPads);
8788 void promoteLandingPadValues(LandingPadInst *LPad);
89 void demoteValuesLiveAcrossHandlers(Function &F,
90 SmallVectorImpl &LPads);
8891 void completeNestedLandingPad(Function *ParentFn,
8992 LandingPadInst *OutlinedLPad,
9093 const LandingPadInst *OriginalLPad,
325328 cl::desc("Prepare functions with SEH personalities"));
326329
327330 bool WinEHPrepare::runOnFunction(Function &Fn) {
331 // No need to prepare outlined handlers.
332 if (Fn.hasFnAttribute("wineh-parent"))
333 return false;
334
328335 SmallVector LPads;
329336 SmallVector Resumes;
330337 for (BasicBlock &BB : Fn) {
368375 AU.addRequired();
369376 }
370377
378 static bool isSelectorDispatch(BasicBlock *BB, BasicBlock *&CatchHandler,
379 Constant *&Selector, BasicBlock *&NextBB);
380
381 // Finds blocks reachable from the starting set Worklist. Does not follow unwind
382 // edges or blocks listed in StopPoints.
383 static void findReachableBlocks(SmallPtrSetImpl &ReachableBBs,
384 SetVector &Worklist,
385 const SetVector *StopPoints) {
386 while (!Worklist.empty()) {
387 BasicBlock *BB = Worklist.pop_back_val();
388
389 // Don't cross blocks that we should stop at.
390 if (StopPoints && StopPoints->count(BB))
391 continue;
392
393 if (!ReachableBBs.insert(BB).second)
394 continue; // Already visited.
395
396 // Don't follow unwind edges of invokes.
397 if (auto *II = dyn_cast(BB->getTerminator())) {
398 Worklist.insert(II->getNormalDest());
399 continue;
400 }
401
402 // Otherwise, follow all successors.
403 Worklist.insert(succ_begin(BB), succ_end(BB));
404 }
405 }
406
407 /// Find all points where exceptional control rejoins normal control flow via
408 /// llvm.eh.endcatch. Add them to the normal bb reachability worklist.
409 static void findCXXEHReturnPoints(Function &F,
410 SetVector &EHReturnBlocks) {
411 for (auto BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI) {
412 BasicBlock *BB = BBI;
413 for (Instruction &I : *BB) {
414 if (match(&I, m_Intrinsic())) {
415 // Split the block after the call to llvm.eh.endcatch if there is
416 // anything other than an unconditional branch, or if the successor
417 // starts with a phi.
418 auto *Br = dyn_cast(I.getNextNode());
419 if (!Br || !Br->isUnconditional() ||
420 isa(Br->getSuccessor(0)->begin())) {
421 DEBUG(dbgs() << "splitting block " << BB->getName()
422 << " with llvm.eh.endcatch\n");
423 BBI = BB->splitBasicBlock(I.getNextNode(), "ehreturn");
424 }
425 // The next BB is normal control flow.
426 EHReturnBlocks.insert(BB->getTerminator()->getSuccessor(0));
427 break;
428 }
429 }
430 }
431 }
432
433 static bool isCatchAllLandingPad(const BasicBlock *BB) {
434 const LandingPadInst *LP = BB->getLandingPadInst();
435 if (!LP)
436 return false;
437 unsigned N = LP->getNumClauses();
438 return (N > 0 && LP->isCatch(N - 1) &&
439 isa(LP->getClause(N - 1)));
440 }
441
442 /// Find all points where exceptions control rejoins normal control flow via
443 /// selector dispatch.
444 static void findSEHEHReturnPoints(Function &F,
445 SetVector &EHReturnBlocks) {
446 for (auto BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI) {
447 BasicBlock *BB = BBI;
448 // If the landingpad is a catch-all, treat the whole lpad as if it is
449 // reachable from normal control flow.
450 // FIXME: This is imprecise. We need a better way of identifying where a
451 // catch-all starts and cleanups stop. As far as LLVM is concerned, there
452 // is no difference.
453 if (isCatchAllLandingPad(BB)) {
454 EHReturnBlocks.insert(BB);
455 continue;
456 }
457
458 BasicBlock *CatchHandler;
459 BasicBlock *NextBB;
460 Constant *Selector;
461 if (isSelectorDispatch(BB, CatchHandler, Selector, NextBB)) {
462 // Split the edge if there is a phi node. Returning from EH to a phi node
463 // is just as impossible as having a phi after an indirectbr.
464 if (isa(CatchHandler->begin())) {
465 DEBUG(dbgs() << "splitting EH return edge from " << BB->getName()
466 << " to " << CatchHandler->getName() << '\n');
467 BBI = CatchHandler = SplitCriticalEdge(
468 BB, std::find(succ_begin(BB), succ_end(BB), CatchHandler));
469 }
470 EHReturnBlocks.insert(CatchHandler);
471 }
472 }
473 }
474
475 /// Ensure that all values live into and out of exception handlers are stored
476 /// in memory.
477 /// FIXME: This falls down when values are defined in one handler and live into
478 /// another handler. For example, a cleanup defines a value used only by a
479 /// catch handler.
480 void WinEHPrepare::demoteValuesLiveAcrossHandlers(
481 Function &F, SmallVectorImpl &LPads) {
482 DEBUG(dbgs() << "Demoting values live across exception handlers in function "
483 << F.getName() << '\n');
484
485 // Build a set of all non-exceptional blocks and exceptional blocks.
486 // - Non-exceptional blocks are blocks reachable from the entry block while
487 // not following invoke unwind edges.
488 // - Exceptional blocks are blocks reachable from landingpads. Analysis does
489 // not follow llvm.eh.endcatch blocks, which mark a transition from
490 // exceptional to normal control.
491 SmallPtrSet NormalBlocks;
492 SmallPtrSet EHBlocks;
493 SetVector EHReturnBlocks;
494 SetVector Worklist;
495
496 if (Personality == EHPersonality::MSVC_CXX)
497 findCXXEHReturnPoints(F, EHReturnBlocks);
498 else
499 findSEHEHReturnPoints(F, EHReturnBlocks);
500
501 DEBUG({
502 dbgs() << "identified the following blocks as EH return points:\n";
503 for (BasicBlock *BB : EHReturnBlocks)
504 dbgs() << " " << BB->getName() << '\n';
505 });
506
507 // Join points should not have phis at this point, unless they are a
508 // landingpad, in which case we will demote their phis later.
509 #ifndef NDEBUG
510 for (BasicBlock *BB : EHReturnBlocks)
511 assert((BB->isLandingPad() || !isa(BB->begin())) &&
512 "non-lpad EH return block has phi");
513 #endif
514
515 // Normal blocks are the blocks reachable from the entry block and all EH
516 // return points.
517 Worklist = EHReturnBlocks;
518 Worklist.insert(&F.getEntryBlock());
519 findReachableBlocks(NormalBlocks, Worklist, nullptr);
520 DEBUG({
521 dbgs() << "marked the following blocks as normal:\n";
522 for (BasicBlock *BB : NormalBlocks)
523 dbgs() << " " << BB->getName() << '\n';
524 });
525
526 // Exceptional blocks are the blocks reachable from landingpads that don't
527 // cross EH return points.
528 Worklist.clear();
529 for (auto *LPI : LPads)
530 Worklist.insert(LPI->getParent());
531 findReachableBlocks(EHBlocks, Worklist, &EHReturnBlocks);
532 DEBUG({
533 dbgs() << "marked the following blocks as exceptional:\n";
534 for (BasicBlock *BB : EHBlocks)
535 dbgs() << " " << BB->getName() << '\n';
536 });
537
538 SetVector ArgsToDemote;
539 SetVector InstrsToDemote;
540 for (BasicBlock &BB : F) {
541 bool IsNormalBB = NormalBlocks.count(&BB);
542 bool IsEHBB = EHBlocks.count(&BB);
543 if (!IsNormalBB && !IsEHBB)
544 continue; // Blocks that are neither normal nor EH are unreachable.
545 for (Instruction &I : BB) {
546 for (Value *Op : I.operands()) {
547 // Don't demote static allocas, constants, and labels.
548 if (isa(Op) || isa(Op) || isa(Op))
549 continue;
550 auto *AI = dyn_cast(Op);
551 if (AI && AI->isStaticAlloca())
552 continue;
553
554 if (auto *Arg = dyn_cast(Op)) {
555 if (IsEHBB) {
556 DEBUG(dbgs() << "Demoting argument " << *Arg
557 << " used by EH instr: " << I << "\n");
558 ArgsToDemote.insert(Arg);
559 }
560 continue;
561 }
562
563 auto *OpI = cast(Op);
564 BasicBlock *OpBB = OpI->getParent();
565 // If a value is produced and consumed in the same BB, we don't need to
566 // demote it.
567 if (OpBB == &BB)
568 continue;
569 bool IsOpNormalBB = NormalBlocks.count(OpBB);
570 bool IsOpEHBB = EHBlocks.count(OpBB);
571 if (IsNormalBB != IsOpNormalBB || IsEHBB != IsOpEHBB) {
572 DEBUG({
573 dbgs() << "Demoting instruction live in-out from EH:\n";
574 dbgs() << "Instr: " << *OpI << '\n';
575 dbgs() << "User: " << I << '\n';
576 });
577 InstrsToDemote.insert(OpI);
578 }
579 }
580 }
581 }
582
583 // Demote values live into and out of handlers.
584 // FIXME: This demotion is inefficient. We should insert spills at the point
585 // of definition, insert one reload in each handler that uses the value, and
586 // insert reloads in the BB used to rejoin normal control flow.
587 Instruction *AllocaInsertPt = F.getEntryBlock().getFirstInsertionPt();
588 for (Instruction *I : InstrsToDemote)
589 DemoteRegToStack(*I, false, AllocaInsertPt);
590
591 // Demote arguments separately, and only for uses in EH blocks.
592 for (Argument *Arg : ArgsToDemote) {
593 auto *Slot = new AllocaInst(Arg->getType(), nullptr,
594 Arg->getName() + ".reg2mem", AllocaInsertPt);
595 SmallVector Users(Arg->user_begin(), Arg->user_end());
596 for (User *U : Users) {
597 auto *I = dyn_cast(U);
598 if (I && EHBlocks.count(I->getParent())) {
599 auto *Reload = new LoadInst(Slot, Arg->getName() + ".reload", false, I);
600 U->replaceUsesOfWith(Arg, Reload);
601 }
602 }
603 new StoreInst(Arg, Slot, AllocaInsertPt);
604 }
605
606 // Demote landingpad phis, as the landingpad will be removed from the machine
607 // CFG.
608 for (LandingPadInst *LPI : LPads) {
609 BasicBlock *BB = LPI->getParent();
610 while (auto *Phi = dyn_cast(BB->begin()))
611 DemotePHIToStack(Phi, AllocaInsertPt);
612 }
613
614 DEBUG(dbgs() << "Demoted " << InstrsToDemote.size() << " instructions and "
615 << ArgsToDemote.size() << " arguments for WinEHPrepare\n\n");
616 }
617
371618 bool WinEHPrepare::prepareExceptionHandlers(
372619 Function &F, SmallVectorImpl &LPads) {
620 // Don't run on functions that are already prepared.
621 for (LandingPadInst *LPad : LPads) {
622 BasicBlock *LPadBB = LPad->getParent();
623 for (Instruction &Inst : *LPadBB)
624 if (match(&Inst, m_Intrinsic()))
625 return false;
626 }
627
628 demoteValuesLiveAcrossHandlers(F, LPads);
629
373630 // These containers are used to re-map frame variables that are used in
374631 // outlined catch and cleanup handlers. They will be populated as the
375632 // handlers are outlined.
390647 bool LPadHasActionList = false;
391648 BasicBlock *LPadBB = LPad->getParent();
392649 for (Instruction &Inst : *LPadBB) {
393 if (auto *IntrinCall = dyn_cast(&Inst)) {
394 if (IntrinCall->getIntrinsicID() == Intrinsic::eh_actions) {
395 LPadHasActionList = true;
396 break;
397 }
650 if (match(&Inst, m_Intrinsic())) {
651 LPadHasActionList = true;
652 break;
398653 }
399654 // FIXME: This is here to help with the development of nested landing pad
400655 // outlining. It should be removed when that is finished.
492747 CallInst::Create(ActionIntrin, ActionArgs, "recover", NewLPadBB);
493748
494749 // Add an indirect branch listing possible successors of the catch handlers.
495 IndirectBrInst *Branch = IndirectBrInst::Create(Recover, 0, NewLPadBB);
750 SetVector ReturnTargets;
496751 for (ActionHandler *Action : Actions) {
497752 if (auto *CatchAction = dyn_cast(Action)) {
498 for (auto *Target : CatchAction->getReturnTargets()) {
499 Branch->addDestination(Target);
500 }
501 }
502 }
753 const auto &CatchTargets = CatchAction->getReturnTargets();
754 ReturnTargets.insert(CatchTargets.begin(), CatchTargets.end());
755 }
756 }
757 IndirectBrInst *Branch =
758 IndirectBrInst::Create(Recover, ReturnTargets.size(), NewLPadBB);
759 for (BasicBlock *Target : ReturnTargets)
760 Branch->addDestination(Target);
503761 } // End for each landingpad
504762
505763 // If nothing got outlined, there is no more processing to be done.
542800
543801 // Finally, replace all of the temporary allocas for frame variables used in
544802 // the outlined handlers with calls to llvm.framerecover.
545 BasicBlock::iterator II = Entry->getFirstInsertionPt();
546 Instruction *AllocaInsertPt = II;
547803 for (auto &VarInfoEntry : FrameVarInfo) {
548804 Value *ParentVal = VarInfoEntry.first;
549805 TinyPtrVector &Allocas = VarInfoEntry.second;
550
551 // If the mapped value isn't already an alloca, we need to spill it if it
552 // is a computed value or copy it if it is an argument.
553 AllocaInst *ParentAlloca = dyn_cast(ParentVal);
554 if (!ParentAlloca) {
555 if (auto *Arg = dyn_cast(ParentVal)) {
556 // Lower this argument to a copy and then demote that to the stack.
557 // We can't just use the argument location because the handler needs
558 // it to be in the frame allocation block.
559 // Use 'select i8 true, %arg, undef' to simulate a 'no-op' instruction.
560 Value *TrueValue = ConstantInt::getTrue(Context);
561 Value *UndefValue = UndefValue::get(Arg->getType());
562 Instruction *SI =
563 SelectInst::Create(TrueValue, Arg, UndefValue,
564 Arg->getName() + ".tmp", AllocaInsertPt);
565 Arg->replaceAllUsesWith(SI);
566 // Reset the select operand, because it was clobbered by the RAUW above.
567 SI->setOperand(1, Arg);
568 ParentAlloca = DemoteRegToStack(*SI, true, SI);
569 } else if (auto *PN = dyn_cast(ParentVal)) {
570 ParentAlloca = DemotePHIToStack(PN, AllocaInsertPt);
571 } else {
572 Instruction *ParentInst = cast(ParentVal);
573 // FIXME: This is a work-around to temporarily handle the case where an
574 // instruction that is only used in handlers is not sunk.
575 // Without uses, DemoteRegToStack would just eliminate the value.
576 // This will fail if ParentInst is an invoke.
577 if (ParentInst->getNumUses() == 0) {
578 BasicBlock::iterator InsertPt = ParentInst;
579 ++InsertPt;
580 ParentAlloca =
581 new AllocaInst(ParentInst->getType(), nullptr,
582 ParentInst->getName() + ".reg2mem",
583 AllocaInsertPt);
584 new StoreInst(ParentInst, ParentAlloca, InsertPt);
585 } else {
586 ParentAlloca = DemoteRegToStack(*ParentInst, true, AllocaInsertPt);
587 }
588 }
589 }
806 AllocaInst *ParentAlloca = cast(ParentVal);
590807
591808 // FIXME: We should try to sink unescaped allocas from the parent frame into
592809 // the child frame. If the alloca is escaped, we have to use the lifetime
13561573 }
13571574
13581575 Value *WinEHFrameVariableMaterializer::materializeValueFor(Value *V) {
1359 // If we're asked to materialize a value that is an instruction, we
1360 // temporarily create an alloca in the outlined function and add this
1361 // to the FrameVarInfo map. When all the outlining is complete, we'll
1362 // collect these into a structure, spilling non-alloca values in the
1363 // parent frame as necessary, and replace these temporary allocas with
1364 // GEPs referencing the frame allocation block.
1365
1366 // If the value is an alloca, the mapping is direct.
1576 // If we're asked to materialize a static alloca, we temporarily create an
1577 // alloca in the outlined function and add this to the FrameVarInfo map. When
1578 // all the outlining is complete, we'll replace these temporary allocas with
1579 // calls to llvm.framerecover.
13671580 if (auto *AV = dyn_cast(V)) {
1581 assert(AV->isStaticAlloca() &&
1582 "cannot materialize un-demoted dynamic alloca");
13681583 AllocaInst *NewAlloca = dyn_cast(AV->clone());
13691584 Builder.Insert(NewAlloca, AV->getName());
13701585 FrameVarInfo[AV].push_back(NewAlloca);
13711586 return NewAlloca;
13721587 }
13731588
1374 // For other types of instructions or arguments, we need an alloca based on
1375 // the value's type and a load of the alloca. The alloca will be replaced
1376 // by a GEP, but the load will stay. In the parent function, the value will
1377 // be spilled to a location in the frame allocation block.
13781589 if (isa(V) || isa(V)) {
1379 AllocaInst *NewAlloca =
1380 Builder.CreateAlloca(V->getType(), nullptr, "eh.temp.alloca");
1381 FrameVarInfo[V].push_back(NewAlloca);
1382 LoadInst *NewLoad = Builder.CreateLoad(NewAlloca, V->getName() + ".reload");
1383 return NewLoad;
1590 errs() << "Failed to demote instruction used in exception handler:\n";
1591 errs() << " " << *V << '\n';
1592 report_fatal_error("WinEHPrepare failed to demote instruction");
13841593 }
13851594
13861595 // Don't materialize other values.
0 ; RUN: opt -winehprepare -S < %s | FileCheck %s
1
2 ; Notionally based on this C++ source:
3 ; int liveout_catch(int p) {
4 ; int val = p + 1;
5 ; try {
6 ; might_throw();
7 ; } catch (int) {
8 ; val++;
9 ; }
10 ; return val;
11 ; }
12
13 declare void @llvm.eh.begincatch(i8*, i8*)
14 declare void @llvm.eh.endcatch()
15 declare void @might_throw()
16 declare i32 @__CxxFrameHandler3(...)
17 declare i32 @llvm.eh.typeid.for(i8*)
18
19 @typeinfo.int = external global i32
20
21 define i32 @liveout_catch(i32 %p) {
22 entry:
23 %val.entry = add i32 %p, 1
24 invoke void @might_throw()
25 to label %ret unwind label %lpad
26
27 lpad:
28 %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__CxxFrameHandler3
29 cleanup
30 catch i32* @typeinfo.int
31 %ehptr = extractvalue { i8*, i32 } %ehvals, 0
32 %sel = extractvalue { i8*, i32 } %ehvals, 1
33 %int_sel = call i32 @llvm.eh.typeid.for(i8* bitcast (i32* @typeinfo.int to i8*))
34 %match = icmp eq i32 %sel, %int_sel
35 br i1 %match, label %catchit, label %resume
36
37 catchit:
38 call void @llvm.eh.begincatch(i8* %ehptr, i8* null)
39 %val.lpad = add i32 %val.entry, 1
40 call void @llvm.eh.endcatch()
41 br label %ret
42
43 ret:
44 %rv = phi i32 [%val.entry, %entry], [%val.lpad, %catchit]
45 ret i32 %rv
46
47 resume:
48 resume {i8*, i32} %ehvals
49 }
50
51 ; CHECK-LABEL: define i32 @liveout_catch(i32 %p)
52 ; CHECK: %val.entry = add i32 %p, 1
53 ; CHECK-NEXT: store i32 %val.entry, i32* %val.entry.reg2mem
54 ; CHECK: invoke void @might_throw()
55 ;
56 ; CHECK: landingpad
57 ; CHECK: indirectbr i8* {{.*}}, [label %ehreturn]
58 ;
59 ; CHECK: ehreturn:
60 ; CHECK: load i32, i32* %val.lpad.reg2mem
61 ; CHECK: br label %ret
62 ;
63 ; CHECK: ret:
64 ; CHECK: %rv = phi i32 [ {{.*}}, %entry ], [ {{.*}}, %ehreturn ]
65 ; CHECK: ret i32
66
67 ; CHECK-LABEL: define internal i8* @liveout_catch.catch(i8*, i8*)
68 ; CHECK: %[[val:[^ ]*]] = load i32, i32*
69 ; CHECK-NEXT: %[[val_lpad:[^ ]*]] = add i32 %[[val]], 1
70 ; CHECK-NEXT: store i32 %[[val_lpad]], i32*
71 ; CHECK: ret i8* blockaddress(@liveout_catch, %ehreturn)
3838 ; CHECK: define i32 @"\01?test@@YAHUA@@@Z"(<{ %struct.A }>* inalloca)
3939 ; CHECK: entry:
4040 ; CHECK: [[TMP_REGMEM:\%.+]] = alloca <{ %struct.A }>*
41 ; CHECK: [[TMP:\%.+]] = select i1 true, <{ %struct.A }>* %0, <{ %struct.A }>* undef
42 ; CHECK: store <{ %struct.A }>* [[TMP]], <{ %struct.A }>** [[TMP_REGMEM]]
41 ; CHECK: store <{ %struct.A }>* %0, <{ %struct.A }>** [[TMP_REGMEM]]
4342 ; CHECK: [[RETVAL:\%.+]] = alloca i32, align 4
4443 ; CHECK: [[E_PTR:\%.+]] = alloca i32, align 4
4544 ; CHECK: [[CLEANUP_SLOT:\%.+]] = alloca i32
108107
109108 ; The cleanup block should be re-written like this.
110109 ; CHECK: cleanup:{{[ ]+}}; preds = %[[LPAD_LABEL]], %try.cont
111 ; CHECK-NOT: %a2 = getelementptr inbounds <{ %struct.A }>, <{ %struct.A }>* %0, i32 0, i32 0
112 ; CHECK: [[TMP_RELOAD:\%.+]] = load volatile <{ %struct.A }>*, <{ %struct.A }>** [[TMP_REGMEM]]
113 ; CHECK: [[A2:\%.+]] = getelementptr inbounds <{ %struct.A }>, <{ %struct.A }>* [[TMP_RELOAD]], i32 0, i32 0
114 ; CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* [[A2]])
110 ; CHECK: %a2 = getelementptr inbounds <{ %struct.A }>, <{ %struct.A }>* %0, i32 0, i32 0
111 ; CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %a2)
115112 ; CHECK: [[TMP1:\%.+]] = load i32, i32* [[RETVAL]]
116113 ; CHECK: ret i32 [[TMP1]]
117114
147144 ; CHECK: [[E_PTR:\%.+]] = bitcast i8* [[RECOVER_E]] to i32*
148145 ; CHECK: [[RECOVER_EH_TEMP:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 1)
149146 ; CHECK: [[EH_TEMP:\%.+]] = bitcast i8* [[RECOVER_EH_TEMP]] to <{ %struct.A }>**
150 ; CHECK: [[TMP_RELOAD:\%.+]] = load <{ %struct.A }>*, <{ %struct.A }>** [[EH_TEMP]]
151147 ; CHECK: [[RECOVER_RETVAL:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 2)
152148 ; CHECK: [[RETVAL1:\%.+]] = bitcast i8* [[RECOVER_RETVAL]] to i32*
153149 ; CHECK: [[RECOVER_CLEANUPSLOT:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 3)
154150 ; CHECK: [[CLEANUPSLOT1:\%.+]] = bitcast i8* [[RECOVER_CLEANUPSLOT]] to i32*
155151 ; CHECK: [[E_I8PTR:\%.+]] = bitcast i32* [[E_PTR]] to i8*
152 ; CHECK: [[TMP_RELOAD:\%.+]] = load <{ %struct.A }>*, <{ %struct.A }>** [[EH_TEMP]]
156153 ; CHECK: [[RECOVER_A:\%.+]] = getelementptr inbounds <{ %struct.A }>, <{ %struct.A }>* [[TMP_RELOAD]], i32 0, i32 0
157154 ; CHECK: [[A1:\%.+]] = getelementptr inbounds %struct.A, %struct.A* [[RECOVER_A]], i32 0, i32 0
158155 ; CHECK: [[TMP2:\%.+]] = load i32, i32* [[A1]], align 4
7878 ; CHECK-SAME: i32 1, i8* bitcast (%eh.HandlerMapEntry* @llvm.eh.handlermapentry._J to i8*), i32 1, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch1",
7979 ; CHECK-SAME: i32 1, i8* bitcast (%eh.HandlerMapEntry* @"llvm.eh.handlermapentry.reference.?AVSomeClass@@" to i8*), i32 2, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch2",
8080 ; CHECK-SAME: i32 1, i8* null, i32 -1, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch3")
81 ; CHECK-NEXT: indirectbr i8* [[RECOVER]], [label %catch14.split, label %catch10.split, label %catch6.split, label %catch.split]
81 ; CHECK-NEXT: indirectbr i8* [[RECOVER]], [label %ret]
8282
8383 lpad: ; preds = %entry
8484 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
9999 %matches = icmp eq i32 %sel, %3
100100 br i1 %matches, label %catch14, label %catch.fallthrough
101101
102 ret:
103 ret void
104
102105 ; CHECK-NOT: catch14:
103 ; CHECK: catch14.split:
106 ; CHECK: ret:
104107 ; CHECK-NEXT: ret void
105108 catch14: ; preds = %catch.dispatch
106109 %exn15 = load i8*, i8** %exn.slot
109112 %5 = load i32, i32* %i, align 4
110113 call void @"\01?handle_int@@YAXH@Z"(i32 %5)
111114 call void @llvm.eh.endcatch() #3
112 ret void
115 br label %ret
113116
114117 try.cont: ; preds = %invoke.cont
115 ret void
118 br label %ret
116119
117120 ; CHECK-NOT: catch.fallthrough:
118121 catch.fallthrough: ; preds = %catch.dispatch
121124 br i1 %matches1, label %catch10, label %catch.fallthrough2
122125
123126 ; CHECK-NOT: catch10:
124 ; CHECK: catch10.split:
125 ; CHECK-NEXT: ret void
126127 catch10: ; preds = %catch.fallthrough
127128 %exn11 = load i8*, i8** %exn.slot
128129 %7 = bitcast i64* %ll to i8*
130131 %8 = load i64, i64* %ll, align 8
131132 call void @"\01?handle_long_long@@YAX_J@Z"(i64 %8)
132133 call void @llvm.eh.endcatch() #3
133 ret void
134 br label %ret
134135
135136 ; CHECK-NOT: catch.fallthrough2:
136137 catch.fallthrough2: ; preds = %catch.fallthrough
139140 br i1 %matches3, label %catch6, label %catch
140141
141142 ; CHECK-NOT: catch6:
142 ; CHECK: catch6.split:
143 ; CHECK-NEXT: ret void
144143 catch6: ; preds = %catch.fallthrough2
145144 %exn7 = load i8*, i8** %exn.slot
146145 %10 = bitcast %class.SomeClass** %obj to i8*
148147 %11 = load %class.SomeClass*, %class.SomeClass** %obj, align 8
149148 call void @"\01?handle_obj@@YAXPEAVSomeClass@@@Z"(%class.SomeClass* %11)
150149 call void @llvm.eh.endcatch() #3
151 ret void
150 br label %ret
152151
153152 ; CHECK-NOT: catch:
154 ; CHECK: catch.split:
155 ; CHECK-NEXT: ret void
156153 catch: ; preds = %catch.fallthrough2
157154 %exn = load i8*, i8** %exn.slot
158155 call void @llvm.eh.begincatch(i8* %exn, i8* null) #3
159156 call void @"\01?handle_exception@@YAXXZ"() call void @llvm.eh.endcatch() #3
160 ret void
157 br label %ret
161158 ; CHECK: }
162159 }
163160
167164 ; CHECK: [[I_PTR:\%.+]] = bitcast i8* [[RECOVER_I]] to i32*
168165 ; CHECK: [[TMP1:\%.+]] = load i32, i32* [[I_PTR]], align 4
169166 ; CHECK: call void @"\01?handle_int@@YAXH@Z"(i32 [[TMP1]])
170 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ", %catch14.split)
167 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ", %ret)
171168 ; CHECK: }
172169
173170 ; CHECK-LABEL: define internal i8* @"\01?test@@YAXXZ.catch1"(i8*, i8*)
176173 ; CHECK: [[LL_PTR:\%.+]] = bitcast i8* [[RECOVER_LL]] to i64*
177174 ; CHECK: [[TMP2:\%.+]] = load i64, i64* [[LL_PTR]], align 8
178175 ; CHECK: call void @"\01?handle_long_long@@YAX_J@Z"(i64 [[TMP2]])
179 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ", %catch10.split)
176 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ", %ret)
180177 ; CHECK: }
181178
182179 ; CHECK-LABEL: define internal i8* @"\01?test@@YAXXZ.catch2"(i8*, i8*)
185182 ; CHECK: [[OBJ_PTR:\%.+]] = bitcast i8* [[RECOVER_OBJ]] to %class.SomeClass**
186183 ; CHECK: [[TMP3:\%.+]] = load %class.SomeClass*, %class.SomeClass** [[OBJ_PTR]], align 8
187184 ; CHECK: call void @"\01?handle_obj@@YAXPEAVSomeClass@@@Z"(%class.SomeClass* [[TMP3]])
188 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ", %catch6.split)
185 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ", %ret)
189186 ; CHECK: }
190187
191188 ; CHECK-LABEL: define internal i8* @"\01?test@@YAXXZ.catch3"(i8*, i8*)
192189 ; CHECK: entry:
193190 ; CHECK: call void @"\01?handle_exception@@YAXXZ"()
194 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ", %catch.split)
191 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ", %ret)
195192 ; CHECK: }
196193
197194
5454 ; CHECK: entry:
5555 ; CHECK: [[NUMEXCEPTIONS_REGMEM:\%.+]] = alloca i32
5656 ; CHECK: [[I_REGMEM:\%.+]] = alloca i32
57 ; CHECK: [[B_REGMEM:\%.+]] = alloca i32*
5758 ; CHECK: [[A_REGMEM:\%.+]] = alloca i32*
58 ; CHECK: [[B_REGMEM:\%.+]] = alloca i32*
5959 ; CHECK: [[E_PTR:\%.+]] = alloca i32, align 4
6060 ; CHECK: [[EXCEPTIONVAL:\%.+]] = alloca [10 x i32], align 16
6161 ; CHECK: [[DATA_PTR:\%.+]] = alloca i64, align 8
6767 ; CHECK: store i32* [[A_PTR]], i32** [[A_REGMEM]]
6868 ; CHECK: [[B_PTR:\%.+]] = getelementptr inbounds %struct.SomeData, %struct.SomeData* [[TMPCAST]], i64 0, i32 1
6969 ; CHECK: store i32* [[B_PTR]], i32** [[B_REGMEM]]
70 ; CHECK: store i32 0, i32* [[NUMEXCEPTIONS_REGMEM]]
71 ; CHECK: store i32 0, i32* [[I_REGMEM]]
72 ; CHECK: call void (...) @llvm.frameescape(i32* %e, i32* %NumExceptions.020.reg2mem, [10 x i32]* [[EXCEPTIONVAL]], i32* [[I_REGMEM]], i32** [[A_REGMEM]], i32** [[B_REGMEM]])
70 ; CHECK: call void (...) @llvm.frameescape(i32* %e, i32* %NumExceptions.020.reg2mem, [10 x i32]* [[EXCEPTIONVAL]], i32* %inc.reg2mem, i32* [[I_REGMEM]], i32** [[A_REGMEM]], i32** [[B_REGMEM]])
7371 ; CHECK: br label %for.body
7472
7573 ; Function Attrs: uwtable
8785 br label %for.body
8886
8987 ; CHECK: for.body:
90 ; CHECK-NOT: phi i32 [ 0, %entry ], [ {{\%NumExceptions.*}}, %try.cont ]
91 ; CHECK-NOT: phi i32 [ 0, %entry ], [ {{\%inc.*}}, %try.cont ]
92 ; CHECK: [[I_RELOAD:\%.+]] = load i32, i32* [[I_REGMEM]]
93 ; CHECK: [[NUMEXCEPTIONS_RELOAD:\%.+]] = load i32, i32* [[NUMEXCEPTIONS_REGMEM]]
88 ; CHECK: [[NUMEXCEPTIONS_PHI:\%.*]] = phi i32 [ 0, %entry ], [ {{\%NumExceptions.*}}, %try.cont ]
89 ; CHECK: [[I_PHI:\%.*]] = phi i32 [ 0, %entry ], [ {{\%inc.*}}, %try.cont ]
90 ; CHECK: store i32 [[I_PHI]], i32* [[I_REGMEM]]
91 ; CHECK: store i32 [[NUMEXCEPTIONS_PHI]], i32* [[NUMEXCEPTIONS_REGMEM]]
92 ; CHECK: invoke void @"\01?may_throw@@YAXXZ"()
9493 for.body: ; preds = %entry, %try.cont
9594 %NumExceptions.020 = phi i32 [ 0, %entry ], [ %NumExceptions.1, %try.cont ]
9695 %i.019 = phi i32 [ 0, %entry ], [ %inc5, %try.cont ]
9897 to label %invoke.cont unwind label %lpad
9998
10099 ; CHECK: invoke.cont: ; preds = %for.body
101 ; CHECK: [[A_RELOAD:\%.+]] = load volatile i32*, i32** [[A_REGMEM]]
100 ; CHECK: [[A_RELOAD:\%.+]] = load i32*, i32** [[A_REGMEM]]
102101 ; CHECK: [[TMP1:\%.+]] = load i32, i32* [[A_RELOAD]], align 8
102 ; CHECK: [[I_RELOAD:\%.+]] = load i32, i32* [[I_REGMEM]]
103103 ; CHECK: [[ADD:\%.+]] = add nsw i32 [[TMP1]], [[I_RELOAD]]
104 ; CHECK: [[A_RELOAD1:\%.+]] = load volatile i32*, i32** [[A_REGMEM]]
105 ; CHECK: store i32 [[ADD]], i32* [[A_RELOAD1]], align 8
104 ; CHECK: [[A_RELOAD1:\%.+]] = load i32*, i32** [[A_REGMEM]]
105 ; CHECK: [[NUMEXCEPTIONS_RELOAD:\%.+]] = load i32, i32* [[NUMEXCEPTIONS_REGMEM]]
106106 ; CHECK: br label %try.cont
107107 invoke.cont: ; preds = %for.body
108108 %1 = load i32, i32* %a, align 8, !tbaa !2
114114 ; CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
115115 ; CHECK-NEXT: catch i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*)
116116 ; CHECK-NEXT: [[RECOVER:\%.+]] = call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*), i32 0, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch")
117 ; CHECK-NEXT: indirectbr i8* [[RECOVER]], [label %try.cont]
117 ; CHECK-NEXT: indirectbr i8* [[RECOVER]], [label %[[SPLIT_RECOVER_BB:.*]]]
118118
119119 lpad: ; preds = %for.body
120120 %2 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
138138 %cmp1 = icmp eq i32 %tmp8, %i.019
139139 br i1 %cmp1, label %if.then, label %if.else
140140
141 ; CHECK-NOT: if.then:
142
143141 if.then: ; preds = %catch
144142 %tmp9 = load i32, i32* %b, align 4, !tbaa !8
145143 %add2 = add nsw i32 %tmp9, %i.019
155153 br label %if.end
156154
157155 ; CHECK-NOT: if.end:
156 ; CHECK: [[SPLIT_RECOVER_BB]]:
157 ; CHECK: [[INC_RELOAD:\%.*]] = load i32, i32*
158 ; CHECK: br label %try.cont
158159
159160 if.end: ; preds = %if.else, %if.then
160161 tail call void @llvm.eh.endcatch() #1
161162 br label %try.cont
162163
163 ; CHECK: try.cont:{{[ ]+}}; preds = %[[LPAD_LABEL]], %invoke.cont
164 ; CHECK-NOT: phi i32
165 ; CHECK: tail call void @"\01?does_not_throw@@YAXH@Z"(i32 [[NUMEXCEPTIONS_RELOAD]])
164 ; CHECK: try.cont:{{[ ]+}}; preds = %[[SPLIT_RECOVER_BB]], %invoke.cont
165 ; CHECK: [[NUMEXCEPTIONS_PHI:\%.*]] = phi i32 [ [[NUMEXCEPTIONS_RELOAD]], %invoke.cont ], [ [[INC_RELOAD]], %[[SPLIT_RECOVER_BB]] ]
166 ; CHECK: tail call void @"\01?does_not_throw@@YAXH@Z"(i32 [[NUMEXCEPTIONS_PHI]])
167 ; CHECK: [[I_RELOAD:\%.+]] = load i32, i32* [[I_REGMEM]]
166168 ; CHECK: [[INC:\%.+]] = add nuw nsw i32 [[I_RELOAD]], 1
167169 ; CHECK: [[CMP:\%.+]] = icmp slt i32 [[INC]], 10
168 ; CHECK: store i32 [[NUMEXCEPTIONS_RELOAD]], i32* [[NUMEXCEPTIONS_REGMEM]]
169 ; CHECK: store i32 [[INC]], i32* [[I_REGMEM]]
170170 ; CHECK: br i1 [[CMP]], label %for.body, label %for.end
171171
172172 try.cont: ; preds = %if.end, %invoke.cont
193193 ; CHECK: entry:
194194 ; CHECK: [[RECOVER_E:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
195195 ; CHECK: [[E_PTR:\%.+]] = bitcast i8* [[RECOVER_E]] to i32*
196 ; CHECK: [[RECOVER_EH_TEMP:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
197 ; CHECK: [[EH_TEMP:\%.+]] = bitcast i8* [[RECOVER_EH_TEMP]] to i32*
198 ; CHECK: [[NUMEXCEPTIONS_RELOAD:\%.+]] = load i32, i32* [[EH_TEMP]]
196 ; CHECK: [[RECOVER_NUMEXCEPTIONS:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
197 ; CHECK: [[NUMEXCEPTIONS_REGMEM:\%.+]] = bitcast i8* [[RECOVER_NUMEXCEPTIONS]] to i32*
199198 ; CHECK: [[RECOVER_EXCEPTIONVAL:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
200199 ; CHECK: [[EXCEPTIONVAL:\%.+]] = bitcast i8* [[RECOVER_EXCEPTIONVAL]] to [10 x i32]*
201 ; CHECK: [[RECOVER_EH_TEMP1:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 3)
202 ; CHECK: [[EH_TEMP1:\%.+]] = bitcast i8* [[RECOVER_EH_TEMP1]] to i32*
203 ; CHECK: [[I_RELOAD:\%.+]] = load i32, i32* [[EH_TEMP1]]
204 ; CHECK: [[RECOVER_EH_TEMP2:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 4)
205 ; CHECK: [[EH_TEMP2:\%.+]] = bitcast i8* [[RECOVER_EH_TEMP2]] to i32**
206 ; CHECK: [[A_RELOAD:\%.+]] = load i32*, i32** [[EH_TEMP2]]
207 ; CHECK: [[RECOVER_EH_TEMP3:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 5)
208 ; CHECK: [[EH_TEMP3:\%.+]] = bitcast i8* [[RECOVER_EH_TEMP3]] to i32**
209 ; CHECK: [[B_RELOAD:\%.+]] = load i32*, i32** [[EH_TEMP3]]
200 ; CHECK: [[RECOVER_INC:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 3)
201 ; CHECK: [[INC_REGMEM:\%.+]] = bitcast i8* [[RECOVER_INC]] to i32*
202 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 4)
203 ; CHECK: [[I_REGMEM:\%.+]] = bitcast i8* [[RECOVER_I]] to i32*
204 ; CHECK: [[RECOVER_A:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 5)
205 ; CHECK: [[A_REGMEM:\%.+]] = bitcast i8* [[RECOVER_A]] to i32**
206 ; CHECK: [[RECOVER_B:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 6)
207 ; CHECK: [[B_REGMEM:\%.+]] = bitcast i8* [[RECOVER_B]] to i32**
210208 ; CHECK: [[E_I8PTR:\%.+]] = bitcast i32* [[E_PTR]] to i8*
211209 ; CHECK: [[TMP:\%.+]] = load i32, i32* [[E_PTR]], align 4
210 ; CHECK: [[NUMEXCEPTIONS_RELOAD:\%.+]] = load i32, i32* [[NUMEXCEPTIONS_REGMEM]]
212211 ; CHECK: [[IDXPROM:\%.+]] = sext i32 [[NUMEXCEPTIONS_RELOAD]] to i64
213212 ; CHECK: [[ARRAYIDX:\%.+]] = getelementptr inbounds [10 x i32], [10 x i32]* [[EXCEPTIONVAL]], i64 0, i64 [[IDXPROM]]
214213 ; CHECK: store i32 [[TMP]], i32* [[ARRAYIDX]], align 4
214 ; CHECK: [[NUMEXCEPTIONS_RELOAD:\%.+]] = load i32, i32* [[NUMEXCEPTIONS_REGMEM]]
215215 ; CHECK: [[INC:\%.+]] = add nsw i32 [[NUMEXCEPTIONS_RELOAD]], 1
216216 ; CHECK: [[CMP:\%.+]] = icmp eq i32 [[TMP]], [[I_RELOAD]]
217217 ; CHECK: br i1 [[CMP]], label %if.then, label %if.else
218218 ;
219219 ; CHECK: if.then:{{[ ]+}}; preds = %entry
220 ; CHECK: [[B_RELOAD:\%.+]] = load i32*, i32** [[B_REGMEM]]
220221 ; CHECK: [[TMP1:\%.+]] = load i32, i32* [[B_RELOAD]], align 4
222 ; CHECK: [[I_RELOAD:\%.+]] = load i32, i32* [[I_REGMEM]]
221223 ; CHECK: [[ADD:\%.+]] = add nsw i32 [[TMP1]], [[I_RELOAD]]
224 ; CHECK: [[B_RELOAD:\%.+]] = load i32*, i32** [[B_REGMEM]]
222225 ; CHECK: store i32 [[ADD]], i32* [[B_RELOAD]], align 4
223226 ; CHECK: br label %if.end
224227 ;
225228 ; CHECK: if.else:{{[ ]+}}; preds = %entry
229 ; CHECK: [[A_RELOAD:\%.+]] = load i32*, i32** [[A_REGMEM]]
226230 ; CHECK: [[TMP2:\%.+]] = load i32, i32* [[A_RELOAD]], align 8
227231 ; CHECK: [[ADD2:\%.+]] = add nsw i32 [[TMP2]], [[TMP]]
232 ; CHECK: [[A_RELOAD:\%.+]] = load i32*, i32** [[A_REGMEM]]
228233 ; CHECK: store i32 [[ADD2]], i32* [[A_RELOAD]], align 8
229234 ; CHECK: br label %if.end
230235 ;
231236 ; CHECK: if.end:{{[ ]+}}; preds = %if.else, %if.then
232 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ", %try.cont)
237 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ", %[[SPLIT_RECOVER_BB]])
233238 ; CHECK: }
234239
235240 ; Function Attrs: nounwind
9393 ; CHECK-LABEL: define i32 @except_phi()
9494 ; CHECK: landingpad { i8*, i32 }
9595 ; CHECK-NEXT: catch i32 ()* @filt
96 ; CHECK-NEXT: call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (i32 ()* @filt to i8*), i32 -1, i8* blockaddress(@except_phi, %return))
97 ; CHECK-NEXT: indirectbr {{.*}} [label %return]
96 ; CHECK-NEXT: call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (i32 ()* @filt to i8*), i32 -1, i8* blockaddress(@except_phi, %lpad.return_crit_edge))
97 ; CHECK-NEXT: indirectbr {{.*}} [label %lpad.return_crit_edge]
98 ;
99 ; CHECK: lpad.return_crit_edge:
100 ; CHECK: br label %return
98101 ;
99102 ; CHECK: return:
100 ; CHECK-NEXT: %r = phi i32 [ 0, %entry ], [ 1, %lpad1 ]
103 ; CHECK-NEXT: %r = phi i32 [ 0, %entry ], [ 1, %lpad.return_crit_edge ]
104 ; CHECK-NEXT: ret i32 %r
105
106 define i32 @lpad_phi() {
107 entry:
108 invoke void @might_crash()
109 to label %cont unwind label %lpad
110
111 cont:
112 invoke void @might_crash()
113 to label %return unwind label %lpad
114
115 lpad:
116 %ncalls.1 = phi i32 [ 0, %entry ], [ 1, %cont ]
117 %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler
118 catch i32 ()* @filt
119 %sel = extractvalue { i8*, i32 } %ehvals, 1
120 %filt_sel = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @filt to i8*))
121 %matches = icmp eq i32 %sel, %filt_sel
122 br i1 %matches, label %return, label %eh.resume
123
124 return:
125 %r = phi i32 [2, %cont], [%ncalls.1, %lpad]
126 ret i32 %r
127
128 eh.resume:
129 resume { i8*, i32 } %ehvals
130 }
131
132 ; CHECK-LABEL: define i32 @lpad_phi()
133 ; CHECK: alloca i32
134 ; CHECK: store i32 0, i32*
135 ; CHECK: invoke void @might_crash()
136 ; CHECK: store i32 1, i32*
137 ; CHECK: invoke void @might_crash()
138 ; CHECK: landingpad { i8*, i32 }
139 ; CHECK-NEXT: cleanup
140 ; CHECK-NEXT: catch i32 ()* @filt
141 ; CHECK-NEXT: call i8* (...) @llvm.eh.actions(i32 0, void (i8*, i8*)* @lpad_phi.cleanup, i32 1, i8* bitcast (i32 ()* @filt to i8*), i32 -1, i8* blockaddress(@lpad_phi, %lpad.return_crit_edge))
142 ; CHECK-NEXT: indirectbr {{.*}} [label %lpad.return_crit_edge]
143 ;
144 ; CHECK: lpad.return_crit_edge:
145 ; CHECK: load i32, i32*
146 ; CHECK: br label %return
147 ;
148 ; CHECK: return:
149 ; CHECK-NEXT: %r = phi i32 [ 2, %cont ], [ %{{.*}}, %lpad.return_crit_edge ]
101150 ; CHECK-NEXT: ret i32 %r
102151
103152 define i32 @cleanup_and_except() {
129178 ; CHECK-NEXT: catch i32 ()* @filt
130179 ; CHECK-NEXT: call i8* (...) @llvm.eh.actions(
131180 ; CHECK: i32 0, void (i8*, i8*)* @cleanup_and_except.cleanup,
132 ; CHECK: i32 1, i8* bitcast (i32 ()* @filt to i8*), i32 -1, i8* blockaddress(@cleanup_and_except, %return))
133 ; CHECK-NEXT: indirectbr {{.*}} [label %return]
181 ; CHECK: i32 1, i8* bitcast (i32 ()* @filt to i8*), i32 -1, i8* blockaddress(@cleanup_and_except, %lpad.return_crit_edge))
182 ; CHECK-NEXT: indirectbr {{.*}} [label %lpad.return_crit_edge]
183 ;
184 ; CHECK: lpad.return_crit_edge:
185 ; CHECK: br label %return
134186 ;
135187 ; CHECK: return:
136 ; CHECK-NEXT: %r = phi i32 [ 0, %entry ], [ 1, %lpad1 ]
188 ; CHECK-NEXT: %r = phi i32 [ 0, %entry ], [ 1, %lpad.return_crit_edge ]
137189 ; CHECK-NEXT: ret i32 %r
190
191 ; FIXME: This cleanup is an artifact of bad demotion.
192 ; CHECK-LABEL: define internal void @lpad_phi.cleanup(i8*, i8*)
193 ; CHECK: load i32
194 ; CHECK: store i32 %{{.*}}, i32*