llvm.org GIT mirror llvm / b508d4b
[WinEH] Clone funclets with multiple parents Windows EH funclets need to always return to a single parent funclet. However, it is possible for earlier optimizations to combine funclets (probably based on one funclet having an unreachable terminator) in such a way that this condition is violated. These changes add code to the WinEHPrepare pass to detect situations where a funclet has multiple parents and clone such funclets, fixing up the unwind and catch return edges so that each copy of the funclet returns to the correct parent funclet. Differential Revision: http://reviews.llvm.org/D13274?id=39098 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252249 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Kaylor 5 years ago
6 changed file(s) with 2665 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
53215321 if (Lex.getKind() == lltok::kw_caller) {
53225322 Lex.Lex();
53235323 } else {
5324 return true;
5324 return Error(Lex.getLoc(),
5325 "'to' must be followed by 'caller' in catchendpad");
53255326 }
53265327 } else {
53275328 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
7690 void demotePHIsOnFunclets(Function &F);
7791 void demoteUsesBetweenFunclets(Function &F);
7892 void demoteArgumentUses(Function &F);
87101
88102 std::map> BlockColors;
89103 std::map> FuncletBlocks;
90 std::mapset> FuncletChildren;
104 std::mapvector> 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::map> EstrangedBlocks;
91116 };
92117
93118 } // end anonymous namespace
558583 static void
559584 colorFunclets(Function &F, SmallVectorImpl &EntryBlocks,
560585 std::map> &BlockColors,
561 std::map> &FuncletBlocks,
562 std::map> &FuncletChildren) {
586 std::map> &FuncletBlocks) {
563587 SmallVector, 16> Worklist;
564588 BasicBlock *EntryBlock = &F.getEntryBlock();
565589
576600 // are as defined above. A post-pass fixes up the block color map to reflect
577601 // the same sense of "color" for funclet entries as for other blocks.
578602
603 DEBUG_WITH_TYPE("winehprepare-coloring", dbgs() << "\nColoring funclets for "
604 << F.getName() << "\n");
605
579606 Worklist.push_back({EntryBlock, EntryBlock});
580607
581608 while (!Worklist.empty()) {
582609 BasicBlock *Visiting;
583610 BasicBlock *Color;
584611 std::tie(Visiting, Color) = Worklist.pop_back_val();
612 DEBUG_WITH_TYPE("winehprepare-coloring",
613 dbgs() << "Visiting " << Visiting->getName() << ", "
614 << Color->getName() << "\n");
585615 Instruction *VisitingHead = Visiting->getFirstNonPHI();
586616 if (VisitingHead->isEHPad() && !isa(VisitingHead) &&
587617 !isa(VisitingHead)) {
599629 if (auto *Exit = dyn_cast(U)) {
600630 for (BasicBlock *Succ : successors(Exit->getParent()))
601631 if (!isa(*Succ->getFirstNonPHI()))
602 if (BlockColors[Succ].insert(Color).second)
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");
603637 Worklist.push_back({Succ, Color});
638 }
604639 }
605640 }
606641 // Handle CatchPad specially since its successors need different colors.
609644 // visit the unwind successor with the color of the parent.
610645 BasicBlock *NormalSucc = CatchPad->getNormalDest();
611646 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");
612651 Worklist.push_back({NormalSucc, Visiting});
613652 }
614653 BasicBlock *UnwindSucc = CatchPad->getUnwindDest();
615654 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");
616659 Worklist.push_back({UnwindSucc, Color});
617660 }
618661 continue;
644687 continue;
645688 }
646689 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");
647694 Worklist.push_back({Succ, Color});
648695 }
649696 }
650697 }
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 (auto *CEP = dyn_cast(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 (auto *CEP = dyn_cast(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 (auto *CEP = dyn_cast(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);
6511490
6521491 // The processing above actually accumulated the parent set for this
6531492 // funclet into the color set for its entry; use the parent set to
6561495 // that transitions to the child funclet).
6571496 for (BasicBlock *FuncletEntry : EntryBlocks) {
6581497 std::set &ColorMapItem = BlockColors[FuncletEntry];
659 for (BasicBlock *Parent : ColorMapItem)
660 FuncletChildren[Parent].insert(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 }
6611514 ColorMapItem.clear();
6621515 ColorMapItem.insert(FuncletEntry);
6631516 }
664 }
665
666 void WinEHPrepare::colorFunclets(Function &F,
667 SmallVectorImpl &EntryBlocks) {
668 ::colorFunclets(F, EntryBlocks, BlockColors, FuncletBlocks, FuncletChildren);
6691517 }
6701518
6711519 void llvm::calculateCatchReturnSuccessorColors(const Function *Fn,
6771525
6781526 std::map> BlockColors;
6791527 std::map> FuncletBlocks;
680 std::map> FuncletChildren;
6811528 // Figure out which basic blocks belong to which funclets.
6821529 colorFunclets(const_cast(*Fn), EntryBlocks, BlockColors,
683 FuncletBlocks, FuncletChildren);
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 }
6841540
6851541 // We need to find the catchret successors. To do this, we must first find
6861542 // all the catchpad funclets.
7711627
7721628 std::map Orig2Clone;
7731629 ValueToValueMapTy VMap;
774 for (BasicBlock *BB : BlocksInFunclet) {
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++;
7751636 std::set &ColorsForBB = BlockColors[BB];
7761637 // We don't need to do anything if the block is monochromatic.
7771638 size_t NumColorsForBB = ColorsForBB.size();
7781639 if (NumColorsForBB == 1)
7791640 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 (auto *CEP = dyn_cast(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");
7801694
7811695 // Create a new basic block and copy instructions into it!
7821696 BasicBlock *CBB =
8051719 BlocksInFunclet.insert(NewBlock);
8061720 BlockColors[NewBlock].insert(FuncletPadBB);
8071721
1722 DEBUG_WITH_TYPE("winehprepare-coloring",
1723 dbgs() << " Assigned color \'" << FuncletPadBB->getName()
1724 << "\' to block \'" << NewBlock->getName()
1725 << "\'.\n");
1726
8081727 BlocksInFunclet.erase(OldBlock);
8091728 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 }
8101768 }
8111769
8121770 // Loop over all of the instructions in this funclet, fixing up operand
9931951
9941952 cloneCommonBlocks(F, EntryBlocks);
9951953
1954 resolveFuncletAncestry(F, EntryBlocks);
1955
9961956 if (!DisableCleanups) {
9971957 removeImplausibleTerminators(F);
9981958
10041964 BlockColors.clear();
10051965 FuncletBlocks.clear();
10061966 FuncletChildren.clear();
1967 FuncletParents.clear();
1968 EstrangedBlocks.clear();
1969 FuncletCloningRequired = false;
10071970
10081971 return true;
10091972 }
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 ; TODO: CHECKs
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
283306
284307
285308 define void @test7() personality i32 (...)* @__CxxFrameHandler3 {
311334 ; with the join at the entry itself instead of following a
312335 ; non-pad join.
313336 ; CHECK-LABEL: define void @test7(
314 ; TODO: CHECKs
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
315363
316364
317365 define void @test8() personality i32 (...)* @__CxxFrameHandler3 {
349397 ; %inner is a two-parent child which itself has a child; need
350398 ; to make two copies of both the %inner and %inner.child.
351399 ; CHECK-LABEL: define void @test8(
352 ; TODO: CHECKs
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
353434
354435
355436 define void @test9() personality i32 (...)* @__CxxFrameHandler3 {
382463 ; of which was which along the way; generating each possibility lets
383464 ; whichever case was correct execute correctly.
384465 ; CHECK-LABEL: define void @test9(
385 ; TODO: CHECKs
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
386493
387494 define void @test10() personality i32 (...)* @__CxxFrameHandler3 {
388495 entry:
8585 ; CHECK: store i32 %z
8686 ; CHECK-NEXT: invoke void @f
8787 invoke void @f()
88 to label %catchret.inner unwind label %merge.outer
88 to label %catchret.inner unwind label %catchend.inner
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 ]
9395 catchendpad unwind label %merge.outer
9496
9597 merge.outer:
9698 ; CHECK: merge.outer:
97 ; CHECK-NOT: = phi
9899 ; 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 ; 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 ; CHECK: to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_END_RIGHT]]
1320 ; CHECK: [[INNER_SIBLING_CATCH_LEFT]]:
1321 ; CHECK: invoke void @f()
1322 ; CHECK: to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_END_LEFT]]
1323 ; CHECK: [[INNER_END_LEFT]]:
1324 ; CHECK: catchendpad unwind to caller
1325 ; CHECK: [[INNER_END_RIGHT]]:
1326 ; CHECK: catchendpad unwind label %[[RIGHT_END]]
1327
1328
1329 define void @test18() personality i32 (...)* @__CxxFrameHandler3 {
1330 entry:
1331 invoke void @f()
1332 to label %invoke.cont unwind label %left
1333 invoke.cont:
1334 invoke void @f()
1335 to label %exit unwind label %right
1336 left:
1337 %l = cleanuppad []
1338 br label %shared
1339 right:
1340 catchpad []
1341 to label %right.catch unwind label %right.end
1342 right.catch:
1343 br label %shared
1344 right.end:
1345 catchendpad unwind to caller
1346 shared:
1347 invoke void @f()
1348 to label %unreachable unwind label %inner
1349 unreachable:
1350 unreachable
1351 inner:
1352 %i = catchpad []
1353 to label %inner.catch unwind label %inner.sibling
1354 inner.catch:
1355 invoke void @f()
1356 to label %unreachable unwind label %inner.end
1357 inner.sibling:
1358 %is = catchpad []
1359 to label %inner.sibling.catch unwind label %inner.end
1360 inner.sibling.catch:
1361 call void @h(i32 0)
1362 unreachable
1363 inner.end:
1364 catchendpad unwind label %right.end
1365 exit:
1366 ret void
1367 }
1368 ; This is like test17 except that the inner invoke is moved from the
1369 ; %inner.sibling funclet to %inner so that it is unwinding to a
1370 ; catchendpad block that has not yet been cloned. The unwind destination
1371 ; of the invoke should still be updated to reach the correct copy of
1372 ; %inner.end for the path by which it is reached.
1373 ; CHECK-LABEL: define void @test18(
1374 ; CHECK: left:
1375 ; CHECK: %l = cleanuppad []
1376 ; CHECK: invoke void @f()
1377 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
1378 ; CHECK: right:
1379 ; CHECK: catchpad []
1380 ; CHECK: to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
1381 ; CHECK: [[RIGHT_CATCH]]:
1382 ; CHECK: invoke void @f()
1383 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
1384 ; CHECK: [[RIGHT_END]]:
1385 ; CHECK: catchendpad unwind to caller
1386 ; CHECK: [[SHARED_CONT_RIGHT]]:
1387 ; CHECK: unreachable
1388 ; CHECK: [[SHARED_CONT_LEFT]]:
1389 ; CHECK: unreachable
1390 ; CHECK: [[INNER_RIGHT]]:
1391 ; CHECK: [[I_RIGHT:\%.+]] = catchpad []
1392 ; CHECK: to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_SIBLING_RIGHT:.+]]
1393 ; CHECK: [[INNER_LEFT]]:
1394 ; CHECK: [[I_LEFT:\%.+]] = catchpad []
1395 ; CHECK: to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_SIBLING_LEFT:.+]]
1396 ; CHECK: [[INNER_CATCH_RIGHT]]:
1397 ; CHECK: invoke void @f()
1398 ; CHECK: to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
1399 ; CHECK: [[INNER_CATCH_LEFT]]:
1400 ; CHECK: invoke void @f()
1401 ; CHECK: to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
1402 ; CHECK: [[INNER_SIBLING_RIGHT]]:
1403 ; CHECK: [[IS_RIGHT:\%.+]] = catchpad []
1404 ; CHECK: to label %[[INNER_SIBLING_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT]]
1405 ; CHECK: [[INNER_SIBLING_LEFT]]:
1406 ; CHECK: [[IS_LEFT:\%.+]] = catchpad []
1407 ; CHECK: to label %[[INNER_SIBLING_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT]]
1408 ; CHECK: [[INNER_SIBLING_CATCH_RIGHT]]:
1409 ; CHECK: call void @h(i32 0)
1410 ; CHECK: unreachable
1411 ; CHECK: [[INNER_SIBLING_CATCH_LEFT]]:
1412 ; CHECK: call void @h(i32 0)
1413 ; CHECK: unreachable
1414 ; CHECK: [[INNER_END_LEFT]]:
1415 ; CHECK: catchendpad unwind to caller
1416 ; CHECK: [[INNER_END_RIGHT]]:
1417 ; CHECK: catchendpad unwind label %[[RIGHT_END]]
1418
1419
1420 define void @test19() personality i32 (...)* @__CxxFrameHandler3 {
1421 entry:
1422 invoke void @f()
1423 to label %invoke.cont unwind label %left
1424 invoke.cont:
1425 invoke void @f()
1426 to label %exit unwind label %right
1427 left:
1428 %l = cleanuppad []
1429 br label %shared
1430 right:
1431 catchpad []
1432 to label %right.catch unwind label %right.end
1433 right.catch:
1434 br label %shared
1435 right.end:
1436 catchendpad unwind to caller
1437 shared:
1438 invoke void @f()
1439 to label %unreachable unwind label %inner
1440 unreachable:
1441 unreachable
1442 inner:
1443 %i = cleanuppad []
1444 invoke void @f()
1445 to label %unreachable unwind label %inner.end
1446 inner.end:
1447 cleanupendpad %i unwind label %right.end
1448 exit:
1449 ret void
1450 }
1451 ; This case tests the scenario where an invoke in a funclet with multiple
1452 ; parents unwinds to a cleanup end pad for the funclet. The unwind destination
1453 ; for the invoke should map to the correct copy of the cleanup end pad block.
1454 ; CHECK-LABEL: define void @test19(
1455 ; CHECK: left:
1456 ; CHECK: %l = cleanuppad []
1457 ; CHECK: invoke void @f()
1458 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
1459 ; CHECK: right:
1460 ; CHECK: catchpad []
1461 ; CHECK: to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
1462 ; CHECK: [[RIGHT_CATCH]]:
1463 ; CHECK: invoke void @f()
1464 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
1465 ; CHECK: [[RIGHT_END]]:
1466 ; CHECK: catchendpad unwind to caller
1467 ; CHECK: [[SHARED_CONT_RIGHT]]:
1468 ; CHECK: unreachable
1469 ; CHECK: [[SHARED_CONT_LEFT]]:
1470 ; CHECK: unreachable
1471 ; CHECK: [[INNER_RIGHT]]:
1472 ; CHECK: [[I_RIGHT:\%.+]] = cleanuppad []
1473 ; CHECK: invoke void @f()
1474 ; CHECK: to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
1475 ; CHECK: [[INNER_LEFT]]:
1476 ; CHECK: [[I_LEFT:\%.+]] = cleanuppad []
1477 ; CHECK: invoke void @f()
1478 ; CHECK: to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
1479 ; CHECK: [[INNER_END_RIGHT]]:
1480 ; CHECK: cleanupendpad [[I_RIGHT]] unwind label %[[RIGHT_END]]
1481 ; CHECK: [[INNER_END_LEFT]]:
1482 ; CHECK: cleanupendpad [[I_LEFT]] unwind to caller
1483
1484 define void @test20() personality i32 (...)* @__CxxFrameHandler3 {
1485 entry:
1486 invoke void @f()
1487 to label %invoke.cont unwind label %left
1488 invoke.cont:
1489 invoke void @f()
1490 to label %exit unwind label %right
1491 left:
1492 %l = cleanuppad []
1493 br label %shared
1494 right:
1495 catchpad []
1496 to label %right.catch unwind label %right.end
1497 right.catch:
1498 br label %shared
1499 right.end:
1500 catchendpad unwind to caller
1501 shared:
1502 invoke void @f()
1503 to label %unreachable unwind label %inner
1504 unreachable:
1505 unreachable
1506 inner:
1507 %i = cleanuppad []
1508 invoke void @f()
1509 to label %unreachable unwind label %inner.cleanup
1510 inner.cleanup:
1511 cleanuppad []
1512 call void @f()
1513 unreachable
1514 exit:
1515 ret void
1516 }
1517 ; This tests the case where a funclet with multiple parents contains an invoke
1518 ; instruction that unwinds to a child funclet. Here %left and %right are both
1519 ; parents of %inner. Initially %inner is the only parent of %inner.cleanup but
1520 ; after %inner is cloned, %inner.cleanup has multiple parents and so it must
1521 ; also be cloned.
1522 ; CHECK-LABEL: define void @test20(
1523 ; CHECK: left:
1524 ; CHECK: %l = cleanuppad []
1525 ; CHECK: invoke void @f()
1526 ; CHECK: to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
1527 ; CHECK: right:
1528 ; CHECK: catchpad []
1529 ; CHECK: to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
1530 ; CHECK: [[RIGHT_CATCH]]:
1531 ; CHECK: invoke void @f()
1532 ; CHECK: to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
1533 ; CHECK: [[RIGHT_END]]:
1534 ; CHECK: catchendpad unwind to caller
1535 ; CHECK: [[SHARED_CONT_RIGHT]]:
1536 ; CHECK: unreachable
1537 ; CHECK: [[SHARED_CONT_LEFT]]:
1538 ; CHECK: unreachable
1539 ; CHECK: [[INNER_RIGHT]]:
1540 ; CHECK: [[I_RIGHT:\%.+]] = cleanuppad []
1541 ; CHECK: invoke void @f()
1542 ; CHECK: to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_CLEANUP_RIGHT:.+]]
1543 ; CHECK: [[INNER_LEFT]]:
1544 ; CHECK: [[I_LEFT:\%.+]] = cleanuppad []
1545 ; CHECK: invoke void @f()
1546 ; CHECK: to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_CLEANUP_LEFT:.+]]
1547 ; CHECK: [[INNER_CLEANUP_RIGHT]]:
1548 ; CHECK: cleanuppad []
1549 ; CHECK: call void @f()
1550 ; CHECK: unreachable
1551 ; CHECK: [[INNER_CLEANUP_LEFT]]:
1552 ; CHECK: cleanuppad []
1553 ; CHECK: call void @f()
1554 ; CHECK: unreachable
1555
1556
3838 unreachable
3939
4040 inner:
41 ; CHECK: %phi = phi i32 [ %x, %right ], [ 0, %invoke.cont2 ], [ %x.for.left, %left ]
4241 %phi = phi i32 [ %x, %shared ], [ 0, %invoke.cont2 ]
4342 %i = cleanuppad []
4443 call void @h(i32 %phi)
4544 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)
4654
4755 exit:
4856 unreachable
7583 unreachable
7684
7785 inner:
78 ; CHECK: %x1 = phi i32 [ %x.for.left, %left ], [ %x, %right ]
79 ; CHECK: call void @h(i32 %x1)
8086 %i = cleanuppad []
8187 call void @h(i32 %x)
8288 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)
8395
8496 exit:
8597 unreachable