llvm.org GIT mirror llvm / 353c554
Revert r252249 (and r252255, r252258), "[WinEH] Clone funclets with multiple parents" It behaved flaky due to iterating pointer key values on std::set and std::map. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252279 91177308-0d34-0410-b5e6-96231b3b80d8 NAKAMURA Takumi 5 years ago
6 changed file(s) with 25 addition(s) and 2669 deletion(s). Raw diff Collapse all Expand all
53215321 if (Lex.getKind() == lltok::kw_caller) {
53225322 Lex.Lex();
53235323 } else {
5324 return Error(Lex.getLoc(),
5325 "'to' must be followed by 'caller' in catchendpad");
5324 return true;
53265325 }
53275326 } else {
53285327 if (ParseTypeAndBasicBlock(UnwindBB, PFS)) {
7373 SmallVectorImpl &EntryBlocks);
7474 void replaceTerminatePadWithCleanup(Function &F);
7575 void colorFunclets(Function &F, SmallVectorImpl &EntryBlocks);
76 void resolveFuncletAncestry(Function &F,
77 SmallVectorImpl &EntryBlocks);
78 void resolveFuncletAncestryForPath(
79 Function &F, SmallVectorImpl &FuncletPath,
80 std::map &IdentityMap);
81 void makeFuncletEdgeUnreachable(BasicBlock *Parent, BasicBlock *Child);
82 BasicBlock *cloneFuncletForParent(Function &F, BasicBlock *FuncletEntry,
83 BasicBlock *Parent);
84 void updateTerminatorsAfterFuncletClone(
85 Function &F, BasicBlock *OrigFunclet, BasicBlock *CloneFunclet,
86 BasicBlock *OrigBlock, BasicBlock *CloneBlock, BasicBlock *CloneParent,
87 ValueToValueMapTy &VMap,
88 std::map &Orig2Clone);
89
9076 void demotePHIsOnFunclets(Function &F);
9177 void demoteUsesBetweenFunclets(Function &F);
9278 void demoteArgumentUses(Function &F);
10187
10288 std::map> BlockColors;
10389 std::map> FuncletBlocks;
104 std::map> FuncletChildren;
105 std::map> FuncletParents;
106
107 // This is a flag that indicates an uncommon situation where we need to
108 // clone funclets has been detected.
109 bool FuncletCloningRequired = false;
110 // When a funclet with multiple parents contains a catchret, the block to
111 // which it returns will be cloned so that there is a copy in each parent
112 // but one of the copies will not be properly linked to the catchret and
113 // in most cases will have no predecessors. This double map allows us
114 // to find these cloned blocks when we clone the child funclet.
115 std::mapmap> EstrangedBlocks;
90 std::mapset> FuncletChildren;
11691 };
11792
11893 } // end anonymous namespace
583558 static void
584559 colorFunclets(Function &F, SmallVectorImpl &EntryBlocks,
585560 std::map> &BlockColors,
586 std::map> &FuncletBlocks) {
561 std::map> &FuncletBlocks,
562 std::map> &FuncletChildren) {
587563 SmallVector, 16> Worklist;
588564 BasicBlock *EntryBlock = &F.getEntryBlock();
589565
600576 // are as defined above. A post-pass fixes up the block color map to reflect
601577 // the same sense of "color" for funclet entries as for other blocks.
602578
603 DEBUG_WITH_TYPE("winehprepare-coloring", dbgs() << "\nColoring funclets for "
604 << F.getName() << "\n");
605
606579 Worklist.push_back({EntryBlock, EntryBlock});
607580
608581 while (!Worklist.empty()) {
609582 BasicBlock *Visiting;
610583 BasicBlock *Color;
611584 std::tie(Visiting, Color) = Worklist.pop_back_val();
612 DEBUG_WITH_TYPE("winehprepare-coloring",
613 dbgs() << "Visiting " << Visiting->getName() << ", "
614 << Color->getName() << "\n");
615585 Instruction *VisitingHead = Visiting->getFirstNonPHI();
616586 if (VisitingHead->isEHPad() && !isa(VisitingHead) &&
617587 !isa(VisitingHead)) {
629599 if (auto *Exit = dyn_cast(U)) {
630600 for (BasicBlock *Succ : successors(Exit->getParent()))
631601 if (!isa(*Succ->getFirstNonPHI()))
632 if (BlockColors[Succ].insert(Color).second) {
633 DEBUG_WITH_TYPE("winehprepare-coloring",
634 dbgs() << " Assigned color \'"
635 << Color->getName() << "\' to block \'"
636 << Succ->getName() << "\'.\n");
602 if (BlockColors[Succ].insert(Color).second)
637603 Worklist.push_back({Succ, Color});
638 }
639604 }
640605 }
641606 // Handle CatchPad specially since its successors need different colors.
644609 // visit the unwind successor with the color of the parent.
645610 BasicBlock *NormalSucc = CatchPad->getNormalDest();
646611 if (BlockColors[NormalSucc].insert(Visiting).second) {
647 DEBUG_WITH_TYPE("winehprepare-coloring",
648 dbgs() << " Assigned color \'" << Visiting->getName()
649 << "\' to block \'" << NormalSucc->getName()
650 << "\'.\n");
651612 Worklist.push_back({NormalSucc, Visiting});
652613 }
653614 BasicBlock *UnwindSucc = CatchPad->getUnwindDest();
654615 if (BlockColors[UnwindSucc].insert(Color).second) {
655 DEBUG_WITH_TYPE("winehprepare-coloring",
656 dbgs() << " Assigned color \'" << Color->getName()
657 << "\' to block \'" << UnwindSucc->getName()
658 << "\'.\n");
659616 Worklist.push_back({UnwindSucc, Color});
660617 }
661618 continue;
687644 continue;
688645 }
689646 if (BlockColors[Succ].insert(Color).second) {
690 DEBUG_WITH_TYPE("winehprepare-coloring",
691 dbgs() << " Assigned color \'" << Color->getName()
692 << "\' to block \'" << Succ->getName()
693 << "\'.\n");
694647 Worklist.push_back({Succ, Color});
695648 }
696649 }
697650 }
698 }
699
700 static BasicBlock *getEndPadForCatch(CatchPadInst *Catch) {
701 // The catch may have sibling catches. Follow the unwind chain until we get
702 // to the catchendpad.
703 BasicBlock *NextUnwindDest = Catch->getUnwindDest();
704 auto *UnwindTerminator = NextUnwindDest->getTerminator();
705 while (auto *NextCatch = dyn_cast(UnwindTerminator)) {
706 NextUnwindDest = NextCatch->getUnwindDest();
707 UnwindTerminator = NextUnwindDest->getTerminator();
708 }
709 // The last catch in the chain must unwind to a catchendpad.
710 assert(isa(UnwindTerminator));
711 return NextUnwindDest;
712 }
713
714 static void updateClonedEHPadUnwindToParent(
715 BasicBlock *UnwindDest, BasicBlock *OrigBlock, BasicBlock *CloneBlock,
716 std::vector &OrigParents, BasicBlock *CloneParent) {
717 auto updateUnwindTerminator = [](BasicBlock *BB) {
718 auto *Terminator = BB->getTerminator();
719 if (isa(Terminator) ||
720 isa(Terminator)) {
721 removeUnwindEdge(BB);
722 } else {
723 // If the block we're updating has a cleanupendpad or cleanupret
724 // terminator, we just want to replace that terminator with an
725 // unreachable instruction.
726 assert(isa(Terminator) ||
727 isa(Terminator));
728 // Loop over all of the successors, removing the block's entry from any
729 // PHI nodes.
730 for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
731 (*SI)->removePredecessor(BB);
732 // Remove the terminator and replace it with an unreachable instruction.
733 BB->getTerminator()->eraseFromParent();
734 new UnreachableInst(BB->getContext(), BB);
735 }
736 };
737
738 assert(UnwindDest->isEHPad());
739 // There are many places to which this EH terminator can unwind and each has
740 // slightly different rules for whether or not it fits with the given
741 // location.
742 auto *EHPadInst = UnwindDest->getFirstNonPHI();
743 if (isa(EHPadInst)) {
744 auto *CloneParentCatch =
745 dyn_cast(CloneParent->getFirstNonPHI());
746 if (!CloneParentCatch ||
747 getEndPadForCatch(CloneParentCatch) != UnwindDest) {
748 DEBUG_WITH_TYPE(
749 "winehprepare-coloring",
750 dbgs() << " removing unwind destination of clone block \'"
751 << CloneBlock->getName() << "\'.\n");
752 updateUnwindTerminator(CloneBlock);
753 }
754 // It's possible that the catch end pad is a legal match for both the clone
755 // and the original, so they must be checked separately. If the original
756 // funclet will still have multiple parents after the current clone parent
757 // is removed, we'll leave its unwind terminator until later.
758 assert(OrigParents.size() >= 2);
759 if (OrigParents.size() != 2)
760 return;
761
762 // If the original funclet will have a single parent after the clone parent
763 // is removed, check that parent's unwind destination.
764 assert(OrigParents.front() == CloneParent ||
765 OrigParents.back() == CloneParent);
766 BasicBlock *OrigParent;
767 if (OrigParents.front() == CloneParent)
768 OrigParent = OrigParents.back();
769 else
770 OrigParent = OrigParents.front();
771
772 auto *OrigParentCatch =
773 dyn_cast(OrigParent->getFirstNonPHI());
774 if (!OrigParentCatch || getEndPadForCatch(OrigParentCatch) != UnwindDest) {
775 DEBUG_WITH_TYPE(
776 "winehprepare-coloring",
777 dbgs() << " removing unwind destination of original block \'"
778 << OrigBlock << "\'.\n");
779 updateUnwindTerminator(OrigBlock);
780 }
781 } else if (auto *CleanupEnd = dyn_cast(EHPadInst)) {
782 // If the EH terminator unwinds to a cleanupendpad, that cleanupendpad
783 // must be ending a cleanuppad of either our clone parent or one
784 // one of the parents of the original funclet.
785 auto *CloneParentCP =
786 dyn_cast(CloneParent->getFirstNonPHI());
787 auto *EndedCP = CleanupEnd->getCleanupPad();
788 if (EndedCP == CloneParentCP) {
789 // If it is ending the cleanuppad of our cloned parent, then we
790 // want to remove the unwind destination of the EH terminator that
791 // we associated with the original funclet.
792 assert(isa(OrigBlock->getFirstNonPHI()));
793 DEBUG_WITH_TYPE(
794 "winehprepare-coloring",
795 dbgs() << " removing unwind destination of original block \'"
796 << OrigBlock->getName() << "\'.\n");
797 updateUnwindTerminator(OrigBlock);
798 } else {
799 // If it isn't ending the cleanuppad of our clone parent, then we
800 // want to remove the unwind destination of the EH terminator that
801 // associated with our cloned funclet.
802 assert(isa(CloneBlock->getFirstNonPHI()));
803 DEBUG_WITH_TYPE(
804 "winehprepare-coloring",
805 dbgs() << " removing unwind destination of clone block \'"
806 << CloneBlock->getName() << "\'.\n");
807 updateUnwindTerminator(CloneBlock);
808 }
809 } else {
810 // If the EH terminator unwinds to a catchpad, cleanuppad or
811 // terminatepad that EH pad must be a sibling of the funclet we're
812 // cloning. We'll clone it later and update one of the catchendpad
813 // instrunctions that unwinds to it at that time.
814 assert(isa(EHPadInst) || isa(EHPadInst) ||
815 isa(EHPadInst));
816 }
817 }
818
819 // If the terminator is a catchpad, we must also clone the catchendpad to which
820 // it unwinds and add this to the clone parent's block list. The catchendpad
821 // unwinds to either its caller, a sibling EH pad, a cleanup end pad in its
822 // parent funclet or a catch end pad in its grandparent funclet (which must be
823 // coupled with the parent funclet). If it has no unwind destination
824 // (i.e. unwind to caller), there is nothing to be done. If the unwind
825 // destination is a sibling EH pad, we will update the terminators later (in
826 // resolveFuncletAncestryForPath). If it unwinds to a cleanup end pad or a
827 // catch end pad and this end pad corresponds to the clone parent, we will
828 // remove the unwind destination in the original catchendpad. If it unwinds to
829 // a cleanup end pad or a catch end pad that does not correspond to the clone
830 // parent, we will remove the unwind destination in the cloned catchendpad.
831 static void updateCatchTerminators(
832 Function &F, CatchPadInst *OrigCatch, CatchPadInst *CloneCatch,
833 std::vector &OrigParents, BasicBlock *CloneParent,
834 ValueToValueMapTy &VMap,
835 std::map> &BlockColors,
836 std::map> &FuncletBlocks) {
837 // If we're cloning a catch pad that unwinds to a catchendpad, we also
838 // need to clone the catchendpad. The coloring algorithm associates
839 // the catchendpad block with the funclet's parent, so we have some work
840 // to do here to figure out whether the original belongs to the clone
841 // parent or one of the original funclets other parents (it might have
842 // more than one at this point). In either case, we might also need to
843 // remove the unwind edge if the catchendpad doesn't unwind to a block
844 // in the right grandparent funclet.
845 Instruction *I = CloneCatch->getUnwindDest()->getFirstNonPHI();
846 if (auto *CEP = dyn_cast(I)) {
847 assert(BlockColors[CEP->getParent()].size() == 1);
848 BasicBlock *CEPFunclet = *(BlockColors[CEP->getParent()].begin());
849 BasicBlock *CEPCloneParent = nullptr;
850 CatchPadInst *PredCatch = nullptr;
851 if (CEPFunclet == CloneParent) {
852 // The catchendpad is in the clone parent, so we need to clone it
853 // and associate the clone with the original funclet's parent. If
854 // the original funclet had multiple parents, we'll add it to the
855 // first parent that isn't the clone parent. The logic in
856 // updateClonedEHPadUnwindToParent() will only remove the unwind edge
857 // if there is only one parent other than the clone parent, so we don't
858 // need to verify the ancestry. The catchendpad will eventually be
859 // cloned into the correct parent and all invalid unwind edges will be
860 // removed.
861 for (auto *Parent : OrigParents) {
862 if (Parent != CloneParent) {
863 CEPCloneParent = Parent;
864 break;
865 }
866 }
867 PredCatch = OrigCatch;
868 } else {
869 CEPCloneParent = CloneParent;
870 PredCatch = CloneCatch;
871 }
872 assert(CEPCloneParent && PredCatch);
873 DEBUG_WITH_TYPE("winehprepare-coloring",
874 dbgs() << " Cloning catchendpad \'"
875 << CEP->getParent()->getName() << "\' for funclet \'"
876 << CEPCloneParent->getName() << "\'.\n");
877 BasicBlock *ClonedCEP = CloneBasicBlock(
878 CEP->getParent(), VMap, Twine(".from.", CEPCloneParent->getName()));
879 // Insert the clone immediately after the original to ensure determinism
880 // and to keep the same relative ordering of any funclet's blocks.
881 ClonedCEP->insertInto(&F, CEP->getParent()->getNextNode());
882 PredCatch->setUnwindDest(ClonedCEP);
883 FuncletBlocks[CEPCloneParent].insert(ClonedCEP);
884 BlockColors[ClonedCEP].insert(CEPCloneParent);
885 DEBUG_WITH_TYPE("winehprepare-coloring",
886 dbgs() << " Assigning color \'"
887 << CEPCloneParent->getName() << "\' to block \'"
888 << ClonedCEP->getName() << "\'.\n");
889 auto *ClonedCEPInst = cast(ClonedCEP->getTerminator());
890 if (auto *Dest = ClonedCEPInst->getUnwindDest())
891 updateClonedEHPadUnwindToParent(Dest, OrigCatch->getUnwindDest(),
892 CloneCatch->getUnwindDest(), OrigParents,
893 CloneParent);
894 }
895 }
896
897 // While we are cloning a funclet because it has multiple parents, we will call
898 // this routine to update the terminators for the original and cloned copies
899 // of each basic block. All blocks in the funclet have been clone by this time.
900 // OrigBlock and CloneBlock will be identical except for their block label.
901 //
902 // If the terminator is a catchpad, we must also clone the catchendpad to which
903 // it unwinds and in most cases update either the original catchendpad or the
904 // clone. See the updateCatchTerminators() helper routine for details.
905 //
906 // If the terminator is a catchret its successor is a block in its parent
907 // funclet. If the instruction returns to a block in the parent for which the
908 // cloned funclet was created, the terminator in the original block must be
909 // replaced by an unreachable instruction. Otherwise the terminator in the
910 // clone block must be replaced by an unreachable instruction.
911 //
912 // If the terminator is a cleanupret or cleanupendpad it either unwinds to
913 // caller or unwinds to a sibling EH pad, a cleanup end pad in its parent
914 // funclet or a catch end pad in its grandparent funclet (which must be
915 // coupled with the parent funclet). If it unwinds to caller there is
916 // nothing to be done. If the unwind destination is a sibling EH pad, we will
917 // update the terminators later (in resolveFuncletAncestryForPath). If it
918 // unwinds to a cleanup end pad or a catch end pad and this end pad corresponds
919 // to the clone parent, we will replace the terminator in the original block
920 // with an unreachable instruction. If it unwinds to a cleanup end pad or a
921 // catch end pad that does not correspond to the clone parent, we will replace
922 // the terminator in the clone block with an unreachable instruction.
923 //
924 // If the terminator is an invoke instruction, it unwinds either to a child
925 // EH pad, a cleanup end pad in the current funclet, or a catch end pad in a
926 // parent funclet (which ends either the current catch pad or a sibling
927 // catch pad). If it unwinds to a child EH pad, the child will have multiple
928 // parents after this funclet is cloned and this case will be handled later in
929 // the resolveFuncletAncestryForPath processing. If it unwinds to a
930 // cleanup end pad in the current funclet, the instruction remapping during
931 // the cloning process should have already mapped the unwind destination to
932 // the cloned copy of the cleanup end pad. If it unwinds to a catch end pad
933 // there are two possibilities: either the catch end pad is the unwind
934 // destination for the catch pad we are currently cloning or it is the unwind
935 // destination for a sibling catch pad. If it it the unwind destination of the
936 // catch pad we are cloning, we need to update the cloned invoke instruction
937 // to unwind to the cloned catch end pad. Otherwise, we will handle this
938 // later (in resolveFuncletAncestryForPath).
939 void WinEHPrepare::updateTerminatorsAfterFuncletClone(
940 Function &F, BasicBlock *OrigFunclet, BasicBlock *CloneFunclet,
941 BasicBlock *OrigBlock, BasicBlock *CloneBlock, BasicBlock *CloneParent,
942 ValueToValueMapTy &VMap, std::map &Orig2Clone) {
943 // If the cloned block doesn't have an exceptional terminator, there is
944 // nothing to be done here.
945 TerminatorInst *CloneTerminator = CloneBlock->getTerminator();
946 if (!CloneTerminator->isExceptional())
947 return;
948
949 if (auto *CloneCatch = dyn_cast(CloneTerminator)) {
950 // A cloned catch pad has a lot of wrinkles, so we'll call a helper function
951 // to update this case.
952 auto *OrigCatch = cast(OrigBlock->getTerminator());
953 updateCatchTerminators(F, OrigCatch, CloneCatch,
954 FuncletParents[OrigFunclet], CloneParent, VMap,
955 BlockColors, FuncletBlocks);
956 } else if (auto *CRI = dyn_cast(CloneTerminator)) {
957 if (FuncletBlocks[CloneParent].count(CRI->getSuccessor())) {
958 BasicBlock *OrigParent;
959 // The original funclet may have more than two parents, but that's OK.
960 // We just need to remap the original catchret to any of the parents.
961 // All of the parents should have an entry in the EstrangedBlocks map
962 // if any of them do.
963 if (FuncletParents[OrigFunclet].front() == CloneParent)
964 OrigParent = FuncletParents[OrigFunclet].back();
965 else
966 OrigParent = FuncletParents[OrigFunclet].front();
967 for (succ_iterator SI = succ_begin(OrigBlock), SE = succ_end(OrigBlock);
968 SI != SE; ++SI)
969 (*SI)->removePredecessor(OrigBlock);
970 BasicBlock *LostBlock = EstrangedBlocks[OrigParent][CRI->getSuccessor()];
971 auto *OrigCatchRet = cast(OrigBlock->getTerminator());
972 if (LostBlock) {
973 OrigCatchRet->setSuccessor(LostBlock);
974 } else {
975 OrigCatchRet->eraseFromParent();
976 new UnreachableInst(OrigBlock->getContext(), OrigBlock);
977 }
978 } else {
979 for (succ_iterator SI = succ_begin(CloneBlock), SE = succ_end(CloneBlock);
980 SI != SE; ++SI)
981 (*SI)->removePredecessor(CloneBlock);
982 BasicBlock *LostBlock = EstrangedBlocks[CloneParent][CRI->getSuccessor()];
983 if (LostBlock) {
984 CRI->setSuccessor(LostBlock);
985 } else {
986 CRI->eraseFromParent();
987 new UnreachableInst(CloneBlock->getContext(), CloneBlock);
988 }
989 }
990 } else if (isa(CloneTerminator) ||
991 isa(CloneTerminator)) {
992 BasicBlock *UnwindDest = nullptr;
993
994 // A cleanup pad can unwind through either a cleanupret or a cleanupendpad
995 // but both are handled the same way.
996 if (auto *CRI = dyn_cast(CloneTerminator))
997 UnwindDest = CRI->getUnwindDest();
998 else if (auto *CEI = dyn_cast(CloneTerminator))
999 UnwindDest = CEI->getUnwindDest();
1000
1001 // If the instruction has no local unwind destination, there is nothing
1002 // to be done.
1003 if (!UnwindDest)
1004 return;
1005
1006 // The unwind destination may be a sibling EH pad, a catchendpad in
1007 // a grandparent funclet (ending a catchpad in the parent) or a cleanup
1008 // cleanupendpad in the parent. Call a helper routine to diagnose this
1009 // and remove either the clone or original terminator as needed.
1010 updateClonedEHPadUnwindToParent(UnwindDest, OrigBlock, CloneBlock,
1011 FuncletParents[OrigFunclet], CloneParent);
1012 } else if (auto *II = dyn_cast(CloneTerminator)) {
1013 BasicBlock *UnwindDest = II->getUnwindDest();
1014 assert(UnwindDest && "Invoke unwinds to a null destination.");
1015 assert(UnwindDest->isEHPad() && "Invoke does not unwind to an EH pad.");
1016 auto *EHPadInst = UnwindDest->getFirstNonPHI();
1017 if (isa(EHPadInst)) {
1018 // An invoke that unwinds to a cleanup end pad must be in a cleanup pad.
1019 assert(isa(CloneFunclet->getFirstNonPHI()) &&
1020 "Unwinding to cleanup end pad from a non cleanup pad funclet.");
1021 // The funclet cloning should have remapped the destination to the cloned
1022 // cleanup end pad.
1023 assert(FuncletBlocks[CloneFunclet].count(UnwindDest) &&
1024 "Unwind destination for invoke was not updated during cloning.");
1025 } else if (isa(EHPadInst)) {
1026 auto *OrigCatch = cast(OrigFunclet->getFirstNonPHI());
1027 auto *CloneCatch = cast(CloneFunclet->getFirstNonPHI());
1028 if (OrigCatch->getUnwindDest() == UnwindDest) {
1029 // If the invoke unwinds to a catch end pad that is the unwind
1030 // destination for the original catch pad, the cloned invoke should
1031 // unwind to the cloned catch end pad.
1032 II->setUnwindDest(CloneCatch->getUnwindDest());
1033 } else if (CloneCatch->getUnwindDest() == UnwindDest) {
1034 // If the invoke unwinds to a catch end pad that is the unwind
1035 // destination for the clone catch pad, the original invoke should
1036 // unwind to the unwind destination of the original catch pad.
1037 // This happens when the catch end pad is matched to the clone
1038 // parent when the catchpad instruction is cloned and the original
1039 // invoke instruction unwinds to the original catch end pad (which
1040 // is now the unwind destination of the cloned catch pad).
1041 auto *OrigInvoke = cast(OrigBlock->getTerminator());
1042 OrigInvoke->setUnwindDest(OrigCatch->getUnwindDest());
1043 } else {
1044 // If the invoke unwinds to a catch end pad that is not the unwind
1045 // destination for the original catch pad, it must be the unwind
1046 // destination for a sibling catch end pad. We'll handle that case
1047 // later.
1048 assert((getEndPadForCatch(OrigCatch) == UnwindDest ||
1049 getEndPadForCatch(CloneCatch) == UnwindDest) &&
1050 "Invoke within catch pad unwinds to an invalid catch end pad.");
1051 }
1052 }
1053 }
1054 }
1055
1056 // Clones all blocks used by the specified funclet to avoid the funclet having
1057 // multiple parent funclets. All terminators in the parent that unwind to the
1058 // original funclet are remapped to unwind to the clone. Any terminator in the
1059 // original funclet which returned to this parent is converted to an unreachable
1060 // instruction. Likewise, any terminator in the cloned funclet which returns to
1061 // a parent funclet other than the specified parent is converted to an
1062 // unreachable instruction.
1063 BasicBlock *WinEHPrepare::cloneFuncletForParent(Function &F,
1064 BasicBlock *FuncletEntry,
1065 BasicBlock *Parent) {
1066 std::set &BlocksInFunclet = FuncletBlocks[FuncletEntry];
1067
1068 DEBUG_WITH_TYPE("winehprepare-coloring",
1069 dbgs() << "Cloning funclet \'" << FuncletEntry->getName()
1070 << "\' for parent \'" << Parent->getName() << "\'.\n");
1071
1072 std::map Orig2Clone;
1073 ValueToValueMapTy VMap;
1074 for (BasicBlock *BB : BlocksInFunclet) {
1075 // Create a new basic block and copy instructions into it.
1076 BasicBlock *CBB =
1077 CloneBasicBlock(BB, VMap, Twine(".from.", Parent->getName()));
1078
1079 // Insert the clone immediately after the original to ensure determinism
1080 // and to keep the same relative ordering of any funclet's blocks.
1081 CBB->insertInto(&F, BB->getNextNode());
1082
1083 // Add basic block mapping.
1084 VMap[BB] = CBB;
1085
1086 // Record delta operations that we need to perform to our color mappings.
1087 Orig2Clone[BB] = CBB;
1088 } // end for (BasicBlock *BB : BlocksInFunclet)
1089
1090 BasicBlock *ClonedFunclet = Orig2Clone[FuncletEntry];
1091 assert(ClonedFunclet);
1092
1093 // Set the coloring for the blocks we just cloned.
1094 std::set &ClonedBlocks = FuncletBlocks[ClonedFunclet];
1095 for (auto &BBMapping : Orig2Clone) {
1096 BasicBlock *NewBlock = BBMapping.second;
1097 ClonedBlocks.insert(NewBlock);
1098 BlockColors[NewBlock].insert(ClonedFunclet);
1099
1100 DEBUG_WITH_TYPE("winehprepare-coloring",
1101 dbgs() << " Assigning color \'" << ClonedFunclet->getName()
1102 << "\' to block \'" << NewBlock->getName()
1103 << "\'.\n");
1104
1105 // Use the VMap to remap the instructions in this cloned block.
1106 for (Instruction &I : *NewBlock)
1107 RemapInstruction(&I, VMap, RF_IgnoreMissingEntries);
1108 }
1109
1110 // All the cloned blocks have to be colored in the loop above before we can
1111 // update the terminators because doing so can require checking the color of
1112 // other blocks in the cloned funclet.
1113 for (auto &BBMapping : Orig2Clone) {
1114 BasicBlock *OldBlock = BBMapping.first;
1115 BasicBlock *NewBlock = BBMapping.second;
1116
1117 // Update the terminator, if necessary, in both the original block and the
1118 // cloned so that the original funclet never returns to a block in the
1119 // clone parent and the clone funclet never returns to a block in any other
1120 // of the original funclet's parents.
1121 updateTerminatorsAfterFuncletClone(F, FuncletEntry, ClonedFunclet, OldBlock,
1122 NewBlock, Parent, VMap, Orig2Clone);
1123
1124 // Check to see if the cloned block successor has PHI nodes. If so, we need
1125 // to add entries to the PHI nodes for the cloned block now.
1126 for (BasicBlock *SuccBB : successors(NewBlock)) {
1127 for (Instruction &SuccI : *SuccBB) {
1128 auto *SuccPN = dyn_cast(&SuccI);
1129 if (!SuccPN)
1130 break;
1131
1132 // Ok, we have a PHI node. Figure out what the incoming value was for
1133 // the OldBlock.
1134 int OldBlockIdx = SuccPN->getBasicBlockIndex(OldBlock);
1135 if (OldBlockIdx == -1)
1136 break;
1137 Value *IV = SuccPN->getIncomingValue(OldBlockIdx);
1138
1139 // Remap the value if necessary.
1140 if (auto *Inst = dyn_cast(IV)) {
1141 ValueToValueMapTy::iterator I = VMap.find(Inst);
1142 if (I != VMap.end())
1143 IV = I->second;
1144 }
1145
1146 SuccPN->addIncoming(IV, NewBlock);
1147 }
1148 }
1149 }
1150
1151 // Erase the clone's parent from the original funclet's parent list.
1152 std::vector &Parents = FuncletParents[FuncletEntry];
1153 Parents.erase(std::remove(Parents.begin(), Parents.end(), Parent),
1154 Parents.end());
1155
1156 // Store the cloned funclet's parent.
1157 assert(std::find(FuncletParents[ClonedFunclet].begin(),
1158 FuncletParents[ClonedFunclet].end(),
1159 Parent) == std::end(FuncletParents[ClonedFunclet]));
1160 FuncletParents[ClonedFunclet].push_back(Parent);
1161
1162 // Copy any children of the original funclet to the clone. We'll either
1163 // clone them too or make that path unreachable when we take the next step
1164 // in resolveFuncletAncestryForPath().
1165 for (auto *Child : FuncletChildren[FuncletEntry]) {
1166 assert(std::find(FuncletChildren[ClonedFunclet].begin(),
1167 FuncletChildren[ClonedFunclet].end(),
1168 Child) == std::end(FuncletChildren[ClonedFunclet]));
1169 FuncletChildren[ClonedFunclet].push_back(Child);
1170 assert(std::find(FuncletParents[Child].begin(), FuncletParents[Child].end(),
1171 ClonedFunclet) == std::end(FuncletParents[Child]));
1172 FuncletParents[Child].push_back(ClonedFunclet);
1173 }
1174
1175 // Find any blocks that unwound to the original funclet entry from the
1176 // clone parent block and remap them to the clone.
1177 for (auto *U : FuncletEntry->users()) {
1178 auto *UT = dyn_cast(U);
1179 if (!UT)
1180 continue;
1181 BasicBlock *UBB = UT->getParent();
1182 assert(BlockColors[UBB].size() == 1);
1183 BasicBlock *UFunclet = *(BlockColors[UBB].begin());
1184 // Funclets shouldn't be able to loop back on themselves.
1185 assert(UFunclet != FuncletEntry);
1186 // If this instruction unwinds to the original funclet from the clone
1187 // parent, remap the terminator so that it unwinds to the clone instead.
1188 // We will perform a similar transformation for siblings after all
1189 // the siblings have been cloned.
1190 if (UFunclet == Parent) {
1191 // We're about to break the path from this block to the uncloned funclet
1192 // entry, so remove it as a predeccessor to clean up the PHIs.
1193 FuncletEntry->removePredecessor(UBB);
1194 TerminatorInst *Terminator = UBB->getTerminator();
1195 RemapInstruction(Terminator, VMap, RF_IgnoreMissingEntries);
1196 }
1197 }
1198
1199 // This asserts a condition that is relied upon inside the loop below,
1200 // namely that no predecessors of the original funclet entry block
1201 // are also predecessors of the cloned funclet entry block.
1202 assert(std::all_of(pred_begin(FuncletEntry), pred_end(FuncletEntry),
1203 [&ClonedFunclet](BasicBlock *Pred) {
1204 return std::find(pred_begin(ClonedFunclet),
1205 pred_end(ClonedFunclet),
1206 Pred) == pred_end(ClonedFunclet);
1207 }));
1208
1209 // Remove any invalid PHI node entries in the cloned funclet.cl
1210 std::vector PHIsToErase;
1211 for (Instruction &I : *ClonedFunclet) {
1212 auto *PN = dyn_cast(&I);
1213 if (!PN)
1214 break;
1215
1216 // Predecessors of the original funclet do not reach the cloned funclet,
1217 // but the cloning process assumes they will. Remove them now.
1218 for (auto *Pred : predecessors(FuncletEntry))
1219 PN->removeIncomingValue(Pred, false);
1220 }
1221 for (auto *PN : PHIsToErase)
1222 PN->eraseFromParent();
1223
1224 // Replace the original funclet in the parent's children vector with the
1225 // cloned funclet.
1226 for (auto &It : FuncletChildren[Parent]) {
1227 if (It == FuncletEntry) {
1228 It = ClonedFunclet;
1229 break;
1230 }
1231 }
1232
1233 return ClonedFunclet;
1234 }
1235
1236 // Removes the unwind edge for any exceptional terminators within the specified
1237 // parent funclet that previously unwound to the specified child funclet.
1238 void WinEHPrepare::makeFuncletEdgeUnreachable(BasicBlock *Parent,
1239 BasicBlock *Child) {
1240 for (BasicBlock *BB : FuncletBlocks[Parent]) {
1241 TerminatorInst *Terminator = BB->getTerminator();
1242 if (!Terminator->isExceptional())
1243 continue;
1244
1245 // Look for terninators that unwind to the child funclet.
1246 BasicBlock *UnwindDest = nullptr;
1247 if (auto *I = dyn_cast(Terminator))
1248 UnwindDest = I->getUnwindDest();
1249 else if (auto *I = dyn_cast(Terminator))
1250 UnwindDest = I->getUnwindDest();
1251 else if (auto *I = dyn_cast(Terminator))
1252 UnwindDest = I->getUnwindDest();
1253 // cleanupendpad, catchret and cleanupret don't represent a parent-to-child
1254 // funclet transition, so we don't need to consider them here.
1255
1256 // If the child funclet is the unwind destination, replace the terminator
1257 // with an unreachable instruction.
1258 if (UnwindDest == Child)
1259 removeUnwindEdge(BB);
1260 }
1261 // The specified parent is no longer a parent of the specified child.
1262 std::vector &Children = FuncletChildren[Parent];
1263 Children.erase(std::remove(Children.begin(), Children.end(), Child),
1264 Children.end());
1265 }
1266
1267 // This routine is called after funclets with multiple parents are cloned for
1268 // a specific parent. Here we look for children of the specified funclet that
1269 // unwind to other children of that funclet and update the unwind destinations
1270 // to ensure that each sibling is connected to the correct clone of the sibling
1271 // to which it unwinds.
1272 static void updateSiblingToSiblingUnwind(
1273 BasicBlock *CurFunclet,
1274 std::map> &BlockColors,
1275 std::map> &FuncletBlocks,
1276 std::map> &FuncletParents,
1277 std::map> &FuncletChildren,
1278 std::map &Funclet2Orig) {
1279 // Remap any bad sibling-to-sibling transitions for funclets that
1280 // we just cloned.
1281 for (BasicBlock *ChildFunclet : FuncletChildren[CurFunclet]) {
1282 bool NeedOrigInvokeRemapping = false;
1283 for (auto *BB : FuncletBlocks[ChildFunclet]) {
1284 TerminatorInst *Terminator = BB->getTerminator();
1285 if (!Terminator->isExceptional())
1286 continue;
1287
1288 // See if this terminator has an unwind destination.
1289 // Note that catchendpads are handled when the associated catchpad
1290 // is cloned. They don't fit the pattern we're looking for here.
1291 BasicBlock *UnwindDest = nullptr;
1292 if (auto *II = dyn_cast(Terminator)) {
1293 UnwindDest = II->getUnwindDest();
1294 assert(UnwindDest && "Invoke unwinds to a null destination.");
1295 assert(UnwindDest->isEHPad() && "Invoke does not unwind to an EH pad.");
1296 auto *EHPadInst = UnwindDest->getFirstNonPHI();
1297 if (isa(EHPadInst)) {
1298 // If the invoke unwind destination is the unwind destination for
1299 // the current child catch pad funclet, there is nothing to be done.
1300 auto *CurCatch = cast(ChildFunclet->getFirstNonPHI());
1301 if (CurCatch->getUnwindDest() == UnwindDest)
1302 continue;
1303
1304 // Otherwise, the invoke unwinds to a catch end pad that is the unwind
1305 // destination another catch pad in the unwind chain from either the
1306 // current catch pad or one of its clones. If it is already the
1307 // catch end pad at the end unwind chain from the current catch pad,
1308 // we'll need to check the invoke instructions in the original funclet
1309 // later. Otherwise, we need to remap this invoke now.
1310 BasicBlock *CurCatchEnd = getEndPadForCatch(CurCatch);
1311 if (CurCatchEnd == UnwindDest)
1312 NeedOrigInvokeRemapping = true;
1313 else
1314 II->setUnwindDest(CurCatchEnd);
1315 continue;
1316 }
1317 // All other unwind scenarios for the invoke are handled elsewhere.
1318 continue;
1319 } else if (auto *I = dyn_cast(Terminator)) {
1320 UnwindDest = I->getUnwindDest();
1321 // The catchendpad is not a sibling destination. This case should
1322 // have been handled in cloneFuncletForParent().
1323 if (isa(Terminator)) {
1324 assert(BlockColors[UnwindDest].size() == 1 &&
1325 "Cloned catchpad unwinds to an pad with multiple parents.");
1326 assert(FuncletParents[UnwindDest].front() == CurFunclet &&
1327 "Cloned catchpad unwinds to the wrong parent.");
1328 continue;
1329 }
1330 } else {
1331 if (auto *I = dyn_cast(Terminator))
1332 UnwindDest = I->getUnwindDest();
1333 else if (auto *I = dyn_cast(Terminator))
1334 UnwindDest = I->getUnwindDest();
1335
1336 // If the cleanup unwinds to caller, there is nothing to be done.
1337 if (!UnwindDest)
1338 continue;
1339 }
1340
1341 // If the destination is not a cleanup pad, catch pad or terminate pad
1342 // we don't need to handle it here.
1343 Instruction *EHPad = UnwindDest->getFirstNonPHI();
1344 if (!isa(EHPad) && !isa(EHPad) &&
1345 !isa(EHPad))
1346 continue;
1347
1348 // If it is one of these, then it is either a sibling of the current
1349 // child funclet or a clone of one of those siblings.
1350 // If it is a sibling, no action is needed.
1351 if (FuncletParents[UnwindDest].size() == 1 &&
1352 FuncletParents[UnwindDest].front() == CurFunclet)
1353 continue;
1354
1355 // If the unwind destination is a clone of a sibling, we need to figure
1356 // out which sibling it is a clone of and use that sibling as the
1357 // unwind destination.
1358 BasicBlock *DestOrig = Funclet2Orig[UnwindDest];
1359 BasicBlock *TargetSibling = nullptr;
1360 for (auto &Mapping : Funclet2Orig) {
1361 if (Mapping.second != DestOrig)
1362 continue;
1363 BasicBlock *MappedFunclet = Mapping.first;
1364 if (FuncletParents[MappedFunclet].size() == 1 &&
1365 FuncletParents[MappedFunclet].front() == CurFunclet) {
1366 TargetSibling = MappedFunclet;
1367 }
1368 }
1369 // If we didn't find the sibling we were looking for then the
1370 // unwind destination is not a clone of one of child's siblings.
1371 // That's unexpected.
1372 assert(TargetSibling && "Funclet unwinds to unexpected destination.");
1373
1374 // Update the terminator instruction to unwind to the correct sibling.
1375 if (auto *I = dyn_cast(Terminator))
1376 I->setUnwindDest(TargetSibling);
1377 else if (auto *I = dyn_cast(Terminator))
1378 I->setUnwindDest(TargetSibling);
1379 else if (auto *I = dyn_cast(Terminator))
1380 I->setUnwindDest(TargetSibling);
1381 }
1382 if (NeedOrigInvokeRemapping) {
1383 // To properly remap invoke instructions that unwind to catch end pads
1384 // that are not the unwind destination of the catch pad funclet in which
1385 // the invoke appears, we must also look at the uncloned invoke in the
1386 // original funclet. If we saw an invoke that was already properly
1387 // unwinding to a sibling's catch end pad, we need to check the invokes
1388 // in the original funclet.
1389 BasicBlock *OrigFunclet = Funclet2Orig[ChildFunclet];
1390 for (auto *BB : FuncletBlocks[OrigFunclet]) {
1391 auto *II = dyn_cast(BB->getTerminator());
1392 if (!II)
1393 continue;
1394
1395 BasicBlock *UnwindDest = II->getUnwindDest();
1396 assert(UnwindDest && "Invoke unwinds to a null destination.");
1397 assert(UnwindDest->isEHPad() && "Invoke does not unwind to an EH pad.");
1398 auto *CEP = dyn_cast(UnwindDest->getFirstNonPHI());
1399 if (!CEP)
1400 continue;
1401 // If the invoke unwind destination is the unwind destination for
1402 // the original catch pad funclet, there is nothing to be done.
1403 auto *OrigCatch = cast(OrigFunclet->getFirstNonPHI());
1404 if (OrigCatch->getUnwindDest() == UnwindDest)
1405 continue;
1406
1407 // Otherwise, the invoke unwinds to a catch end pad that is the unwind
1408 // destination another catch pad in the unwind chain from either the
1409 // current catch pad or one of its clones. If it is not already the
1410 // catch end pad at the end unwind chain from the current catch pad,
1411 // we need to remap this invoke now.
1412 BasicBlock *OrigCatchEnd = getEndPadForCatch(OrigCatch);
1413 if (OrigCatchEnd != UnwindDest)
1414 II->setUnwindDest(OrigCatchEnd);
1415 }
1416 }
1417 }
1418 }
1419
1420 void WinEHPrepare::resolveFuncletAncestry(
1421 Function &F, SmallVectorImpl &EntryBlocks) {
1422 // Most of the time this will be unnecessary. If the conditions arise that
1423 // require this work, this flag will be set.
1424 if (!FuncletCloningRequired)
1425 return;
1426
1427 // Funclet2Orig is used to map any cloned funclets back to the original
1428 // funclet from which they were cloned. The map is seeded with the
1429 // original funclets mapping to themselves.
1430 std::map Funclet2Orig;
1431 for (auto *Funclet : EntryBlocks)
1432 Funclet2Orig[Funclet] = Funclet;
1433
1434 // Start with the entry funclet and walk the funclet parent-child tree.
1435 SmallVector FuncletPath;
1436 FuncletPath.push_back(&(F.getEntryBlock()));
1437 resolveFuncletAncestryForPath(F, FuncletPath, Funclet2Orig);
1438 }
1439
1440 // Walks the funclet control flow, cloning any funclets that have more than one
1441 // parent funclet and breaking any cyclic unwind chains so that the path becomes
1442 // unreachable at the point where a funclet would have unwound to a funclet that
1443 // was already in the chain.
1444 void WinEHPrepare::resolveFuncletAncestryForPath(
1445 Function &F, SmallVectorImpl &FuncletPath,
1446 std::map &Funclet2Orig) {
1447 bool ClonedAnyChildren = false;
1448 BasicBlock *CurFunclet = FuncletPath.back();
1449 // Copy the children vector because we might changing it.
1450 std::vector Children(FuncletChildren[CurFunclet]);
1451 for (BasicBlock *ChildFunclet : Children) {
1452 // Don't allow the funclet chain to unwind back on itself.
1453 // If this funclet is already in the current funclet chain, make the
1454 // path to it through the current funclet unreachable.
1455 bool IsCyclic = false;
1456 BasicBlock *ChildIdentity = Funclet2Orig[ChildFunclet];
1457 for (BasicBlock *Ancestor : FuncletPath) {
1458 BasicBlock *AncestorIdentity = Funclet2Orig[Ancestor];
1459 if (AncestorIdentity == ChildIdentity) {
1460 IsCyclic = true;
1461 break;
1462 }
1463 }
1464 // If the unwind chain wraps back on itself, break the chain.
1465 if (IsCyclic) {
1466 makeFuncletEdgeUnreachable(CurFunclet, ChildFunclet);
1467 continue;
1468 }
1469 // If this child funclet has other parents, clone the entire funclet.
1470 if (FuncletParents[ChildFunclet].size() > 1) {
1471 ChildFunclet = cloneFuncletForParent(F, ChildFunclet, CurFunclet);
1472 Funclet2Orig[ChildFunclet] = ChildIdentity;
1473 ClonedAnyChildren = true;
1474 }
1475 FuncletPath.push_back(ChildFunclet);
1476 resolveFuncletAncestryForPath(F, FuncletPath, Funclet2Orig);
1477 FuncletPath.pop_back();
1478 }
1479 // If we didn't clone any children, we can return now.
1480 if (!ClonedAnyChildren)
1481 return;
1482
1483 updateSiblingToSiblingUnwind(CurFunclet, BlockColors, FuncletBlocks,
1484 FuncletParents, FuncletChildren, Funclet2Orig);
1485 }
1486
1487 void WinEHPrepare::colorFunclets(Function &F,
1488 SmallVectorImpl &EntryBlocks) {
1489 ::colorFunclets(F, EntryBlocks, BlockColors, FuncletBlocks);
1490651
1491652 // The processing above actually accumulated the parent set for this
1492653 // funclet into the color set for its entry; use the parent set to
1495656 // that transitions to the child funclet).
1496657 for (BasicBlock *FuncletEntry : EntryBlocks) {
1497658 std::set &ColorMapItem = BlockColors[FuncletEntry];
1498 // It will be rare for funclets to have multiple parents, but if any
1499 // do we need to clone the funclet later to address that. Here we
1500 // set a flag indicating that this case has arisen so that we don't
1501 // have to do a lot of checking later to handle the more common case.
1502 if (ColorMapItem.size() > 1)
1503 FuncletCloningRequired = true;
1504 for (BasicBlock *Parent : ColorMapItem) {
1505 assert(std::find(FuncletChildren[Parent].begin(),
1506 FuncletChildren[Parent].end(),
1507 FuncletEntry) == std::end(FuncletChildren[Parent]));
1508 FuncletChildren[Parent].push_back(FuncletEntry);
1509 assert(std::find(FuncletParents[FuncletEntry].begin(),
1510 FuncletParents[FuncletEntry].end(),
1511 Parent) == std::end(FuncletParents[FuncletEntry]));
1512 FuncletParents[FuncletEntry].push_back(Parent);
1513 }
659 for (BasicBlock *Parent : ColorMapItem)
660 FuncletChildren[Parent].insert(FuncletEntry);
1514661 ColorMapItem.clear();
1515662 ColorMapItem.insert(FuncletEntry);
1516663 }
664 }
665
666 void WinEHPrepare::colorFunclets(Function &F,
667 SmallVectorImpl &EntryBlocks) {
668 ::colorFunclets(F, EntryBlocks, BlockColors, FuncletBlocks, FuncletChildren);
1517669 }
1518670
1519671 void llvm::calculateCatchReturnSuccessorColors(const Function *Fn,
1525677
1526678 std::map> BlockColors;
1527679 std::map> FuncletBlocks;
680 std::map> FuncletChildren;
1528681 // Figure out which basic blocks belong to which funclets.
1529682 colorFunclets(const_cast(*Fn), EntryBlocks, BlockColors,
1530 FuncletBlocks);
1531
1532 // The static colorFunclets routine assigns multiple colors to funclet entries
1533 // because that information is needed to calculate funclets' parent-child
1534 // relationship, but we don't need those relationship here and ultimately the
1535 // entry blocks should have the color of the funclet they begin.
1536 for (BasicBlock *FuncletEntry : EntryBlocks) {
1537 BlockColors[FuncletEntry].clear();
1538 BlockColors[FuncletEntry].insert(FuncletEntry);
1539 }
683 FuncletBlocks, FuncletChildren);
1540684
1541685 // We need to find the catchret successors. To do this, we must first find
1542686 // all the catchpad funclets.
1627771
1628772 std::map Orig2Clone;
1629773 ValueToValueMapTy VMap;
1630 for (auto BlockIt = BlocksInFunclet.begin(),
1631 BlockEnd = BlocksInFunclet.end();
1632 BlockIt != BlockEnd;) {
1633 // Increment the iterator inside the loop because we might be removing
1634 // blocks from the set.
1635 BasicBlock *BB = *BlockIt++;
774 for (BasicBlock *BB : BlocksInFunclet) {
1636775 std::set &ColorsForBB = BlockColors[BB];
1637776 // We don't need to do anything if the block is monochromatic.
1638777 size_t NumColorsForBB = ColorsForBB.size();
1639778 if (NumColorsForBB == 1)
1640779 continue;
1641
1642 // If this block is a catchendpad, it shouldn't be cloned.
1643 // We will only see a catchendpad with multiple colors in the case where
1644 // some funclet has multiple parents. In that case, the color will be
1645 // resolved during the resolveFuncletAncestry processing.
1646 // For now, find the catchpad that unwinds to this block and assign
1647 // that catchpad's first parent to be the color for this block.
1648 if (isa(BB->getFirstNonPHI())) {
1649 assert(
1650 FuncletCloningRequired &&
1651 "Found multi-colored catchendpad with no multi-parent funclets.");
1652 BasicBlock *CatchParent = nullptr;
1653 // There can only be one catchpad predecessor for a catchendpad.
1654 for (BasicBlock *PredBB : predecessors(BB)) {
1655 if (isa(PredBB->getTerminator())) {
1656 CatchParent = PredBB;
1657 break;
1658 }
1659 }
1660 // There must be one catchpad predecessor for a catchendpad.
1661 assert(CatchParent && "No catchpad found for catchendpad.");
1662
1663 // If the catchpad has multiple parents, we'll clone the catchendpad
1664 // when we clone the catchpad funclet and insert it into the correct
1665 // funclet. For now, we just select the first parent of the catchpad
1666 // and give the catchendpad that color.
1667 BasicBlock *CorrectColor = FuncletParents[CatchParent].front();
1668 assert(FuncletBlocks[CorrectColor].count(BB));
1669 assert(BlockColors[BB].count(CorrectColor));
1670
1671 // Remove this block from the FuncletBlocks set of any funclet that
1672 // isn't the funclet whose color we just selected.
1673 for (auto It = BlockColors[BB].begin(), End = BlockColors[BB].end();
1674 It != End; ) {
1675 // The iterator must be incremented here because we are removing
1676 // elements from the set we're walking.
1677 auto Temp = It++;
1678 BasicBlock *ContainingFunclet = *Temp;
1679 if (ContainingFunclet != CorrectColor) {
1680 FuncletBlocks[ContainingFunclet].erase(BB);
1681 BlockColors[BB].erase(Temp);
1682 }
1683 }
1684
1685 // This should leave just one color for BB.
1686 assert(BlockColors[BB].size() == 1);
1687 continue;
1688 }
1689
1690 DEBUG_WITH_TYPE("winehprepare-coloring",
1691 dbgs() << " Cloning block \'" << BB->getName()
1692 << "\' for funclet \'" << FuncletPadBB->getName()
1693 << "\'.\n");
1694780
1695781 // Create a new basic block and copy instructions into it!
1696782 BasicBlock *CBB =
1719805 BlocksInFunclet.insert(NewBlock);
1720806 BlockColors[NewBlock].insert(FuncletPadBB);
1721807
1722 DEBUG_WITH_TYPE("winehprepare-coloring",
1723 dbgs() << " Assigned color \'" << FuncletPadBB->getName()
1724 << "\' to block \'" << NewBlock->getName()
1725 << "\'.\n");
1726
1727808 BlocksInFunclet.erase(OldBlock);
1728809 BlockColors[OldBlock].erase(FuncletPadBB);
1729
1730 DEBUG_WITH_TYPE("winehprepare-coloring",
1731 dbgs() << " Removed color \'" << FuncletPadBB->getName()
1732 << "\' from block \'" << OldBlock->getName()
1733 << "\'.\n");
1734
1735 // If we are cloning a funclet that might share a child funclet with
1736 // another funclet, look to see if the cloned block is reached from a
1737 // catchret instruction. If so, save this association so we can retrieve
1738 // the possibly orphaned clone when we clone the child funclet.
1739 if (FuncletCloningRequired) {
1740 for (auto *Pred : predecessors(OldBlock)) {
1741 auto *Terminator = Pred->getTerminator();
1742 if (!isa(Terminator))
1743 continue;
1744 // If this block is reached from a catchret instruction in a funclet
1745 // that has multiple parents, it will have a color for each of those
1746 // parents. We just removed the color of one of the parents, but
1747 // the cloned block will be unreachable until we clone the child
1748 // funclet that contains the catchret instruction. In that case we
1749 // need to create a mapping that will let us find the cloned block
1750 // later and associate it with the cloned child funclet.
1751 bool BlockWillBeEstranged = false;
1752 for (auto *Color : BlockColors[Pred]) {
1753 if (FuncletParents[Color].size() > 1) {
1754 BlockWillBeEstranged = true;
1755 break; // Breaks out of the color loop
1756 }
1757 }
1758 if (BlockWillBeEstranged) {
1759 EstrangedBlocks[FuncletPadBB][OldBlock] = NewBlock;
1760 DEBUG_WITH_TYPE("winehprepare-coloring",
1761 dbgs() << " Saved mapping of estranged block \'"
1762 << NewBlock->getName() << "\' for \'"
1763 << FuncletPadBB->getName() << "\'.\n");
1764 break; // Breaks out of the predecessor loop
1765 }
1766 }
1767 }
1768810 }
1769811
1770812 // Loop over all of the instructions in this funclet, fixing up operand
1951993
1952994 cloneCommonBlocks(F, EntryBlocks);
1953995
1954 resolveFuncletAncestry(F, EntryBlocks);
1955
1956996 if (!DisableCleanups) {
1957997 removeImplausibleTerminators(F);
1958998
19641004 BlockColors.clear();
19651005 FuncletBlocks.clear();
19661006 FuncletChildren.clear();
1967 FuncletParents.clear();
1968 EstrangedBlocks.clear();
1969 FuncletCloningRequired = false;
19701007
19711008 return true;
19721009 }
279279 ; the dynamic path enters %left, then enters %inner,
280280 ; then calls @h, and that the call to @h doesn't return.
281281 ; CHECK-LABEL: define void @test6(
282 ; CHECK: left:
283 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
284 ; CHECK: right:
285 ; CHECK: to label %right.catch unwind label %right.end
286 ; CHECK: right.catch:
287 ; CHECK: %x = call i32 @g()
288 ; CHECK: store i32 %x, i32* %x.wineh.spillslot
289 ; CHECK: to label %shared.cont unwind label %[[INNER_RIGHT:.+]]
290 ; CHECK: right.end:
291 ; CHECK: catchendpad unwind to caller
292 ; CHECK: shared.cont:
293 ; CHECK: unreachable
294 ; CHECK: [[SHARED_CONT_LEFT]]:
295 ; CHECK: unreachable
296 ; CHECK: [[INNER_RIGHT]]:
297 ; CHECK: [[I_R:\%.+]] = cleanuppad []
298 ; CHECK: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot
299 ; CHECK: call void @h(i32 [[X_RELOAD_R]])
300 ; CHECK: cleanupret [[I_R]] unwind label %right.end
301 ; CHECK: [[INNER_LEFT]]:
302 ; CHECK: [[I_L:\%.+]] = cleanuppad []
303 ; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot
304 ; CHECK: call void @h(i32 [[X_RELOAD_L]])
305 ; CHECK: unreachable
282 ; TODO: CHECKs
306283
307284
308285 define void @test7() personality i32 (...)* @__CxxFrameHandler3 {
334311 ; with the join at the entry itself instead of following a
335312 ; non-pad join.
336313 ; CHECK-LABEL: define void @test7(
337 ; CHECK: invoke.cont:
338 ; CHECK: to label %[[UNREACHABLE_ENTRY:.+]] unwind label %right
339 ; CHECK: left:
340 ; CHECK: to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
341 ; CHECK: right:
342 ; CHECK: to label %right.catch unwind label %right.end
343 ; CHECK: right.catch:
344 ; CHECK: to label %unreachable unwind label %[[INNER_RIGHT:.+]]
345 ; CHECK: right.end:
346 ; CHECK: catchendpad unwind to caller
347 ; CHECK: [[INNER_RIGHT]]:
348 ; CHECK: [[I_R:\%.+]] = cleanuppad []
349 ; CHECK: [[X_R:\%.+]] = call i32 @g()
350 ; CHECK: call void @h(i32 [[X_R]])
351 ; CHECK: cleanupret [[I_R]] unwind label %right.end
352 ; CHECK: [[INNER_LEFT]]:
353 ; CHECK: [[I_L:\%.+]] = cleanuppad []
354 ; CHECK: [[X_L:\%.+]] = call i32 @g()
355 ; CHECK: call void @h(i32 [[X_L]])
356 ; CHECK: unreachable
357 ; CHECK: unreachable:
358 ; CHECK: unreachable
359 ; CHECK: [[UNREACHABLE_LEFT]]:
360 ; CHECK: unreachable
361 ; CHECK: [[UNREACHABLE_ENTRY]]:
362 ; CHECK: unreachable
314 ; TODO: CHECKs
363315
364316
365317 define void @test8() personality i32 (...)* @__CxxFrameHandler3 {
397349 ; %inner is a two-parent child which itself has a child; need
398350 ; to make two copies of both the %inner and %inner.child.
399351 ; CHECK-LABEL: define void @test8(
400 ; CHECK: invoke.cont:
401 ; CHECK: to label %[[UNREACHABLE_ENTRY:.+]] unwind label %right
402 ; CHECK: left:
403 ; CHECK: to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
404 ; CHECK: right:
405 ; CHECK: to label %right.catch unwind label %right.end
406 ; CHECK: right.catch:
407 ; CHECK: to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
408 ; CHECK: right.end:
409 ; CHECK: catchendpad unwind to caller
410 ; CHECK: [[INNER_RIGHT]]:
411 ; CHECK: to label %[[UNREACHABLE_INNER_RIGHT:.+]] unwind label %[[INNER_CHILD_RIGHT:.+]]
412 ; CHECK: [[INNER_LEFT]]:
413 ; CHECK: to label %[[UNREACHABLE_INNER_LEFT:.+]] unwind label %[[INNER_CHILD_LEFT:.+]]
414 ; CHECK: [[INNER_CHILD_RIGHT]]:
415 ; CHECK: [[TMP:\%.+]] = cleanuppad []
416 ; CHECK: [[X:\%.+]] = call i32 @g()
417 ; CHECK: call void @h(i32 [[X]])
418 ; CHECK: unreachable
419 ; CHECK: [[INNER_CHILD_LEFT]]:
420 ; CHECK: [[TMP:\%.+]] = cleanuppad []
421 ; CHECK: [[X:\%.+]] = call i32 @g()
422 ; CHECK: call void @h(i32 [[X]])
423 ; CHECK: unreachable
424 ; CHECK: [[UNREACHABLE_INNER_RIGHT]]:
425 ; CHECK: unreachable
426 ; CHECK: [[UNREACHABLE_INNER_LEFT]]:
427 ; CHECK: unreachable
428 ; CHECK: [[UNREACHABLE_RIGHT]]:
429 ; CHECK: unreachable
430 ; CHECK: [[UNREACHABLE_LEFT]]:
431 ; CHECK: unreachable
432 ; CHECK: [[UNREACHABLE_ENTRY]]:
433 ; CHECK: unreachable
352 ; TODO: CHECKs
434353
435354
436355 define void @test9() personality i32 (...)* @__CxxFrameHandler3 {
463382 ; of which was which along the way; generating each possibility lets
464383 ; whichever case was correct execute correctly.
465384 ; CHECK-LABEL: define void @test9(
466 ; CHECK: entry:
467 ; CHECK: to label %invoke.cont unwind label %[[LEFT:.+]]
468 ; CHECK: invoke.cont:
469 ; CHECK: to label %[[UNREACHABLE_ENTRY:.+]] unwind label %[[RIGHT:.+]]
470 ; CHECK: [[LEFT_FROM_RIGHT:.+]]:
471 ; CHECK: call void @h(i32 1)
472 ; CHECK: call void @f()
473 ; CHECK: unreachable
474 ; CHECK: [[LEFT]]:
475 ; CHECK: call void @h(i32 1)
476 ; CHECK: invoke void @f()
477 ; CHECK: to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[RIGHT_FROM_LEFT:.+]]
478 ; CHECK: [[RIGHT]]:
479 ; CHECK: call void @h(i32 2)
480 ; CHECK: invoke void @f()
481 ; CHECK: to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[LEFT_FROM_RIGHT]]
482 ; CHECK: [[RIGHT_FROM_LEFT]]:
483 ; CHECK: call void @h(i32 2)
484 ; CHECK: call void @f()
485 ; CHECK: unreachable
486 ; CHECK: [[UNREACHABLE_RIGHT]]:
487 ; CHECK: unreachable
488 ; CHECK: [[UNREACHABLE_LEFT]]:
489 ; CHECK: unreachable
490 ; CHECK: [[UNREACHABLE_ENTRY]]:
491 ; CHECK: unreachable
492
385 ; TODO: CHECKs
493386
494387 define void @test10() personality i32 (...)* @__CxxFrameHandler3 {
495388 entry:
8585 ; CHECK: store i32 %z
8686 ; CHECK-NEXT: invoke void @f
8787 invoke void @f()
88 to label %catchret.inner unwind label %catchend.inner
88 to label %catchret.inner unwind label %merge.outer
8989
9090 catchret.inner:
9191 catchret %cpinner to label %exit
9292 catchend.inner:
93 ; CHECK-NOT: = phi
94 %y = phi i32 [ %x, %merge.inner ], [ %z, %catch.inner ]
9593 catchendpad unwind label %merge.outer
9694
9795 merge.outer:
9896 ; CHECK: merge.outer:
97 ; CHECK-NOT: = phi
9998 ; CHECK: [[CatchPad:%[^ ]+]] = catchpad []
99 %y = phi i32 [ %x, %catchend.inner ], [ %z, %catch.inner ]
100100 %cpouter = catchpad [] to label %catch.outer unwind label %catchend.outer
101101
102102 catchend.outer:
+0
-1561
test/CodeGen/WinEH/wineh-multi-parent-cloning.ll less more
None ; RUN: opt -mtriple=x86_x64-pc-windows-msvc -S -winehprepare < %s | FileCheck %s
1
2 declare i32 @__CxxFrameHandler3(...)
3
4 declare void @f()
5 declare i32 @g()
6 declare void @h(i32)
7 declare i1 @b()
8
9 define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
10 entry:
11 invoke void @f()
12 to label %invoke.cont unwind label %left
13 invoke.cont:
14 invoke void @f()
15 to label %exit unwind label %right
16 left:
17 cleanuppad []
18 br label %shared
19 right:
20 catchpad []
21 to label %right.catch unwind label %right.end
22 right.catch:
23 br label %shared
24 right.end:
25 catchendpad unwind to caller
26 shared:
27 %x = call i32 @g()
28 invoke void @f()
29 to label %shared.cont unwind label %inner
30 shared.cont:
31 unreachable
32 inner:
33 %i = cleanuppad []
34 call void @h(i32 %x)
35 cleanupret %i unwind label %right.end
36 exit:
37 ret void
38 }
39 ; %inner is a cleanup which appears both as a child of
40 ; %left and as a child of %right. Since statically we
41 ; need each funclet to have a single parent, we need to
42 ; clone the entire %inner funclet so we can have one
43 ; copy under each parent. The cleanupret in %inner
44 ; unwinds to the catchendpad for %right, so the copy
45 ; of %inner under %right should include it; the copy
46 ; of %inner under %left should instead have an
47 ; `unreachable` inserted there, but the copy under
48 ; %left still needs to be created because it's possible
49 ; the dynamic path enters %left, then enters %inner,
50 ; then calls @h, and that the call to @h doesn't return.
51 ; CHECK-LABEL: define void @test1(
52 ; CHECK: left:
53 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
54 ; CHECK: right:
55 ; CHECK: to label %right.catch unwind label %right.end
56 ; CHECK: right.catch:
57 ; CHECK: %x = call i32 @g()
58 ; CHECK: store i32 %x, i32* %x.wineh.spillslot
59 ; CHECK: to label %shared.cont unwind label %[[INNER_RIGHT:.+]]
60 ; CHECK: right.end:
61 ; CHECK: catchendpad unwind to caller
62 ; CHECK: shared.cont:
63 ; CHECK: unreachable
64 ; CHECK: [[SHARED_CONT_LEFT]]:
65 ; CHECK: unreachable
66 ; CHECK: [[INNER_RIGHT]]:
67 ; CHECK: [[I_R:\%.+]] = cleanuppad []
68 ; CHECK: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot
69 ; CHECK: call void @h(i32 [[X_RELOAD_R]])
70 ; CHECK: cleanupret [[I_R]] unwind label %right.end
71 ; CHECK: [[INNER_LEFT]]:
72 ; CHECK: [[I_L:\%.+]] = cleanuppad []
73 ; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot
74 ; CHECK: call void @h(i32 [[X_RELOAD_L]])
75 ; CHECK: unreachable
76
77
78 define void @test2() personality i32 (...)* @__CxxFrameHandler3 {
79 entry:
80 invoke void @f()
81 to label %invoke.cont unwind label %left
82 invoke.cont:
83 invoke void @f()
84 to label %exit unwind label %right
85 left:
86 cleanuppad []
87 br label %shared
88 right:
89 catchpad []
90 to label %right.catch unwind label %right.end
91 right.catch:
92 br label %shared
93 right.end:
94 catchendpad unwind to caller
95 shared:
96 %x = call i32 @g()
97 invoke void @f()
98 to label %shared.cont unwind label %inner
99 shared.cont:
100 unreachable
101 inner:
102 catchpad []
103 to label %inner.catch unwind label %inner.end
104 inner.catch:
105 call void @h(i32 %x)
106 unreachable
107 inner.end:
108 catchendpad unwind label %right.end
109 exit:
110 ret void
111 }
112 ; In this case left and right are both parents of inner. This differs from
113 ; @test1 in that inner is a catchpad rather than a cleanuppad, which makes
114 ; inner.end a block that gets cloned so that left and right each contain a
115 ; copy (catchendpad blocks are considered to be part of the parent funclet
116 ; of the associated catchpad). The catchendpad in %inner.end unwinds to
117 ; %right.end (which belongs to the entry funclet).
118 ; CHECK-LABEL: define void @test2(
119 ; CHECK: left:
120 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
121 ; CHECK: right:
122 ; CHECK: to label %right.catch unwind label %[[RIGHT_END:.+]]
123 ; CHECK: right.catch:
124 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
125 ; CHECK: [[RIGHT_END]]:
126 ; CHECK: catchendpad unwind to caller
127 ; CHECK: [[SHARED_CONT_RIGHT]]:
128 ; CHECK: unreachable
129 ; CHECK: [[SHARED_CONT_LEFT]]:
130 ; CHECK: unreachable
131 ; CHECK: [[INNER_RIGHT]]:
132 ; CHECK: catchpad []
133 ; CHECK: to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
134 ; CHECK: [[INNER_LEFT]]:
135 ; CHECK: catchpad []
136 ; CHECK: to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
137 ; CHECK: [[INNER_CATCH_RIGHT]]:
138 ; CHECK: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot
139 ; CHECK: call void @h(i32 [[X_RELOAD_R]])
140 ; CHECK: unreachable
141 ; CHECK: [[INNER_CATCH_LEFT]]:
142 ; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot
143 ; CHECK: call void @h(i32 [[X_RELOAD_L]])
144 ; CHECK: unreachable
145 ; CHECK: [[INNER_END_LEFT]]:
146 ; CHECK: catchendpad unwind to caller
147 ; CHECK: [[INNER_END_RIGHT]]:
148 ; CHECK: catchendpad unwind label %[[RIGHT_END]]
149
150 define void @test3() personality i32 (...)* @__CxxFrameHandler3 {
151 entry:
152 invoke void @f()
153 to label %exit unwind label %left
154 left:
155 %l = cleanuppad []
156 br label %shared
157 left.end:
158 cleanupendpad %l unwind label %right
159 right:
160 catchpad []
161 to label %right.catch unwind label %right.end
162 right.catch:
163 br label %shared
164 right.end:
165 catchendpad unwind to caller
166 shared:
167 %x = call i32 @g()
168 invoke void @f()
169 to label %shared.cont unwind label %inner
170 shared.cont:
171 unreachable
172 inner:
173 catchpad []
174 to label %inner.catch unwind label %inner.end
175 inner.catch:
176 call void @h(i32 %x)
177 unreachable
178 inner.end:
179 catchendpad unwind label %left.end
180 exit:
181 ret void
182 }
183 ; In this case, %left and %right are siblings with %entry as the parent of both,
184 ; while %left and %right are both parents of %inner. The catchendpad in
185 ; %inner.end unwinds to %left.end. When %inner is cloned a copy of %inner.end
186 ; will be made for both %left and %right, but because %left.end is a cleanup pad
187 ; and %right is a catch pad the unwind edge from the copy of %inner.end for
188 ; %right must be removed.
189 ; CHECK-LABEL: define void @test3(
190 ; CHECK: left:
191 ; CHECK: %l = cleanuppad []
192 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
193 ; CHECK: [[LEFT_END:left.end.*]]:
194 ; CHECK: cleanupendpad %l unwind label %right
195 ; CHECK: right:
196 ; CHECK: to label %right.catch unwind label %[[RIGHT_END:.+]]
197 ; CHECK: right.catch:
198 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
199 ; CHECK: [[RIGHT_END]]:
200 ; CHECK: catchendpad unwind to caller
201 ; CHECK: [[SHARED_CONT_RIGHT]]:
202 ; CHECK: unreachable
203 ; CHECK: [[SHARED_CONT_LEFT]]:
204 ; CHECK: unreachable
205 ; CHECK: [[INNER_RIGHT]]:
206 ; CHECK: catchpad []
207 ; CHECK: to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
208 ; CHECK: [[INNER_LEFT]]:
209 ; CHECK: catchpad []
210 ; CHECK: to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
211 ; CHECK: [[INNER_CATCH_RIGHT]]:
212 ; CHECK: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot
213 ; CHECK: call void @h(i32 [[X_RELOAD_R]])
214 ; CHECK: unreachable
215 ; CHECK: [[INNER_CATCH_LEFT]]:
216 ; CHECK: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot
217 ; CHECK: call void @h(i32 [[X_RELOAD_R]])
218 ; CHECK: unreachable
219 ; CHECK: [[INNER_END_LEFT]]:
220 ; CHECK: catchendpad unwind label %[[LEFT_END]]
221 ; CHECK: [[INNER_END_RIGHT]]:
222 ; CHECK: catchendpad unwind to caller
223
224
225 define void @test4() personality i32 (...)* @__CxxFrameHandler3 {
226 entry:
227 invoke void @f()
228 to label %exit unwind label %left
229 left:
230 catchpad []
231 to label %left.catch unwind label %left.end
232 left.catch:
233 br label %shared
234 left.end:
235 catchendpad unwind label %right
236 right:
237 catchpad []
238 to label %right.catch unwind label %right.end
239 right.catch:
240 br label %shared
241 right.end:
242 catchendpad unwind to caller
243 shared:
244 %x = call i32 @g()
245 invoke void @f()
246 to label %shared.cont unwind label %inner
247 shared.cont:
248 unreachable
249 inner:
250 catchpad []
251 to label %inner.catch unwind label %inner.end
252 inner.catch:
253 call void @h(i32 %x)
254 unreachable
255 inner.end:
256 catchendpad unwind label %left.end
257 exit:
258 ret void
259 }
260 ; This is a variation of @test3 in which both %left and %right are catch pads.
261 ; In this case, %left and %right are siblings with %entry as the parent of both,
262 ; while %left and %right are both parents of %inner. The catchendpad in
263 ; %inner.end unwinds to %left.end. When %inner is cloned a copy of %inner.end
264 ; will be made for both %left and %right, but because the catchpad in %right
265 ; does not unwind to %left.end the unwind edge from the copy of %inner.end for
266 ; %right must be removed.
267 ; CHECK-LABEL: define void @test4(
268 ; CHECK: left:
269 ; CHECK: catchpad []
270 ; CHECK: to label %left.catch unwind label %[[LEFT_END:.+]]
271 ; CHECK: left.catch:
272 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
273 ; CHECK: [[LEFT_END]]:
274 ; CHECK: catchendpad unwind label %right
275 ; CHECK: right:
276 ; CHECK: to label %right.catch unwind label %[[RIGHT_END:.+]]
277 ; CHECK: right.catch:
278 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
279 ; CHECK: [[RIGHT_END]]:
280 ; CHECK: catchendpad unwind to caller
281 ; CHECK: [[SHARED_CONT_RIGHT]]:
282 ; CHECK: unreachable
283 ; CHECK: [[SHARED_CONT_LEFT]]:
284 ; CHECK: unreachable
285 ; CHECK: [[INNER_RIGHT]]:
286 ; CHECK: catchpad []
287 ; CHECK: to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
288 ; CHECK: [[INNER_LEFT]]:
289 ; CHECK: catchpad []
290 ; CHECK: to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
291 ; CHECK: [[INNER_CATCH_RIGHT]]:
292 ; CHECK: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot
293 ; CHECK: call void @h(i32 [[X_RELOAD_R]])
294 ; CHECK: unreachable
295 ; CHECK: [[INNER_CATCH_LEFT]]:
296 ; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot
297 ; CHECK: call void @h(i32 [[X_RELOAD_L]])
298 ; CHECK: unreachable
299 ; CHECK: [[INNER_END_LEFT]]:
300 ; CHECK: catchendpad unwind label %[[LEFT_END]]
301 ; CHECK: [[INNER_END_RIGHT]]:
302 ; CHECK: catchendpad unwind to caller
303
304
305 define void @test5() personality i32 (...)* @__CxxFrameHandler3 {
306 entry:
307 invoke void @f()
308 to label %exit unwind label %left
309 left:
310 catchpad []
311 to label %left.catch unwind label %left.end
312 left.catch:
313 br label %shared
314 left.end:
315 catchendpad unwind label %right
316 right:
317 %r = cleanuppad []
318 br label %shared
319 shared:
320 %x = call i32 @g()
321 invoke void @f()
322 to label %shared.cont unwind label %inner
323 shared.cont:
324 unreachable
325 inner:
326 catchpad []
327 to label %inner.catch unwind label %inner.end
328 inner.catch:
329 call void @h(i32 %x)
330 unreachable
331 inner.end:
332 catchendpad unwind label %left.end
333 exit:
334 ret void
335 }
336 ; Like @test3, %left and %right are siblings with %entry as the parent of both,
337 ; while %left and %right are both parents of %inner. This case makes %left a
338 ; catch and %right a cleanup so that %inner unwinds to %left.end, which is a
339 ; block in %entry. The %inner funclet is cloned for %left and %right, but the
340 ; copy of %inner.end for %right must have its unwind edge removed because the
341 ; catchendpad at %left.end is not compatible with %right.
342 ; CHECK-LABEL: define void @test5(
343 ; CHECK: left:
344 ; CHECK: catchpad []
345 ; CHECK: to label %left.catch unwind label %[[LEFT_END:.+]]
346 ; CHECK: left.catch:
347 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
348 ; CHECK: [[LEFT_END]]:
349 ; CHECK: catchendpad unwind label %right
350 ; CHECK: right:
351 ; CHECK: %r = cleanuppad []
352 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
353 ; CHECK: [[SHARED_CONT_RIGHT]]:
354 ; CHECK: unreachable
355 ; CHECK: [[SHARED_CONT_LEFT]]:
356 ; CHECK: unreachable
357 ; CHECK: [[INNER_RIGHT]]:
358 ; CHECK: catchpad []
359 ; CHECK: to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
360 ; CHECK: [[INNER_LEFT]]:
361 ; CHECK: catchpad []
362 ; CHECK: to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
363 ; CHECK: [[INNER_CATCH_RIGHT]]:
364 ; CHECK: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot
365 ; CHECK: call void @h(i32 [[X_RELOAD_R]])
366 ; CHECK: unreachable
367 ; CHECK: [[INNER_CATCH_LEFT]]:
368 ; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot
369 ; CHECK: call void @h(i32 [[X_RELOAD_L]])
370 ; CHECK: unreachable
371 ; CHECK: [[INNER_END_LEFT]]:
372 ; CHECK: catchendpad unwind label %[[LEFT_END]]
373 ; CHECK: [[INNER_END_RIGHT]]:
374 ; CHECK: catchendpad unwind to caller
375
376 define void @test6() personality i32 (...)* @__CxxFrameHandler3 {
377 entry:
378 invoke void @f()
379 to label %exit unwind label %left
380 left:
381 catchpad []
382 to label %left.catch unwind label %left.end
383 left.catch:
384 br label %shared
385 left.end:
386 catchendpad unwind label %middle
387 middle:
388 %m = catchpad []
389 to label %middle.catch unwind label %middle.end
390 middle.catch:
391 catchret %m to label %exit
392 middle.end:
393 catchendpad unwind label %right
394 right:
395 %r = cleanuppad []
396 br label %shared
397 shared:
398 %x = call i32 @g()
399 invoke void @f()
400 to label %shared.cont unwind label %inner
401 shared.cont:
402 unreachable
403 inner:
404 catchpad []
405 to label %inner.catch unwind label %inner.end
406 inner.catch:
407 call void @h(i32 %x)
408 unreachable
409 inner.end:
410 catchendpad unwind label %left.end
411 exit:
412 ret void
413 }
414 ; This is like @test5 but it inserts another sibling between %left and %right.
415 ; In this case %left, %middle and %right are all siblings, while %left and
416 ; %right are both parents of %inner. This checks the proper handling of the
417 ; catchendpad in %inner.end (which will be cloned so that %left and %right both
418 ; have copies) unwinding to a catchendpad that unwinds to a sibling.
419 ; CHECK-LABEL: define void @test6(
420 ; CHECK: left:
421 ; CHECK: catchpad []
422 ; CHECK: to label %left.catch unwind label %[[LEFT_END:.+]]
423 ; CHECK: left.catch:
424 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
425 ; CHECK: [[LEFT_END]]:
426 ; CHECK: catchendpad unwind label %middle
427 ; CHECK: middle:
428 ; CHECK: catchpad []
429 ; CHECK: to label %middle.catch unwind label %middle.end
430 ; CHECK: middle.catch:
431 ; CHECK: catchret %m to label %exit
432 ; CHECK: middle.end:
433 ; CHECK: catchendpad unwind label %right
434 ; CHECK: right:
435 ; CHECK: %r = cleanuppad []
436 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
437 ; CHECK: [[SHARED_CONT_RIGHT]]:
438 ; CHECK: unreachable
439 ; CHECK: [[SHARED_CONT_LEFT]]:
440 ; CHECK: unreachable
441 ; CHECK: [[INNER_RIGHT]]:
442 ; CHECK: catchpad []
443 ; CHECK: to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
444 ; CHECK: [[INNER_LEFT]]:
445 ; CHECK: catchpad []
446 ; CHECK: to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
447 ; CHECK: [[INNER_CATCH_RIGHT]]:
448 ; CHECK: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot
449 ; CHECK: call void @h(i32 [[X_RELOAD_R]])
450 ; CHECK: unreachable
451 ; CHECK: [[INNER_CATCH_LEFT]]:
452 ; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot
453 ; CHECK: call void @h(i32 [[X_RELOAD_L]])
454 ; CHECK: unreachable
455 ; CHECK: [[INNER_END_LEFT]]:
456 ; CHECK: catchendpad unwind label %[[LEFT_END]]
457 ; CHECK: [[INNER_END_RIGHT]]:
458 ; CHECK: catchendpad unwind to caller
459
460
461 define void @test7() personality i32 (...)* @__CxxFrameHandler3 {
462 entry:
463 invoke void @f()
464 to label %exit unwind label %left
465 left:
466 catchpad []
467 to label %left.catch unwind label %left.end
468 left.catch:
469 br label %shared
470 left.end:
471 catchendpad unwind label %right
472 right:
473 %r = cleanuppad []
474 br label %shared
475 shared:
476 %x = call i32 @g()
477 invoke void @f()
478 to label %shared.cont unwind label %inner
479 shared.cont:
480 unreachable
481 inner:
482 catchpad []
483 to label %inner.catch unwind label %inner.end
484 inner.catch:
485 call void @h(i32 %x)
486 unreachable
487 inner.end:
488 catchendpad unwind label %inner.sibling
489 inner.sibling:
490 %is = cleanuppad []
491 call void @h(i32 0)
492 cleanupret %is unwind label %left.end
493 exit:
494 ret void
495 }
496 ; This is like @test5 but instead of unwinding to %left.end, the catchendpad
497 ; in %inner.end unwinds to a sibling cleanup pad. Both %inner (along with its
498 ; associated blocks) and %inner.sibling must be cloned for %left and %right.
499 ; The clones of %inner will be identical, but the copy of %inner.sibling for
500 ; %right must end with an unreachable instruction, because it cannot unwind to
501 ; %left.end.
502 ; CHECK-LABEL: define void @test7(
503 ; CHECK: left:
504 ; CHECK: catchpad []
505 ; CHECK: to label %left.catch unwind label %[[LEFT_END:.+]]
506 ; CHECK: left.catch:
507 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
508 ; CHECK: [[LEFT_END]]:
509 ; CHECK: catchendpad unwind label %[[RIGHT:.+]]
510 ; CHECK: [[RIGHT]]:
511 ; CHECK: [[R:\%.+]] = cleanuppad []
512 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
513 ; CHECK: [[SHARED_CONT_RIGHT]]:
514 ; CHECK: unreachable
515 ; CHECK: [[SHARED_CONT_LEFT]]:
516 ; CHECK: unreachable
517 ; CHECK: [[INNER_RIGHT]]:
518 ; CHECK: catchpad []
519 ; CHECK: to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
520 ; CHECK: [[INNER_LEFT]]:
521 ; CHECK: catchpad []
522 ; CHECK: to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
523 ; CHECK: [[INNER_CATCH_RIGHT]]:
524 ; CHECK: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot
525 ; CHECK: call void @h(i32 [[X_RELOAD_R]])
526 ; CHECK: unreachable
527 ; CHECK: [[INNER_CATCH_LEFT]]:
528 ; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot
529 ; CHECK: call void @h(i32 [[X_RELOAD_L]])
530 ; CHECK: unreachable
531 ; CHECK: [[INNER_END_LEFT]]:
532 ; CHECK: catchendpad unwind label %[[INNER_SIBLING_LEFT:.+]]
533 ; CHECK: [[INNER_END_RIGHT]]:
534 ; CHECK: catchendpad unwind label %[[INNER_SIBLING_RIGHT:.+]]
535 ; CHECK: [[INNER_SIBLING_RIGHT]]
536 ; CHECK: [[IS_R:\%.+]] = cleanuppad []
537 ; CHECK: call void @h(i32 0)
538 ; CHECK: unreachable
539 ; CHECK: [[INNER_SIBLING_LEFT]]
540 ; CHECK: [[IS_L:\%.+]] = cleanuppad []
541 ; CHECK: call void @h(i32 0)
542 ; CHECK: cleanupret [[IS_L]] unwind label %[[LEFT_END]]
543
544
545 define void @test8() personality i32 (...)* @__CxxFrameHandler3 {
546 entry:
547 invoke void @f()
548 to label %invoke.cont unwind label %left
549 invoke.cont:
550 invoke void @f()
551 to label %unreachable unwind label %right
552 left:
553 cleanuppad []
554 invoke void @f() to label %unreachable unwind label %inner
555 right:
556 catchpad []
557 to label %right.catch unwind label %right.end
558 right.catch:
559 invoke void @f() to label %unreachable unwind label %inner
560 right.end:
561 catchendpad unwind to caller
562 inner:
563 %i = cleanuppad []
564 %x = call i32 @g()
565 call void @h(i32 %x)
566 cleanupret %i unwind label %right.end
567 unreachable:
568 unreachable
569 }
570 ; Another case of a two-parent child (like @test1), this time
571 ; with the join at the entry itself instead of following a
572 ; non-pad join.
573 ; CHECK-LABEL: define void @test8(
574 ; CHECK: invoke.cont:
575 ; CHECK: to label %[[UNREACHABLE_ENTRY:.+]] unwind label %right
576 ; CHECK: left:
577 ; CHECK: to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
578 ; CHECK: right:
579 ; CHECK: to label %right.catch unwind label %right.end
580 ; CHECK: right.catch:
581 ; CHECK: to label %unreachable unwind label %[[INNER_RIGHT:.+]]
582 ; CHECK: right.end:
583 ; CHECK: catchendpad unwind to caller
584 ; CHECK: [[INNER_RIGHT]]:
585 ; CHECK: [[I_R:\%.+]] = cleanuppad []
586 ; CHECK: [[X_R:\%.+]] = call i32 @g()
587 ; CHECK: call void @h(i32 [[X_R]])
588 ; CHECK: cleanupret [[I_R]] unwind label %right.end
589 ; CHECK: [[INNER_LEFT]]:
590 ; CHECK: [[I_L:\%.+]] = cleanuppad []
591 ; CHECK: [[X_L:\%.+]] = call i32 @g()
592 ; CHECK: call void @h(i32 [[X_L]])
593 ; CHECK: unreachable
594 ; CHECK: unreachable:
595 ; CHECK: unreachable
596 ; CHECK: [[UNREACHABLE_LEFT]]:
597 ; CHECK: unreachable
598 ; CHECK: [[UNREACHABLE_ENTRY]]:
599 ; CHECK: unreachable
600
601
602 define void @test9() personality i32 (...)* @__CxxFrameHandler3 {
603 entry:
604 invoke void @f()
605 to label %invoke.cont unwind label %left
606 invoke.cont:
607 invoke void @f()
608 to label %unreachable unwind label %right
609 left:
610 cleanuppad []
611 br label %shared
612 right:
613 catchpad []
614 to label %right.catch unwind label %right.end
615 right.catch:
616 br label %shared
617 right.end:
618 catchendpad unwind to caller
619 shared:
620 invoke void @f()
621 to label %unreachable unwind label %inner
622 inner:
623 cleanuppad []
624 invoke void @f()
625 to label %unreachable unwind label %inner.child
626 inner.child:
627 cleanuppad []
628 %x = call i32 @g()
629 call void @h(i32 %x)
630 unreachable
631 unreachable:
632 unreachable
633 }
634 ; %inner is a two-parent child which itself has a child; need
635 ; to make two copies of both the %inner and %inner.child.
636 ; CHECK-LABEL: define void @test9(
637 ; CHECK: invoke.cont:
638 ; CHECK: to label %[[UNREACHABLE_ENTRY:.+]] unwind label %right
639 ; CHECK: left:
640 ; CHECK: to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
641 ; CHECK: right:
642 ; CHECK: to label %right.catch unwind label %right.end
643 ; CHECK: right.catch:
644 ; CHECK: to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
645 ; CHECK: right.end:
646 ; CHECK: catchendpad unwind to caller
647 ; CHECK: [[INNER_RIGHT]]:
648 ; CHECK: to label %[[UNREACHABLE_INNER_RIGHT:.+]] unwind label %[[INNER_CHILD_RIGHT:.+]]
649 ; CHECK: [[INNER_LEFT]]:
650 ; CHECK: to label %[[UNREACHABLE_INNER_LEFT:.+]] unwind label %[[INNER_CHILD_LEFT:.+]]
651 ; CHECK: [[INNER_CHILD_RIGHT]]:
652 ; CHECK: [[TMP:\%.+]] = cleanuppad []
653 ; CHECK: [[X:\%.+]] = call i32 @g()
654 ; CHECK: call void @h(i32 [[X]])
655 ; CHECK: unreachable
656 ; CHECK: [[INNER_CHILD_LEFT]]:
657 ; CHECK: [[TMP:\%.+]] = cleanuppad []
658 ; CHECK: [[X:\%.+]] = call i32 @g()
659 ; CHECK: call void @h(i32 [[X]])
660 ; CHECK: unreachable
661 ; CHECK: [[UNREACHABLE_INNER_RIGHT]]:
662 ; CHECK: unreachable
663 ; CHECK: [[UNREACHABLE_INNER_LEFT]]:
664 ; CHECK: unreachable
665 ; CHECK: [[UNREACHABLE_RIGHT]]:
666 ; CHECK: unreachable
667 ; CHECK: [[UNREACHABLE_LEFT]]:
668 ; CHECK: unreachable
669 ; CHECK: [[UNREACHABLE_ENTRY]]:
670 ; CHECK: unreachable
671
672
673 define void @test10() personality i32 (...)* @__CxxFrameHandler3 {
674 entry:
675 invoke void @f()
676 to label %invoke.cont unwind label %left
677 invoke.cont:
678 invoke void @f()
679 to label %unreachable unwind label %right
680 left:
681 cleanuppad []
682 call void @h(i32 1)
683 invoke void @f()
684 to label %unreachable unwind label %right
685 right:
686 cleanuppad []
687 call void @h(i32 2)
688 invoke void @f()
689 to label %unreachable unwind label %left
690 unreachable:
691 unreachable
692 }
693 ; This is an irreducible loop with two funclets that enter each other;
694 ; need to make two copies of each funclet (one a child of root, the
695 ; other a child of the opposite funclet), but also make sure not to
696 ; clone self-descendants (if we tried to do that we'd need to make an
697 ; infinite number of them). Presumably if optimizations ever generated
698 ; such a thing it would mean that one of the two cleanups was originally
699 ; the parent of the other, but that we'd somehow lost track in the CFG
700 ; of which was which along the way; generating each possibility lets
701 ; whichever case was correct execute correctly.
702 ; CHECK-LABEL: define void @test10(
703 ; CHECK: entry:
704 ; CHECK: to label %invoke.cont unwind label %[[LEFT:.+]]
705 ; CHECK: invoke.cont:
706 ; CHECK: to label %[[UNREACHABLE_ENTRY:.+]] unwind label %[[RIGHT:.+]]
707 ; CHECK: [[LEFT_FROM_RIGHT:.+]]:
708 ; CHECK: call void @h(i32 1)
709 ; CHECK: call void @f()
710 ; CHECK: unreachable
711 ; CHECK: [[LEFT]]:
712 ; CHECK: call void @h(i32 1)
713 ; CHECK: invoke void @f()
714 ; CHECK: to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[RIGHT_FROM_LEFT:.+]]
715 ; CHECK: [[RIGHT]]:
716 ; CHECK: call void @h(i32 2)
717 ; CHECK: invoke void @f()
718 ; CHECK: to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[LEFT_FROM_RIGHT]]
719 ; CHECK: [[RIGHT_FROM_LEFT]]:
720 ; CHECK: call void @h(i32 2)
721 ; CHECK: call void @f()
722 ; CHECK: unreachable
723 ; CHECK: [[UNREACHABLE_RIGHT]]:
724 ; CHECK: unreachable
725 ; CHECK: [[UNREACHABLE_LEFT]]:
726 ; CHECK: unreachable
727 ; CHECK: [[UNREACHABLE_ENTRY]]:
728 ; CHECK: unreachable
729
730
731 define void @test11() personality i32 (...)* @__CxxFrameHandler3 {
732 entry:
733 invoke void @f()
734 to label %exit unwind label %left
735 left:
736 catchpad []
737 to label %left.catch unwind label %left.sibling
738 left.catch:
739 br label %shared
740 left.sibling:
741 %ls = catchpad []
742 to label %left.sibling.catch unwind label %left.end
743 left.sibling.catch:
744 catchret %ls to label %exit
745 left.end:
746 catchendpad unwind label %right
747 right:
748 catchpad []
749 to label %right.catch unwind label %right.end
750 right.catch:
751 br label %shared
752 right.end:
753 catchendpad unwind to caller
754 shared:
755 %x = call i32 @g()
756 invoke void @f()
757 to label %shared.cont unwind label %inner
758 shared.cont:
759 unreachable
760 inner:
761 catchpad []
762 to label %inner.catch unwind label %inner.end
763 inner.catch:
764 call void @h(i32 %x)
765 unreachable
766 inner.end:
767 catchendpad unwind label %left.end
768 exit:
769 ret void
770 }
771 ; This is a variation of @test4 in which the shared child funclet unwinds to a
772 ; catchend pad that is the unwind destination of %left.sibling rather than %left
773 ; but is still a valid destination for %inner as reach from %left.
774 ; When %inner is cloned a copy of %inner.end will be made for both %left and
775 ; %right, but because the catchpad in %right does not unwind to %left.end the
776 ; unwind edge from the copy of %inner.end for %right must be removed.
777 ; CHECK-LABEL: define void @test11(
778 ; CHECK: left:
779 ; CHECK: catchpad []
780 ; CHECK: to label %left.catch unwind label %left.sibling
781 ; CHECK: left.catch:
782 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
783 ; CHECK: left.sibling:
784 ; CHECK: catchpad []
785 ; CHECK: to label %left.sibling.catch unwind label %[[LEFT_END:.+]]
786 ; CHECK: [[LEFT_END]]:
787 ; CHECK: catchendpad unwind label %right
788 ; CHECK: right:
789 ; CHECK: to label %right.catch unwind label %[[RIGHT_END:.+]]
790 ; CHECK: right.catch:
791 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
792 ; CHECK: [[RIGHT_END]]:
793 ; CHECK: catchendpad unwind to caller
794 ; CHECK: [[SHARED_CONT_RIGHT]]:
795 ; CHECK: unreachable
796 ; CHECK: [[SHARED_CONT_LEFT]]:
797 ; CHECK: unreachable
798 ; CHECK: [[INNER_RIGHT]]:
799 ; CHECK: catchpad []
800 ; CHECK: to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
801 ; CHECK: [[INNER_LEFT]]:
802 ; CHECK: catchpad []
803 ; CHECK: to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
804 ; CHECK: [[INNER_CATCH_RIGHT]]:
805 ; CHECK: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot
806 ; CHECK: call void @h(i32 [[X_RELOAD_R]])
807 ; CHECK: unreachable
808 ; CHECK: [[INNER_CATCH_LEFT]]:
809 ; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot
810 ; CHECK: call void @h(i32 [[X_RELOAD_L]])
811 ; CHECK: unreachable
812 ; CHECK: [[INNER_END_LEFT]]:
813 ; CHECK: catchendpad unwind label %[[LEFT_END]]
814 ; CHECK: [[INNER_END_RIGHT]]:
815 ; CHECK: catchendpad unwind to caller
816
817
818 define void @test12() personality i32 (...)* @__CxxFrameHandler3 {
819 entry:
820 invoke void @f()
821 to label %exit unwind label %left
822 left:
823 catchpad []
824 to label %left.catch unwind label %right
825 left.catch:
826 br label %shared
827 right:
828 catchpad []
829 to label %right.catch unwind label %right.end
830 right.catch:
831 br label %shared
832 right.end:
833 catchendpad unwind to caller
834 shared:
835 %x = call i32 @g()
836 invoke void @f()
837 to label %shared.cont unwind label %inner
838 shared.cont:
839 unreachable
840 inner:
841 catchpad []
842 to label %inner.catch unwind label %inner.end
843 inner.catch:
844 call void @h(i32 %x)
845 unreachable
846 inner.end:
847 catchendpad unwind label %right.end
848 exit:
849 ret void
850 }
851 ; In this case %left and %right are both parents of %inner, so %inner must be
852 ; cloned but the catchendpad unwind target in %inner.end is valid for both
853 ; parents, so the unwind edge should not be removed in either case.
854 ; CHECK-LABEL: define void @test12(
855 ; CHECK: left:
856 ; CHECK: catchpad []
857 ; CHECK: to label %left.catch unwind label %right
858 ; CHECK: left.catch:
859 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
860 ; CHECK: right:
861 ; CHECK: to label %right.catch unwind label %[[RIGHT_END:.+]]
862 ; CHECK: right.catch:
863 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
864 ; CHECK: [[RIGHT_END]]:
865 ; CHECK: catchendpad unwind to caller
866 ; CHECK: [[SHARED_CONT_RIGHT]]:
867 ; CHECK: unreachable
868 ; CHECK: [[SHARED_CONT_LEFT]]:
869 ; CHECK: unreachable
870 ; CHECK: [[INNER_RIGHT]]:
871 ; CHECK: catchpad []
872 ; CHECK: to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
873 ; CHECK: [[INNER_LEFT]]:
874 ; CHECK: catchpad []
875 ; CHECK: to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
876 ; CHECK: [[INNER_CATCH_RIGHT]]:
877 ; CHECK: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot
878 ; CHECK: call void @h(i32 [[X_RELOAD_R]])
879 ; CHECK: unreachable
880 ; CHECK: [[INNER_CATCH_LEFT]]:
881 ; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot
882 ; CHECK: call void @h(i32 [[X_RELOAD_L]])
883 ; CHECK: unreachable
884 ; CHECK: [[INNER_END_LEFT]]:
885 ; CHECK: catchendpad unwind label %[[RIGHT_END]]
886 ; CHECK: [[INNER_END_RIGHT]]:
887 ; CHECK: catchendpad unwind label %[[RIGHT_END]]
888
889 define void @test13() personality i32 (...)* @__CxxFrameHandler3 {
890 entry:
891 invoke void @f()
892 to label %invoke.cont unwind label %left
893 invoke.cont:
894 invoke void @f()
895 to label %exit unwind label %right
896 left:
897 %l = catchpad []
898 to label %left.cont unwind label %left.end
899 left.cont:
900 invoke void @f()
901 to label %left.ret unwind label %inner
902 left.ret:
903 catchret %l to label %invoke.cont
904 left.end:
905 catchendpad unwind to caller
906 right:
907 %r = catchpad []
908 to label %right.catch unwind label %right.end
909 right.catch:
910 invoke void @f()
911 to label %right.ret unwind label %inner
912 right.ret:
913 catchret %r to label %exit
914 right.end:
915 catchendpad unwind to caller
916 shared:
917 call void @h(i32 0)
918 unreachable
919 inner:
920 %i = catchpad []
921 to label %inner.catch unwind label %inner.end
922 inner.catch:
923 call void @h(i32 1)
924 catchret %i to label %shared
925 inner.end:
926 catchendpad unwind label %left.end
927 exit:
928 ret void
929 }
930 ; This case tests the scenario where a funclet with multiple parents uses a
931 ; catchret to return to a block that may exist in either parent funclets.
932 ; Both %left and %right are parents of %inner. During common block cloning
933 ; a clone of %shared will be made so that both %left and %right have a copy,
934 ; but the copy of %shared for one of the parent funclets will be unreachable
935 ; until the %inner funclet is cloned. When the %inner.catch block is cloned
936 ; during the %inner funclet cloning, the catchret instruction should be updated
937 ; so that the catchret in the copy %inner.catch for %left returns to the copy of
938 ; %shared in %left and the catchret in the copy of %inner.catch for %right
939 ; returns to the copy of %shared for %right.
940 ; CHECK-LABEL: define void @test13(
941 ; CHECK: left:
942 ; CHECK: %l = catchpad []
943 ; CHECK: to label %left.cont unwind label %left.end
944 ; CHECK: left.cont:
945 ; CHECK: invoke void @f()
946 ; CHECK: to label %left.ret unwind label %[[INNER_LEFT:.+]]
947 ; CHECK: left.ret:
948 ; CHECK: catchret %l to label %invoke.cont
949 ; CHECK: left.end:
950 ; CHECK: catchendpad unwind to caller
951 ; CHECK: right:
952 ; CHECK: %r = catchpad []
953 ; CHECK: to label %right.catch unwind label %right.end
954 ; CHECK: right.catch:
955 ; CHECK: invoke void @f()
956 ; CHECK: to label %right.ret unwind label %[[INNER_RIGHT:.+]]
957 ; CHECK: right.ret:
958 ; CHECK: catchret %r to label %exit
959 ; CHECK: right.end:
960 ; CHECK: catchendpad unwind to caller
961 ; CHECK: [[SHARED_RIGHT:.+]]:
962 ; CHECK: call void @h(i32 0)
963 ; CHECK: unreachable
964 ; CHECK: [[SHARED_LEFT:.+]]:
965 ; CHECK: call void @h(i32 0)
966 ; CHECK: unreachable
967 ; CHECK: [[INNER_RIGHT]]:
968 ; CHECK: %[[I_RIGHT:.+]] = catchpad []
969 ; CHECK: to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
970 ; CHECK: [[INNER_LEFT]]:
971 ; CHECK: %[[I_LEFT:.+]] = catchpad []
972 ; CHECK: to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
973 ; CHECK: [[INNER_CATCH_RIGHT]]:
974 ; CHECK: call void @h(i32 1)
975 ; CHECK: catchret %[[I_RIGHT]] to label %[[SHARED_RIGHT]]
976 ; CHECK: [[INNER_CATCH_LEFT]]:
977 ; CHECK: call void @h(i32 1)
978 ; CHECK: catchret %[[I_LEFT]] to label %[[SHARED_LEFT]]
979 ; CHECK: [[INNER_END_LEFT]]:
980 ; CHECK: catchendpad unwind label %[[LEFT_END]]
981 ; CHECK: [[INNER_END_RIGHT]]:
982 ; CHECK: catchendpad unwind to caller
983
984
985 define void @test14() personality i32 (...)* @__CxxFrameHandler3 {
986 entry:
987 invoke void @f()
988 to label %exit unwind label %left
989 left:
990 %l = catchpad []
991 to label %shared unwind label %left.end
992 left.cont:
993 invoke void @f()
994 to label %left.ret unwind label %right
995 left.ret:
996 catchret %l to label %exit
997 left.end:
998 catchendpad unwind to caller
999 right:
1000 catchpad []
1001 to label %right.catch unwind label %right.end
1002 right.catch:
1003 br label %shared
1004 right.end:
1005 catchendpad unwind label %left.end
1006 shared:
1007 invoke void @f()
1008 to label %shared.cont unwind label %inner
1009 shared.cont:
1010 unreachable
1011 inner:
1012 %i = catchpad []
1013 to label %inner.catch unwind label %inner.end
1014 inner.catch:
1015 call void @h(i32 0)
1016 catchret %i to label %left.cont
1017 inner.end:
1018 catchendpad unwind label %left.end
1019 exit:
1020 ret void
1021 }
1022 ; This case tests another scenario where a funclet with multiple parents uses a
1023 ; catchret to return to a block in one of the parent funclets. Here %right and
1024 ; %left are both parents of %inner and %left is a parent of %right. The
1025 ; catchret in %inner.catch will cause %left.cont and %left.ret to be cloned for
1026 ; both %left and %right, but the catchret in %left.ret is invalid for %right
1027 ; but the catchret instruction in the copy of %left.ret for %right will be
1028 ; removed as an implausible terminator.
1029 ; CHECK-LABEL: define void @test14(
1030 ; CHECK: left:
1031 ; CHECK: %l = catchpad []
1032 ; CHECK: to label %[[SHARED_LEFT:.+]] unwind label %[[LEFT_END:.+]]
1033 ; CHECK: [[LEFT_CONT:left.cont.*]]:
1034 ; CHECK: invoke void @f()
1035 ; CHECK: to label %[[LEFT_RET:.+]] unwind label %[[RIGHT:.+]]
1036 ; CHECK: [[LEFT_RET]]:
1037 ; CHECK: catchret %l to label %exit
1038 ; CHECK: [[LEFT_END]]:
1039 ; CHECK: catchendpad unwind to caller
1040 ; CHECK: [[RIGHT]]:
1041 ; CHECK: catchpad []
1042 ; CHECK: to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
1043 ; CHECK: [[RIGHT_CATCH]]:
1044 ; CHECK: invoke void @f()
1045 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
1046 ; CHECK: [[RIGHT_END]]:
1047 ; CHECK: catchendpad unwind label %[[LEFT_END]]
1048 ; CHECK: [[SHARED_LEFT]]:
1049 ; CHECK: invoke void @f()
1050 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
1051 ; CHECK: [[SHARED_CONT_RIGHT]]:
1052 ; CHECK: unreachable
1053 ; CHECK: [[SHARED_CONT_LEFT]]:
1054 ; CHECK: unreachable
1055 ; CHECK: [[INNER_LEFT]]:
1056 ; CHECK: [[I_LEFT:\%.+]] = catchpad []
1057 ; CHECK: to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
1058 ; CHECK: [[INNER_RIGHT]]:
1059 ; CHECK: [[I_RIGHT:\%.+]] = catchpad []
1060 ; CHECK: to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
1061 ; CHECK: [[INNER_CATCH_LEFT]]:
1062 ; CHECK: call void @h(i32 0)
1063 ; CHECK: catchret [[I_LEFT]] to label %[[LEFT_CONT]]
1064 ; CHECK: [[INNER_CATCH_RIGHT]]:
1065 ; CHECK: call void @h(i32 0)
1066 ; CHECK: unreachable
1067 ; CHECK: [[INNER_END_LEFT]]:
1068 ; CHECK: catchendpad unwind label %[[LEFT_END]]
1069 ; CHECK: [[INNER_END_RIGHT]]:
1070 ; CHECK: catchendpad unwind to caller
1071
1072 define void @test15() personality i32 (...)* @__CxxFrameHandler3 {
1073 entry:
1074 invoke void @f()
1075 to label %exit unwind label %left
1076 left:
1077 %l = catchpad []
1078 to label %left.catch unwind label %left.end
1079 left.catch:
1080 invoke void @f()
1081 to label %shared unwind label %right
1082 left.ret:
1083 catchret %l to label %exit
1084 left.end:
1085 catchendpad unwind to caller
1086 right:
1087 catchpad []
1088 to label %right.catch unwind label %right.end
1089 right.catch:
1090 br label %shared
1091 right.end:
1092 catchendpad unwind label %left.end
1093 shared:
1094 invoke void @f()
1095 to label %shared.cont unwind label %inner
1096 shared.cont:
1097 unreachable
1098 inner:
1099 %i = catchpad []
1100 to label %inner.catch unwind label %inner.end
1101 inner.catch:
1102 call void @h(i32 0)
1103 catchret %i to label %left.ret
1104 inner.end:
1105 catchendpad unwind label %left.end
1106 exit:
1107 ret void
1108 }
1109 ; This case is a variation of test14 but instead of returning to an invoke the
1110 ; catchret in %inner.catch returns to a catchret instruction.
1111 ; CHECK-LABEL: define void @test15(
1112 ; CHECK: left:
1113 ; CHECK: %l = catchpad []
1114 ; CHECK: to label %left.catch unwind label %[[LEFT_END:.+]]
1115 ; CHECK: left.catch:
1116 ; CHECK: invoke void @f()
1117 ; CHECK: to label %[[SHARED_LEFT:.+]] unwind label %[[RIGHT:.+]]
1118 ; CHECK: [[LEFT_RET_RIGHT:.+]]:
1119 ; CHECK: unreachable
1120 ; CHECK: [[LEFT_RET_LEFT:.+]]:
1121 ; CHECK: catchret %l to label %exit
1122 ; CHECK: [[LEFT_END]]:
1123 ; CHECK: catchendpad unwind to caller
1124 ; CHECK: [[RIGHT]]:
1125 ; CHECK: catchpad []
1126 ; CHECK: to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
1127 ; CHECK: [[RIGHT_CATCH]]:
1128 ; CHECK: invoke void @f()
1129 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
1130 ; CHECK: [[RIGHT_END]]:
1131 ; CHECK: catchendpad unwind label %[[LEFT_END]]
1132 ; CHECK: [[SHARED_LEFT]]:
1133 ; CHECK: invoke void @f()
1134 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
1135 ; CHECK: [[SHARED_CONT_RIGHT]]:
1136 ; CHECK: unreachable
1137 ; CHECK: [[SHARED_CONT_LEFT]]:
1138 ; CHECK: unreachable
1139 ; CHECK: [[INNER_LEFT]]:
1140 ; CHECK: [[I_LEFT:\%.+]] = catchpad []
1141 ; CHECK: to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
1142 ; CHECK: [[INNER_RIGHT]]:
1143 ; CHECK: [[I_RIGHT:\%.+]] = catchpad []
1144 ; CHECK: to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
1145 ; CHECK: [[INNER_CATCH_LEFT]]:
1146 ; CHECK: call void @h(i32 0)
1147 ; CHECK: catchret [[I_LEFT]] to label %[[LEFT_RET_LEFT]]
1148 ; CHECK: [[INNER_CATCH_RIGHT]]:
1149 ; CHECK: call void @h(i32 0)
1150 ; CHECK: catchret [[I_RIGHT]] to label %[[LEFT_RET_RIGHT]]
1151 ; CHECK: [[INNER_END_LEFT]]:
1152 ; CHECK: catchendpad unwind label %[[LEFT_END]]
1153 ; CHECK: [[INNER_END_RIGHT]]:
1154 ; CHECK: catchendpad unwind to caller
1155
1156
1157 define void @test16() personality i32 (...)* @__CxxFrameHandler3 {
1158 entry:
1159 invoke void @f()
1160 to label %exit unwind label %left
1161 left:
1162 %l = cleanuppad []
1163 br label %shared
1164 left.cont:
1165 cleanupret %l unwind label %right
1166 left.end:
1167 cleanupendpad %l unwind label %right
1168 right:
1169 catchpad []
1170 to label %right.catch unwind label %right.end
1171 right.catch:
1172 br label %shared
1173 right.end:
1174 catchendpad unwind to caller
1175 shared:
1176 invoke void @f()
1177 to label %shared.cont unwind label %inner
1178 shared.cont:
1179 unreachable
1180 inner:
1181 %i = catchpad []
1182 to label %inner.catch unwind label %inner.end
1183 inner.catch:
1184 call void @h(i32 0)
1185 catchret %i to label %left.cont
1186 inner.end:
1187 catchendpad unwind label %left.end
1188 exit:
1189 ret void
1190 }
1191 ; This case is another variation of test14 but here the catchret in %inner.catch
1192 ; returns to a cleanupret instruction.
1193 ; CHECK-LABEL: define void @test16(
1194 ; CHECK: left:
1195 ; CHECK: %l = cleanuppad []
1196 ; CHECK: invoke void @f()
1197 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
1198 ; CHECK: [[LEFT_CONT_RIGHT:.+]]:
1199 ; CHECK: unreachable
1200 ; CHECK: [[LEFT_CONT_LEFT:.+]]:
1201 ; CHECK: cleanupret %l unwind label %[[RIGHT:.+]]
1202 ; CHECK: [[LEFT_END_LEFT:.+]]:
1203 ; CHECK: cleanupendpad %l unwind label %[[RIGHT]]
1204 ; CHECK: [[RIGHT]]:
1205 ; CHECK: catchpad []
1206 ; CHECK: to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
1207 ; CHECK: [[RIGHT_CATCH]]:
1208 ; CHECK: invoke void @f()
1209 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
1210 ; CHECK: [[RIGHT_END]]:
1211 ; CHECK: catchendpad unwind to caller
1212 ; CHECK: [[SHARED_CONT_RIGHT]]:
1213 ; CHECK: unreachable
1214 ; CHECK: [[SHARED_CONT_LEFT]]:
1215 ; CHECK: unreachable
1216 ; CHECK: [[INNER_RIGHT]]:
1217 ; CHECK: [[I_RIGHT:\%.+]] = catchpad []
1218 ; CHECK: to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
1219 ; CHECK: [[INNER_LEFT]]:
1220 ; CHECK: [[I_LEFT:\%.+]] = catchpad []
1221 ; CHECK: to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
1222 ; CHECK: [[INNER_CATCH_RIGHT]]:
1223 ; CHECK: call void @h(i32 0)
1224 ; CHECK: catchret [[I_RIGHT]] to label %[[LEFT_CONT_RIGHT]]
1225 ; CHECK: [[INNER_CATCH_LEFT]]:
1226 ; CHECK: call void @h(i32 0)
1227 ; CHECK: catchret [[I_LEFT]] to label %[[LEFT_CONT_LEFT]]
1228 ; CHECK: [[INNER_END_LEFT]]:
1229 ; CHECK: catchendpad unwind label %[[LEFT_END_LEFT]]
1230 ; CHECK: [[INNER_END_RIGHT]]:
1231 ; CHECK: catchendpad unwind to caller
1232
1233
1234 define void @test17() personality i32 (...)* @__CxxFrameHandler3 {
1235 entry:
1236 invoke void @f()
1237 to label %invoke.cont unwind label %left
1238 invoke.cont:
1239 invoke void @f()
1240 to label %exit unwind label %right
1241 left:
1242 %l = cleanuppad []
1243 br label %shared
1244 right:
1245 catchpad []
1246 to label %right.catch unwind label %right.end
1247 right.catch:
1248 br label %shared
1249 right.end:
1250 catchendpad unwind to caller
1251 shared:
1252 invoke void @f()
1253 to label %unreachable unwind label %inner
1254 unreachable:
1255 unreachable
1256 inner:
1257 %i = catchpad []
1258 to label %inner.catch unwind label %inner.sibling
1259 inner.catch:
1260 call void @h(i32 0)
1261 unreachable
1262 inner.sibling:
1263 %is = catchpad []
1264 to label %inner.sibling.catch unwind label %inner.end
1265 inner.sibling.catch:
1266 invoke void @f()
1267 to label %unreachable unwind label %inner.end
1268 inner.end:
1269 catchendpad unwind label %right.end
1270 exit:
1271 ret void
1272 }
1273 ; This case tests the scenario where two catchpads with the same catchendpad
1274 ; have multiple parents. Both %left and %right are parents of %inner and
1275 ; %inner.sibling so both of the inner funclets must be cloned. Because
1276 ; the catchendpad in %inner.end unwinds to the catchendpad for %right, the
1277 ; unwind edge should be removed for the copy of %inner.end that is reached
1278 ; from %left. In addition, the %inner.siblin.catch block contains an invoke
1279 ; that unwinds to the shared inner catchendpad. The unwind destination for
1280 ; this invoke should be updated to unwind to the correct cloned %inner.end
1281 ; for each path to the funclet.
1282 ; CHECK-LABEL: define void @test17(
1283 ; CHECK: left:
1284 ; CHECK: %l = cleanuppad []
1285 ; CHECK: invoke void @f()
1286 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
1287 ; CHECK: right:
1288 ; CHECK: catchpad []
1289 ; CHECK: to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
1290 ; CHECK: [[RIGHT_CATCH]]:
1291 ; CHECK: invoke void @f()
1292 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
1293 ; CHECK: [[RIGHT_END]]:
1294 ; CHECK: catchendpad unwind to caller
1295 ; CHECK: [[SHARED_CONT_RIGHT]]:
1296 ; CHECK: unreachable
1297 ; CHECK: [[SHARED_CONT_LEFT]]:
1298 ; CHECK: unreachable
1299 ; CHECK: [[INNER_RIGHT]]:
1300 ; CHECK: [[I_RIGHT:\%.+]] = catchpad []
1301 ; CHECK: to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_SIBLING_RIGHT:.+]]
1302 ; CHECK: [[INNER_LEFT]]:
1303 ; CHECK: [[I_LEFT:\%.+]] = catchpad []
1304 ; CHECK: to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_SIBLING_LEFT:.+]]
1305 ; CHECK: [[INNER_CATCH_RIGHT]]:
1306 ; CHECK: call void @h(i32 0)
1307 ; CHECK: unreachable
1308 ; CHECK: [[INNER_CATCH_LEFT]]:
1309 ; CHECK: call void @h(i32 0)
1310 ; CHECK: unreachable
1311 ; CHECK: [[INNER_SIBLING_RIGHT]]:
1312 ; CHECK: [[IS_RIGHT:\%.+]] = catchpad []
1313 ; CHECK: to label %[[INNER_SIBLING_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
1314 ; CHECK: [[INNER_SIBLING_LEFT]]:
1315 ; CHECK: [[IS_LEFT:\%.+]] = catchpad []
1316 ; CHECK: to label %[[INNER_SIBLING_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
1317 ; CHECK: [[INNER_SIBLING_CATCH_RIGHT]]:
1318 ; CHECK: invoke void @f()
1319 ; TODO: Re-enable this check when it is less flaky.
1320 ; to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_END_RIGHT]]
1321 ; CHECK: [[INNER_SIBLING_CATCH_LEFT]]:
1322 ; CHECK: invoke void @f()
1323 ; TODO: Re-enable this check when it is less flaky.
1324 ; to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_END_LEFT]]
1325 ; CHECK: [[INNER_END_LEFT]]:
1326 ; CHECK: catchendpad unwind to caller
1327 ; CHECK: [[INNER_END_RIGHT]]:
1328 ; CHECK: catchendpad unwind label %[[RIGHT_END]]
1329
1330
1331 define void @test18() personality i32 (...)* @__CxxFrameHandler3 {
1332 entry:
1333 invoke void @f()
1334 to label %invoke.cont unwind label %left
1335 invoke.cont:
1336 invoke void @f()
1337 to label %exit unwind label %right
1338 left:
1339 %l = cleanuppad []
1340 br label %shared
1341 right:
1342 catchpad []
1343 to label %right.catch unwind label %right.end
1344 right.catch:
1345 br label %shared
1346 right.end:
1347 catchendpad unwind to caller
1348 shared:
1349 invoke void @f()
1350 to label %unreachable unwind label %inner
1351 unreachable:
1352 unreachable
1353 inner:
1354 %i = catchpad []
1355 to label %inner.catch unwind label %inner.sibling
1356 inner.catch:
1357 invoke void @f()
1358 to label %unreachable unwind label %inner.end
1359 inner.sibling:
1360 %is = catchpad []
1361 to label %inner.sibling.catch unwind label %inner.end
1362 inner.sibling.catch:
1363 call void @h(i32 0)
1364 unreachable
1365 inner.end:
1366 catchendpad unwind label %right.end
1367 exit:
1368 ret void
1369 }
1370 ; This is like test17 except that the inner invoke is moved from the
1371 ; %inner.sibling funclet to %inner so that it is unwinding to a
1372 ; catchendpad block that has not yet been cloned. The unwind destination
1373 ; of the invoke should still be updated to reach the correct copy of
1374 ; %inner.end for the path by which it is reached.
1375 ; CHECK-LABEL: define void @test18(
1376 ; CHECK: left:
1377 ; CHECK: %l = cleanuppad []
1378 ; CHECK: invoke void @f()
1379 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
1380 ; CHECK: right:
1381 ; CHECK: catchpad []
1382 ; CHECK: to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
1383 ; CHECK: [[RIGHT_CATCH]]:
1384 ; CHECK: invoke void @f()
1385 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
1386 ; CHECK: [[RIGHT_END]]:
1387 ; CHECK: catchendpad unwind to caller
1388 ; CHECK: [[SHARED_CONT_RIGHT]]:
1389 ; CHECK: unreachable
1390 ; CHECK: [[SHARED_CONT_LEFT]]:
1391 ; CHECK: unreachable
1392 ; CHECK: [[INNER_RIGHT]]:
1393 ; CHECK: [[I_RIGHT:\%.+]] = catchpad []
1394 ; CHECK: to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_SIBLING_RIGHT:.+]]
1395 ; CHECK: [[INNER_LEFT]]:
1396 ; CHECK: [[I_LEFT:\%.+]] = catchpad []
1397 ; CHECK: to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_SIBLING_LEFT:.+]]
1398 ; CHECK: [[INNER_CATCH_RIGHT]]:
1399 ; CHECK: invoke void @f()
1400 ; CHECK: to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
1401 ; CHECK: [[INNER_CATCH_LEFT]]:
1402 ; CHECK: invoke void @f()
1403 ; CHECK: to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
1404 ; CHECK: [[INNER_SIBLING_RIGHT]]:
1405 ; CHECK: [[IS_RIGHT:\%.+]] = catchpad []
1406 ; TODO: Re-enable this check when it is less flaky.
1407 ; to label %[[INNER_SIBLING_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT]]
1408 ; CHECK: [[INNER_SIBLING_LEFT]]:
1409 ; CHECK: [[IS_LEFT:\%.+]] = catchpad []
1410 ; TODO: Re-enable this check when it is less flaky.
1411 ; to label %[[INNER_SIBLING_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT]]
1412 ; CHECK: [[INNER_SIBLING_CATCH_RIGHT]]:
1413 ; CHECK: call void @h(i32 0)
1414 ; CHECK: unreachable
1415 ; CHECK: [[INNER_SIBLING_CATCH_LEFT]]:
1416 ; CHECK: call void @h(i32 0)
1417 ; CHECK: unreachable
1418 ; CHECK: [[INNER_END_LEFT]]:
1419 ; CHECK: catchendpad unwind to caller
1420 ; CHECK: [[INNER_END_RIGHT]]:
1421 ; CHECK: catchendpad unwind label %[[RIGHT_END]]
1422
1423
1424 define void @test19() personality i32 (...)* @__CxxFrameHandler3 {
1425 entry:
1426 invoke void @f()
1427 to label %invoke.cont unwind label %left
1428 invoke.cont:
1429 invoke void @f()
1430 to label %exit unwind label %right
1431 left:
1432 %l = cleanuppad []
1433 br label %shared
1434 right:
1435 catchpad []
1436 to label %right.catch unwind label %right.end
1437 right.catch:
1438 br label %shared
1439 right.end:
1440 catchendpad unwind to caller
1441 shared:
1442 invoke void @f()
1443 to label %unreachable unwind label %inner
1444 unreachable:
1445 unreachable
1446 inner:
1447 %i = cleanuppad []
1448 invoke void @f()
1449 to label %unreachable unwind label %inner.end
1450 inner.end:
1451 cleanupendpad %i unwind label %right.end
1452 exit:
1453 ret void
1454 }
1455 ; This case tests the scenario where an invoke in a funclet with multiple
1456 ; parents unwinds to a cleanup end pad for the funclet. The unwind destination
1457 ; for the invoke should map to the correct copy of the cleanup end pad block.
1458 ; CHECK-LABEL: define void @test19(
1459 ; CHECK: left:
1460 ; CHECK: %l = cleanuppad []
1461 ; CHECK: invoke void @f()
1462 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
1463 ; CHECK: right:
1464 ; CHECK: catchpad []
1465 ; CHECK: to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
1466 ; CHECK: [[RIGHT_CATCH]]:
1467 ; CHECK: invoke void @f()
1468 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
1469 ; CHECK: [[RIGHT_END]]:
1470 ; CHECK: catchendpad unwind to caller
1471 ; CHECK: [[SHARED_CONT_RIGHT]]:
1472 ; CHECK: unreachable
1473 ; CHECK: [[SHARED_CONT_LEFT]]:
1474 ; CHECK: unreachable
1475 ; CHECK: [[INNER_RIGHT]]:
1476 ; CHECK: [[I_RIGHT:\%.+]] = cleanuppad []
1477 ; CHECK: invoke void @f()
1478 ; CHECK: to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
1479 ; CHECK: [[INNER_LEFT]]:
1480 ; CHECK: [[I_LEFT:\%.+]] = cleanuppad []
1481 ; CHECK: invoke void @f()
1482 ; CHECK: to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
1483 ; CHECK: [[INNER_END_RIGHT]]:
1484 ; CHECK: cleanupendpad [[I_RIGHT]] unwind label %[[RIGHT_END]]
1485 ; CHECK: [[INNER_END_LEFT]]:
1486 ; CHECK: cleanupendpad [[I_LEFT]] unwind to caller
1487
1488 define void @test20() personality i32 (...)* @__CxxFrameHandler3 {
1489 entry:
1490 invoke void @f()
1491 to label %invoke.cont unwind label %left
1492 invoke.cont:
1493 invoke void @f()
1494 to label %exit unwind label %right
1495 left:
1496 %l = cleanuppad []
1497 br label %shared
1498 right:
1499 catchpad []
1500 to label %right.catch unwind label %right.end
1501 right.catch:
1502 br label %shared
1503 right.end:
1504 catchendpad unwind to caller
1505 shared:
1506 invoke void @f()
1507 to label %unreachable unwind label %inner
1508 unreachable:
1509 unreachable
1510 inner:
1511 %i = cleanuppad []
1512 invoke void @f()
1513 to label %unreachable unwind label %inner.cleanup
1514 inner.cleanup:
1515 cleanuppad []
1516 call void @f()
1517 unreachable
1518 exit:
1519 ret void
1520 }
1521 ; This tests the case where a funclet with multiple parents contains an invoke
1522 ; instruction that unwinds to a child funclet. Here %left and %right are both
1523 ; parents of %inner. Initially %inner is the only parent of %inner.cleanup but
1524 ; after %inner is cloned, %inner.cleanup has multiple parents and so it must
1525 ; also be cloned.
1526 ; CHECK-LABEL: define void @test20(
1527 ; CHECK: left:
1528 ; CHECK: %l = cleanuppad []
1529 ; CHECK: invoke void @f()
1530 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
1531 ; CHECK: right:
1532 ; CHECK: catchpad []
1533 ; CHECK: to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
1534 ; CHECK: [[RIGHT_CATCH]]:
1535 ; CHECK: invoke void @f()
1536 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
1537 ; CHECK: [[RIGHT_END]]:
1538 ; CHECK: catchendpad unwind to caller
1539 ; CHECK: [[SHARED_CONT_RIGHT]]:
1540 ; CHECK: unreachable
1541 ; CHECK: [[SHARED_CONT_LEFT]]:
1542 ; CHECK: unreachable
1543 ; CHECK: [[INNER_RIGHT]]:
1544 ; CHECK: [[I_RIGHT:\%.+]] = cleanuppad []
1545 ; CHECK: invoke void @f()
1546 ; CHECK: to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_CLEANUP_RIGHT:.+]]
1547 ; CHECK: [[INNER_LEFT]]:
1548 ; CHECK: [[I_LEFT:\%.+]] = cleanuppad []
1549 ; CHECK: invoke void @f()
1550 ; CHECK: to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_CLEANUP_LEFT:.+]]
1551 ; CHECK: [[INNER_CLEANUP_RIGHT]]:
1552 ; CHECK: cleanuppad []
1553 ; CHECK: call void @f()
1554 ; CHECK: unreachable
1555 ; CHECK: [[INNER_CLEANUP_LEFT]]:
1556 ; CHECK: cleanuppad []
1557 ; CHECK: call void @f()
1558 ; CHECK: unreachable
1559
1560
3838 unreachable
3939
4040 inner:
41 ; CHECK: %phi = phi i32 [ %x, %right ], [ 0, %invoke.cont2 ], [ %x.for.left, %left ]
4142 %phi = phi i32 [ %x, %shared ], [ 0, %invoke.cont2 ]
4243 %i = cleanuppad []
4344 call void @h(i32 %phi)
4445 unreachable
45
46 ; CHECK [[INNER_INVOKE_CONT2:inner.*]]:
47 ; CHECK: call void @h(i32 0)
48
49 ; CHECK [[INNER_RIGHT:inner.*]]:
50 ; CHECK: call void @h(i32 %x)
51
52 ; CHECK [[INNER_LEFT:inner.*]]:
53 ; CHECK: call void @h(i32 %x.for.left)
5446
5547 exit:
5648 unreachable
8375 unreachable
8476
8577 inner:
78 ; CHECK: %x1 = phi i32 [ %x.for.left, %left ], [ %x, %right ]
79 ; CHECK: call void @h(i32 %x1)
8680 %i = cleanuppad []
8781 call void @h(i32 %x)
8882 unreachable
89
90 ; CHECK [[INNER_RIGHT:inner.*]]:
91 ; CHECK: call void @h(i32 %x)
92
93 ; CHECK [[INNER_LEFT:inner.*]]:
94 ; CHECK: call void @h(i32 %x.for.left)
9583
9684 exit:
9785 unreachable