llvm.org GIT mirror llvm / 805b66a
[WinEH] Re-committing r252249 (Clone funclets with multiple parents) with additional fixes for determinism problems Differential Revision: http://reviews.llvm.org/D14454 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252508 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Kaylor 5 years ago
5 changed file(s) with 2691 addition(s) and 44 deletion(s). Raw diff Collapse all Expand all
1616 //===----------------------------------------------------------------------===//
1717
1818 #include "llvm/CodeGen/Passes.h"
19 #include "llvm/ADT/SetVector.h"
1920 #include "llvm/Analysis/CFG.h"
2021 #include "llvm/Analysis/LibCallSemantics.h"
2122 #include "llvm/CodeGen/WinEHFuncInfo.h"
4344 cl::init(false));
4445
4546 namespace {
46
47
4748 class WinEHPrepare : public FunctionPass {
4849 public:
4950 static char ID; // Pass identification, replacement for typeid.
6768 AllocaInst *insertPHILoads(PHINode *PN, Function &F);
6869 void replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
6970 DenseMap &Loads, Function &F);
70 void demoteNonlocalUses(Value *V, std::set &ColorsForBB,
71 void demoteNonlocalUses(Value *V, SetVector &ColorsForBB,
7172 Function &F);
7273 bool prepareExplicitEH(Function &F,
7374 SmallVectorImpl &EntryBlocks);
7475 void replaceTerminatePadWithCleanup(Function &F);
7576 void colorFunclets(Function &F, SmallVectorImpl &EntryBlocks);
77 void resolveFuncletAncestry(Function &F,
78 SmallVectorImpl &EntryBlocks);
79 void resolveFuncletAncestryForPath(
80 Function &F, SmallVectorImpl &FuncletPath,
81 std::map &IdentityMap);
82 void makeFuncletEdgeUnreachable(BasicBlock *Parent, BasicBlock *Child);
83 BasicBlock *cloneFuncletForParent(Function &F, BasicBlock *FuncletEntry,
84 BasicBlock *Parent);
85 void updateTerminatorsAfterFuncletClone(
86 Function &F, BasicBlock *OrigFunclet, BasicBlock *CloneFunclet,
87 BasicBlock *OrigBlock, BasicBlock *CloneBlock, BasicBlock *CloneParent,
88 ValueToValueMapTy &VMap,
89 std::map &Orig2Clone);
90
7691 void demotePHIsOnFunclets(Function &F);
7792 void demoteUsesBetweenFunclets(Function &F);
7893 void demoteArgumentUses(Function &F);
85100 // All fields are reset by runOnFunction.
86101 EHPersonality Personality = EHPersonality::Unknown;
87102
88 std::mapstd::set> BlockColors;
103 std::mapSetVector> BlockColors;
89104 std::map> FuncletBlocks;
90 std::mapset> FuncletChildren;
105 std::mapvector> FuncletChildren;
106 std::map> FuncletParents;
107
108 // This is a flag that indicates an uncommon situation where we need to
109 // clone funclets has been detected.
110 bool FuncletCloningRequired = false;
111 // When a funclet with multiple parents contains a catchret, the block to
112 // which it returns will be cloned so that there is a copy in each parent
113 // but one of the copies will not be properly linked to the catchret and
114 // in most cases will have no predecessors. This double map allows us
115 // to find these cloned blocks when we clone the child funclet.
116 std::map> EstrangedBlocks;
91117 };
92118
93119 } // end anonymous namespace
557583
558584 static void
559585 colorFunclets(Function &F, SmallVectorImpl &EntryBlocks,
560 std::map> &BlockColors,
561 std::map> &FuncletBlocks,
562 std::mapstd::set> &FuncletChildren) {
586 std::mapSetVector> &BlockColors,
587 std::map> &FuncletBlocks) {
563588 SmallVector, 16> Worklist;
564589 BasicBlock *EntryBlock = &F.getEntryBlock();
565590
576601 // are as defined above. A post-pass fixes up the block color map to reflect
577602 // the same sense of "color" for funclet entries as for other blocks.
578603
604 DEBUG_WITH_TYPE("winehprepare-coloring", dbgs() << "\nColoring funclets for "
605 << F.getName() << "\n");
606
579607 Worklist.push_back({EntryBlock, EntryBlock});
580608
581609 while (!Worklist.empty()) {
582610 BasicBlock *Visiting;
583611 BasicBlock *Color;
584612 std::tie(Visiting, Color) = Worklist.pop_back_val();
613 DEBUG_WITH_TYPE("winehprepare-coloring",
614 dbgs() << "Visiting " << Visiting->getName() << ", "
615 << Color->getName() << "\n");
585616 Instruction *VisitingHead = Visiting->getFirstNonPHI();
586617 if (VisitingHead->isEHPad() && !isa(VisitingHead) &&
587618 !isa(VisitingHead)) {
599630 if (auto *Exit = dyn_cast(U)) {
600631 for (BasicBlock *Succ : successors(Exit->getParent()))
601632 if (!isa(*Succ->getFirstNonPHI()))
602 if (BlockColors[Succ].insert(Color).second)
633 if (BlockColors[Succ].insert(Color)) {
634 DEBUG_WITH_TYPE("winehprepare-coloring",
635 dbgs() << " Assigned color \'"
636 << Color->getName() << "\' to block \'"
637 << Succ->getName() << "\'.\n");
603638 Worklist.push_back({Succ, Color});
639 }
604640 }
605641 }
606642 // Handle CatchPad specially since its successors need different colors.
608644 // Visit the normal successor with the color of the new EH pad, and
609645 // visit the unwind successor with the color of the parent.
610646 BasicBlock *NormalSucc = CatchPad->getNormalDest();
611 if (BlockColors[NormalSucc].insert(Visiting).second) {
647 if (BlockColors[NormalSucc].insert(Visiting)) {
648 DEBUG_WITH_TYPE("winehprepare-coloring",
649 dbgs() << " Assigned color \'" << Visiting->getName()
650 << "\' to block \'" << NormalSucc->getName()
651 << "\'.\n");
612652 Worklist.push_back({NormalSucc, Visiting});
613653 }
614654 BasicBlock *UnwindSucc = CatchPad->getUnwindDest();
615 if (BlockColors[UnwindSucc].insert(Color).second) {
655 if (BlockColors[UnwindSucc].insert(Color)) {
656 DEBUG_WITH_TYPE("winehprepare-coloring",
657 dbgs() << " Assigned color \'" << Color->getName()
658 << "\' to block \'" << UnwindSucc->getName()
659 << "\'.\n");
616660 Worklist.push_back({UnwindSucc, Color});
617661 }
618662 continue;
643687 // safely skip this successor here.
644688 continue;
645689 }
646 if (BlockColors[Succ].insert(Color).second) {
690 if (BlockColors[Succ].insert(Color)) {
691 DEBUG_WITH_TYPE("winehprepare-coloring",
692 dbgs() << " Assigned color \'" << Color->getName()
693 << "\' to block \'" << Succ->getName()
694 << "\'.\n");
647695 Worklist.push_back({Succ, Color});
648696 }
649697 }
650698 }
699 }
700
701 static BasicBlock *getEndPadForCatch(CatchPadInst *Catch) {
702 // The catch may have sibling catches. Follow the unwind chain until we get
703 // to the catchendpad.
704 BasicBlock *NextUnwindDest = Catch->getUnwindDest();
705 auto *UnwindTerminator = NextUnwindDest->getTerminator();
706 while (auto *NextCatch = dyn_cast(UnwindTerminator)) {
707 NextUnwindDest = NextCatch->getUnwindDest();
708 UnwindTerminator = NextUnwindDest->getTerminator();
709 }
710 // The last catch in the chain must unwind to a catchendpad.
711 assert(isa(UnwindTerminator));
712 return NextUnwindDest;
713 }
714
715 static void updateClonedEHPadUnwindToParent(
716 BasicBlock *UnwindDest, BasicBlock *OrigBlock, BasicBlock *CloneBlock,
717 std::vector &OrigParents, BasicBlock *CloneParent) {
718 auto updateUnwindTerminator = [](BasicBlock *BB) {
719 auto *Terminator = BB->getTerminator();
720 if (isa(Terminator) ||
721 isa(Terminator)) {
722 removeUnwindEdge(BB);
723 } else {
724 // If the block we're updating has a cleanupendpad or cleanupret
725 // terminator, we just want to replace that terminator with an
726 // unreachable instruction.
727 assert(isa(Terminator) ||
728 isa(Terminator));
729 // Loop over all of the successors, removing the block's entry from any
730 // PHI nodes.
731 for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
732 (*SI)->removePredecessor(BB);
733 // Remove the terminator and replace it with an unreachable instruction.
734 BB->getTerminator()->eraseFromParent();
735 new UnreachableInst(BB->getContext(), BB);
736 }
737 };
738
739 assert(UnwindDest->isEHPad());
740 // There are many places to which this EH terminator can unwind and each has
741 // slightly different rules for whether or not it fits with the given
742 // location.
743 auto *EHPadInst = UnwindDest->getFirstNonPHI();
744 if (isa(EHPadInst)) {
745 auto *CloneParentCatch =
746 dyn_cast(CloneParent->getFirstNonPHI());
747 if (!CloneParentCatch ||
748 getEndPadForCatch(CloneParentCatch) != UnwindDest) {
749 DEBUG_WITH_TYPE(
750 "winehprepare-coloring",
751 dbgs() << " removing unwind destination of clone block \'"
752 << CloneBlock->getName() << "\'.\n");
753 updateUnwindTerminator(CloneBlock);
754 }
755 // It's possible that the catch end pad is a legal match for both the clone
756 // and the original, so they must be checked separately. If the original
757 // funclet will still have multiple parents after the current clone parent
758 // is removed, we'll leave its unwind terminator until later.
759 assert(OrigParents.size() >= 2);
760 if (OrigParents.size() != 2)
761 return;
762
763 // If the original funclet will have a single parent after the clone parent
764 // is removed, check that parent's unwind destination.
765 assert(OrigParents.front() == CloneParent ||
766 OrigParents.back() == CloneParent);
767 BasicBlock *OrigParent;
768 if (OrigParents.front() == CloneParent)
769 OrigParent = OrigParents.back();
770 else
771 OrigParent = OrigParents.front();
772
773 auto *OrigParentCatch =
774 dyn_cast(OrigParent->getFirstNonPHI());
775 if (!OrigParentCatch || getEndPadForCatch(OrigParentCatch) != UnwindDest) {
776 DEBUG_WITH_TYPE(
777 "winehprepare-coloring",
778 dbgs() << " removing unwind destination of original block \'"
779 << OrigBlock << "\'.\n");
780 updateUnwindTerminator(OrigBlock);
781 }
782 } else if (auto *CleanupEnd = dyn_cast(EHPadInst)) {
783 // If the EH terminator unwinds to a cleanupendpad, that cleanupendpad
784 // must be ending a cleanuppad of either our clone parent or one
785 // one of the parents of the original funclet.
786 auto *CloneParentCP =
787 dyn_cast(CloneParent->getFirstNonPHI());
788 auto *EndedCP = CleanupEnd->getCleanupPad();
789 if (EndedCP == CloneParentCP) {
790 // If it is ending the cleanuppad of our cloned parent, then we
791 // want to remove the unwind destination of the EH terminator that
792 // we associated with the original funclet.
793 assert(isa(OrigBlock->getFirstNonPHI()));
794 DEBUG_WITH_TYPE(
795 "winehprepare-coloring",
796 dbgs() << " removing unwind destination of original block \'"
797 << OrigBlock->getName() << "\'.\n");
798 updateUnwindTerminator(OrigBlock);
799 } else {
800 // If it isn't ending the cleanuppad of our clone parent, then we
801 // want to remove the unwind destination of the EH terminator that
802 // associated with our cloned funclet.
803 assert(isa(CloneBlock->getFirstNonPHI()));
804 DEBUG_WITH_TYPE(
805 "winehprepare-coloring",
806 dbgs() << " removing unwind destination of clone block \'"
807 << CloneBlock->getName() << "\'.\n");
808 updateUnwindTerminator(CloneBlock);
809 }
810 } else {
811 // If the EH terminator unwinds to a catchpad, cleanuppad or
812 // terminatepad that EH pad must be a sibling of the funclet we're
813 // cloning. We'll clone it later and update one of the catchendpad
814 // instrunctions that unwinds to it at that time.
815 assert(isa(EHPadInst) || isa(EHPadInst) ||
816 isa(EHPadInst));
817 }
818 }
819
820 // If the terminator is a catchpad, we must also clone the catchendpad to which
821 // it unwinds and add this to the clone parent's block list. The catchendpad
822 // unwinds to either its caller, a sibling EH pad, a cleanup end pad in its
823 // parent funclet or a catch end pad in its grandparent funclet (which must be
824 // coupled with the parent funclet). If it has no unwind destination
825 // (i.e. unwind to caller), there is nothing to be done. If the unwind
826 // destination is a sibling EH pad, we will update the terminators later (in
827 // resolveFuncletAncestryForPath). If it unwinds to a cleanup end pad or a
828 // catch end pad and this end pad corresponds to the clone parent, we will
829 // remove the unwind destination in the original catchendpad. If it unwinds to
830 // a cleanup end pad or a catch end pad that does not correspond to the clone
831 // parent, we will remove the unwind destination in the cloned catchendpad.
832 static void updateCatchTerminators(
833 Function &F, CatchPadInst *OrigCatch, CatchPadInst *CloneCatch,
834 std::vector &OrigParents, BasicBlock *CloneParent,
835 ValueToValueMapTy &VMap,
836 std::map> &BlockColors,
837 std::map> &FuncletBlocks) {
838 // If we're cloning a catch pad that unwinds to a catchendpad, we also
839 // need to clone the catchendpad. The coloring algorithm associates
840 // the catchendpad block with the funclet's parent, so we have some work
841 // to do here to figure out whether the original belongs to the clone
842 // parent or one of the original funclets other parents (it might have
843 // more than one at this point). In either case, we might also need to
844 // remove the unwind edge if the catchendpad doesn't unwind to a block
845 // in the right grandparent funclet.
846 Instruction *I = CloneCatch->getUnwindDest()->getFirstNonPHI();
847 if (auto *CEP = dyn_cast(I)) {
848 assert(BlockColors[CEP->getParent()].size() == 1);
849 BasicBlock *CEPFunclet = *(BlockColors[CEP->getParent()].begin());
850 BasicBlock *CEPCloneParent = nullptr;
851 CatchPadInst *PredCatch = nullptr;
852 if (CEPFunclet == CloneParent) {
853 // The catchendpad is in the clone parent, so we need to clone it
854 // and associate the clone with the original funclet's parent. If
855 // the original funclet had multiple parents, we'll add it to the
856 // first parent that isn't the clone parent. The logic in
857 // updateClonedEHPadUnwindToParent() will only remove the unwind edge
858 // if there is only one parent other than the clone parent, so we don't
859 // need to verify the ancestry. The catchendpad will eventually be
860 // cloned into the correct parent and all invalid unwind edges will be
861 // removed.
862 for (auto *Parent : OrigParents) {
863 if (Parent != CloneParent) {
864 CEPCloneParent = Parent;
865 break;
866 }
867 }
868 PredCatch = OrigCatch;
869 } else {
870 CEPCloneParent = CloneParent;
871 PredCatch = CloneCatch;
872 }
873 assert(CEPCloneParent && PredCatch);
874 DEBUG_WITH_TYPE("winehprepare-coloring",
875 dbgs() << " Cloning catchendpad \'"
876 << CEP->getParent()->getName() << "\' for funclet \'"
877 << CEPCloneParent->getName() << "\'.\n");
878 BasicBlock *ClonedCEP = CloneBasicBlock(
879 CEP->getParent(), VMap, Twine(".from.", CEPCloneParent->getName()));
880 // Insert the clone immediately after the original to ensure determinism
881 // and to keep the same relative ordering of any funclet's blocks.
882 ClonedCEP->insertInto(&F, CEP->getParent()->getNextNode());
883 PredCatch->setUnwindDest(ClonedCEP);
884 FuncletBlocks[CEPCloneParent].insert(ClonedCEP);
885 BlockColors[ClonedCEP].insert(CEPCloneParent);
886 DEBUG_WITH_TYPE("winehprepare-coloring",
887 dbgs() << " Assigning color \'"
888 << CEPCloneParent->getName() << "\' to block \'"
889 << ClonedCEP->getName() << "\'.\n");
890 auto *ClonedCEPInst = cast(ClonedCEP->getTerminator());
891 if (auto *Dest = ClonedCEPInst->getUnwindDest())
892 updateClonedEHPadUnwindToParent(Dest, OrigCatch->getUnwindDest(),
893 CloneCatch->getUnwindDest(), OrigParents,
894 CloneParent);
895 }
896 }
897
898 // While we are cloning a funclet because it has multiple parents, we will call
899 // this routine to update the terminators for the original and cloned copies
900 // of each basic block. All blocks in the funclet have been clone by this time.
901 // OrigBlock and CloneBlock will be identical except for their block label.
902 //
903 // If the terminator is a catchpad, we must also clone the catchendpad to which
904 // it unwinds and in most cases update either the original catchendpad or the
905 // clone. See the updateCatchTerminators() helper routine for details.
906 //
907 // If the terminator is a catchret its successor is a block in its parent
908 // funclet. If the instruction returns to a block in the parent for which the
909 // cloned funclet was created, the terminator in the original block must be
910 // replaced by an unreachable instruction. Otherwise the terminator in the
911 // clone block must be replaced by an unreachable instruction.
912 //
913 // If the terminator is a cleanupret or cleanupendpad it either unwinds to
914 // caller or unwinds to a sibling EH pad, a cleanup end pad in its parent
915 // funclet or a catch end pad in its grandparent funclet (which must be
916 // coupled with the parent funclet). If it unwinds to caller there is
917 // nothing to be done. If the unwind destination is a sibling EH pad, we will
918 // update the terminators later (in resolveFuncletAncestryForPath). If it
919 // unwinds to a cleanup end pad or a catch end pad and this end pad corresponds
920 // to the clone parent, we will replace the terminator in the original block
921 // with an unreachable instruction. If it unwinds to a cleanup end pad or a
922 // catch end pad that does not correspond to the clone parent, we will replace
923 // the terminator in the clone block with an unreachable instruction.
924 //
925 // If the terminator is an invoke instruction, we will handle it after all
926 // siblings of the current funclet have been cloned.
927 void WinEHPrepare::updateTerminatorsAfterFuncletClone(
928 Function &F, BasicBlock *OrigFunclet, BasicBlock *CloneFunclet,
929 BasicBlock *OrigBlock, BasicBlock *CloneBlock, BasicBlock *CloneParent,
930 ValueToValueMapTy &VMap, std::map &Orig2Clone) {
931 // If the cloned block doesn't have an exceptional terminator, there is
932 // nothing to be done here.
933 TerminatorInst *CloneTerminator = CloneBlock->getTerminator();
934 if (!CloneTerminator->isExceptional())
935 return;
936
937 if (auto *CloneCatch = dyn_cast(CloneTerminator)) {
938 // A cloned catch pad has a lot of wrinkles, so we'll call a helper function
939 // to update this case.
940 auto *OrigCatch = cast(OrigBlock->getTerminator());
941 updateCatchTerminators(F, OrigCatch, CloneCatch,
942 FuncletParents[OrigFunclet], CloneParent, VMap,
943 BlockColors, FuncletBlocks);
944 } else if (auto *CRI = dyn_cast(CloneTerminator)) {
945 if (FuncletBlocks[CloneParent].count(CRI->getSuccessor())) {
946 BasicBlock *OrigParent;
947 // The original funclet may have more than two parents, but that's OK.
948 // We just need to remap the original catchret to any of the parents.
949 // All of the parents should have an entry in the EstrangedBlocks map
950 // if any of them do.
951 if (FuncletParents[OrigFunclet].front() == CloneParent)
952 OrigParent = FuncletParents[OrigFunclet].back();
953 else
954 OrigParent = FuncletParents[OrigFunclet].front();
955 for (succ_iterator SI = succ_begin(OrigBlock), SE = succ_end(OrigBlock);
956 SI != SE; ++SI)
957 (*SI)->removePredecessor(OrigBlock);
958 BasicBlock *LostBlock = EstrangedBlocks[OrigParent][CRI->getSuccessor()];
959 auto *OrigCatchRet = cast(OrigBlock->getTerminator());
960 if (LostBlock) {
961 OrigCatchRet->setSuccessor(LostBlock);
962 } else {
963 OrigCatchRet->eraseFromParent();
964 new UnreachableInst(OrigBlock->getContext(), OrigBlock);
965 }
966 } else {
967 for (succ_iterator SI = succ_begin(CloneBlock), SE = succ_end(CloneBlock);
968 SI != SE; ++SI)
969 (*SI)->removePredecessor(CloneBlock);
970 BasicBlock *LostBlock = EstrangedBlocks[CloneParent][CRI->getSuccessor()];
971 if (LostBlock) {
972 CRI->setSuccessor(LostBlock);
973 } else {
974 CRI->eraseFromParent();
975 new UnreachableInst(CloneBlock->getContext(), CloneBlock);
976 }
977 }
978 } else if (isa(CloneTerminator) ||
979 isa(CloneTerminator)) {
980 BasicBlock *UnwindDest = nullptr;
981
982 // A cleanup pad can unwind through either a cleanupret or a cleanupendpad
983 // but both are handled the same way.
984 if (auto *CRI = dyn_cast(CloneTerminator))
985 UnwindDest = CRI->getUnwindDest();
986 else if (auto *CEI = dyn_cast(CloneTerminator))
987 UnwindDest = CEI->getUnwindDest();
988
989 // If the instruction has no local unwind destination, there is nothing
990 // to be done.
991 if (!UnwindDest)
992 return;
993
994 // The unwind destination may be a sibling EH pad, a catchendpad in
995 // a grandparent funclet (ending a catchpad in the parent) or a cleanup
996 // cleanupendpad in the parent. Call a helper routine to diagnose this
997 // and remove either the clone or original terminator as needed.
998 updateClonedEHPadUnwindToParent(UnwindDest, OrigBlock, CloneBlock,
999 FuncletParents[OrigFunclet], CloneParent);
1000 }
1001 }
1002
1003 // Clones all blocks used by the specified funclet to avoid the funclet having
1004 // multiple parent funclets. All terminators in the parent that unwind to the
1005 // original funclet are remapped to unwind to the clone. Any terminator in the
1006 // original funclet which returned to this parent is converted to an unreachable
1007 // instruction. Likewise, any terminator in the cloned funclet which returns to
1008 // a parent funclet other than the specified parent is converted to an
1009 // unreachable instruction.
1010 BasicBlock *WinEHPrepare::cloneFuncletForParent(Function &F,
1011 BasicBlock *FuncletEntry,
1012 BasicBlock *Parent) {
1013 std::set &BlocksInFunclet = FuncletBlocks[FuncletEntry];
1014
1015 DEBUG_WITH_TYPE("winehprepare-coloring",
1016 dbgs() << "Cloning funclet \'" << FuncletEntry->getName()
1017 << "\' for parent \'" << Parent->getName() << "\'.\n");
1018
1019 std::map Orig2Clone;
1020 ValueToValueMapTy VMap;
1021 for (BasicBlock *BB : BlocksInFunclet) {
1022 // Create a new basic block and copy instructions into it.
1023 BasicBlock *CBB =
1024 CloneBasicBlock(BB, VMap, Twine(".from.", Parent->getName()));
1025
1026 // Insert the clone immediately after the original to ensure determinism
1027 // and to keep the same relative ordering of any funclet's blocks.
1028 CBB->insertInto(&F, BB->getNextNode());
1029
1030 // Add basic block mapping.
1031 VMap[BB] = CBB;
1032
1033 // Record delta operations that we need to perform to our color mappings.
1034 Orig2Clone[BB] = CBB;
1035 } // end for (BasicBlock *BB : BlocksInFunclet)
1036
1037 BasicBlock *ClonedFunclet = Orig2Clone[FuncletEntry];
1038 assert(ClonedFunclet);
1039
1040 // Set the coloring for the blocks we just cloned.
1041 std::set &ClonedBlocks = FuncletBlocks[ClonedFunclet];
1042 for (auto &BBMapping : Orig2Clone) {
1043 BasicBlock *NewBlock = BBMapping.second;
1044 ClonedBlocks.insert(NewBlock);
1045 BlockColors[NewBlock].insert(ClonedFunclet);
1046
1047 DEBUG_WITH_TYPE("winehprepare-coloring",
1048 dbgs() << " Assigning color \'" << ClonedFunclet->getName()
1049 << "\' to block \'" << NewBlock->getName()
1050 << "\'.\n");
1051
1052 // Use the VMap to remap the instructions in this cloned block.
1053 for (Instruction &I : *NewBlock)
1054 RemapInstruction(&I, VMap, RF_IgnoreMissingEntries);
1055 }
1056
1057 // All the cloned blocks have to be colored in the loop above before we can
1058 // update the terminators because doing so can require checking the color of
1059 // other blocks in the cloned funclet.
1060 for (auto &BBMapping : Orig2Clone) {
1061 BasicBlock *OldBlock = BBMapping.first;
1062 BasicBlock *NewBlock = BBMapping.second;
1063
1064 // Update the terminator, if necessary, in both the original block and the
1065 // cloned so that the original funclet never returns to a block in the
1066 // clone parent and the clone funclet never returns to a block in any other
1067 // of the original funclet's parents.
1068 updateTerminatorsAfterFuncletClone(F, FuncletEntry, ClonedFunclet, OldBlock,
1069 NewBlock, Parent, VMap, Orig2Clone);
1070
1071 // Check to see if the cloned block successor has PHI nodes. If so, we need
1072 // to add entries to the PHI nodes for the cloned block now.
1073 for (BasicBlock *SuccBB : successors(NewBlock)) {
1074 for (Instruction &SuccI : *SuccBB) {
1075 auto *SuccPN = dyn_cast(&SuccI);
1076 if (!SuccPN)
1077 break;
1078
1079 // Ok, we have a PHI node. Figure out what the incoming value was for
1080 // the OldBlock.
1081 int OldBlockIdx = SuccPN->getBasicBlockIndex(OldBlock);
1082 if (OldBlockIdx == -1)
1083 break;
1084 Value *IV = SuccPN->getIncomingValue(OldBlockIdx);
1085
1086 // Remap the value if necessary.
1087 if (auto *Inst = dyn_cast(IV)) {
1088 ValueToValueMapTy::iterator I = VMap.find(Inst);
1089 if (I != VMap.end())
1090 IV = I->second;
1091 }
1092
1093 SuccPN->addIncoming(IV, NewBlock);
1094 }
1095 }
1096 }
1097
1098 // Erase the clone's parent from the original funclet's parent list.
1099 std::vector &Parents = FuncletParents[FuncletEntry];
1100 Parents.erase(std::remove(Parents.begin(), Parents.end(), Parent),
1101 Parents.end());
1102
1103 // Store the cloned funclet's parent.
1104 assert(std::find(FuncletParents[ClonedFunclet].begin(),
1105 FuncletParents[ClonedFunclet].end(),
1106 Parent) == std::end(FuncletParents[ClonedFunclet]));
1107 FuncletParents[ClonedFunclet].push_back(Parent);
1108
1109 // Copy any children of the original funclet to the clone. We'll either
1110 // clone them too or make that path unreachable when we take the next step
1111 // in resolveFuncletAncestryForPath().
1112 for (auto *Child : FuncletChildren[FuncletEntry]) {
1113 assert(std::find(FuncletChildren[ClonedFunclet].begin(),
1114 FuncletChildren[ClonedFunclet].end(),
1115 Child) == std::end(FuncletChildren[ClonedFunclet]));
1116 FuncletChildren[ClonedFunclet].push_back(Child);
1117 assert(std::find(FuncletParents[Child].begin(), FuncletParents[Child].end(),
1118 ClonedFunclet) == std::end(FuncletParents[Child]));
1119 FuncletParents[Child].push_back(ClonedFunclet);
1120 }
1121
1122 // Find any blocks that unwound to the original funclet entry from the
1123 // clone parent block and remap them to the clone.
1124 for (auto *U : FuncletEntry->users()) {
1125 auto *UT = dyn_cast(U);
1126 if (!UT)
1127 continue;
1128 BasicBlock *UBB = UT->getParent();
1129 assert(BlockColors[UBB].size() == 1);
1130 BasicBlock *UFunclet = *(BlockColors[UBB].begin());
1131 // Funclets shouldn't be able to loop back on themselves.
1132 assert(UFunclet != FuncletEntry);
1133 // If this instruction unwinds to the original funclet from the clone
1134 // parent, remap the terminator so that it unwinds to the clone instead.
1135 // We will perform a similar transformation for siblings after all
1136 // the siblings have been cloned.
1137 if (UFunclet == Parent) {
1138 // We're about to break the path from this block to the uncloned funclet
1139 // entry, so remove it as a predeccessor to clean up the PHIs.
1140 FuncletEntry->removePredecessor(UBB);
1141 TerminatorInst *Terminator = UBB->getTerminator();
1142 RemapInstruction(Terminator, VMap, RF_IgnoreMissingEntries);
1143 }
1144 }
1145
1146 // This asserts a condition that is relied upon inside the loop below,
1147 // namely that no predecessors of the original funclet entry block
1148 // are also predecessors of the cloned funclet entry block.
1149 assert(std::all_of(pred_begin(FuncletEntry), pred_end(FuncletEntry),
1150 [&ClonedFunclet](BasicBlock *Pred) {
1151 return std::find(pred_begin(ClonedFunclet),
1152 pred_end(ClonedFunclet),
1153 Pred) == pred_end(ClonedFunclet);
1154 }));
1155
1156 // Remove any invalid PHI node entries in the cloned funclet.cl
1157 std::vector PHIsToErase;
1158 for (Instruction &I : *ClonedFunclet) {
1159 auto *PN = dyn_cast(&I);
1160 if (!PN)
1161 break;
1162
1163 // Predecessors of the original funclet do not reach the cloned funclet,
1164 // but the cloning process assumes they will. Remove them now.
1165 for (auto *Pred : predecessors(FuncletEntry))
1166 PN->removeIncomingValue(Pred, false);
1167 }
1168 for (auto *PN : PHIsToErase)
1169 PN->eraseFromParent();
1170
1171 // Replace the original funclet in the parent's children vector with the
1172 // cloned funclet.
1173 for (auto &It : FuncletChildren[Parent]) {
1174 if (It == FuncletEntry) {
1175 It = ClonedFunclet;
1176 break;
1177 }
1178 }
1179
1180 return ClonedFunclet;
1181 }
1182
1183 // Removes the unwind edge for any exceptional terminators within the specified
1184 // parent funclet that previously unwound to the specified child funclet.
1185 void WinEHPrepare::makeFuncletEdgeUnreachable(BasicBlock *Parent,
1186 BasicBlock *Child) {
1187 for (BasicBlock *BB : FuncletBlocks[Parent]) {
1188 TerminatorInst *Terminator = BB->getTerminator();
1189 if (!Terminator->isExceptional())
1190 continue;
1191
1192 // Look for terninators that unwind to the child funclet.
1193 BasicBlock *UnwindDest = nullptr;
1194 if (auto *I = dyn_cast(Terminator))
1195 UnwindDest = I->getUnwindDest();
1196 else if (auto *I = dyn_cast(Terminator))
1197 UnwindDest = I->getUnwindDest();
1198 else if (auto *I = dyn_cast(Terminator))
1199 UnwindDest = I->getUnwindDest();
1200 // cleanupendpad, catchret and cleanupret don't represent a parent-to-child
1201 // funclet transition, so we don't need to consider them here.
1202
1203 // If the child funclet is the unwind destination, replace the terminator
1204 // with an unreachable instruction.
1205 if (UnwindDest == Child)
1206 removeUnwindEdge(BB);
1207 }
1208 // The specified parent is no longer a parent of the specified child.
1209 std::vector &Children = FuncletChildren[Parent];
1210 Children.erase(std::remove(Children.begin(), Children.end(), Child),
1211 Children.end());
1212 }
1213
1214 // This routine is called after funclets with multiple parents are cloned for
1215 // a specific parent. Here we look for children of the specified funclet that
1216 // unwind to other children of that funclet and update the unwind destinations
1217 // to ensure that each sibling is connected to the correct clone of the sibling
1218 // to which it unwinds.
1219 //
1220 // If the terminator is an invoke instruction, it unwinds either to a child
1221 // EH pad, a cleanup end pad in the current funclet, or a catch end pad in a
1222 // parent funclet (which ends either the current catch pad or a sibling
1223 // catch pad). If it unwinds to a child EH pad, the child will have multiple
1224 // parents after this funclet is cloned and this case will be handled later in
1225 // the resolveFuncletAncestryForPath processing. If it unwinds to a
1226 // cleanup end pad in the current funclet, the instruction remapping during
1227 // the cloning process should have already mapped the unwind destination to
1228 // the cloned copy of the cleanup end pad. If it unwinds to a catch end pad
1229 // there are two possibilities: either the catch end pad is the unwind
1230 // destination for the catch pad we are currently cloning or it is the unwind
1231 // destination for a sibling catch pad. If it it the unwind destination of the
1232 // catch pad we are cloning, we need to update the cloned invoke instruction
1233 // to unwind to the cloned catch end pad. Otherwise, we will handle this
1234 // later (in resolveFuncletAncestryForPath).
1235 static void updateSiblingToSiblingUnwind(
1236 BasicBlock *CurFunclet,
1237 std::map> &BlockColors,
1238 std::map> &FuncletBlocks,
1239 std::map> &FuncletParents,
1240 std::map> &FuncletChildren,
1241 std::map &Funclet2Orig) {
1242 // Remap any bad sibling-to-sibling transitions for funclets that
1243 // we just cloned.
1244 for (BasicBlock *ChildFunclet : FuncletChildren[CurFunclet]) {
1245 for (auto *BB : FuncletBlocks[ChildFunclet]) {
1246 TerminatorInst *Terminator = BB->getTerminator();
1247 if (!Terminator->isExceptional())
1248 continue;
1249
1250 // See if this terminator has an unwind destination.
1251 // Note that catchendpads are handled when the associated catchpad
1252 // is cloned. They don't fit the pattern we're looking for here.
1253 BasicBlock *UnwindDest = nullptr;
1254 if (auto *I = dyn_cast(Terminator)) {
1255 UnwindDest = I->getUnwindDest();
1256 // The catchendpad is not a sibling destination. This case should
1257 // have been handled in cloneFuncletForParent().
1258 if (isa(Terminator)) {
1259 assert(BlockColors[UnwindDest].size() == 1 &&
1260 "Cloned catchpad unwinds to an pad with multiple parents.");
1261 assert(FuncletParents[UnwindDest].front() == CurFunclet &&
1262 "Cloned catchpad unwinds to the wrong parent.");
1263 continue;
1264 }
1265 } else {
1266 if (auto *I = dyn_cast(Terminator))
1267 UnwindDest = I->getUnwindDest();
1268 else if (auto *I = dyn_cast(Terminator))
1269 UnwindDest = I->getUnwindDest();
1270
1271 // If the cleanup unwinds to caller, there is nothing to be done.
1272 if (!UnwindDest)
1273 continue;
1274 }
1275
1276 // If the destination is not a cleanup pad, catch pad or terminate pad
1277 // we don't need to handle it here.
1278 Instruction *EHPad = UnwindDest->getFirstNonPHI();
1279 if (!isa(EHPad) && !isa(EHPad) &&
1280 !isa(EHPad))
1281 continue;
1282
1283 // If it is one of these, then it is either a sibling of the current
1284 // child funclet or a clone of one of those siblings.
1285 // If it is a sibling, no action is needed.
1286 if (FuncletParents[UnwindDest].size() == 1 &&
1287 FuncletParents[UnwindDest].front() == CurFunclet)
1288 continue;
1289
1290 // If the unwind destination is a clone of a sibling, we need to figure
1291 // out which sibling it is a clone of and use that sibling as the
1292 // unwind destination.
1293 BasicBlock *DestOrig = Funclet2Orig[UnwindDest];
1294 BasicBlock *TargetSibling = nullptr;
1295 for (auto &Mapping : Funclet2Orig) {
1296 if (Mapping.second != DestOrig)
1297 continue;
1298 BasicBlock *MappedFunclet = Mapping.first;
1299 if (FuncletParents[MappedFunclet].size() == 1 &&
1300 FuncletParents[MappedFunclet].front() == CurFunclet) {
1301 TargetSibling = MappedFunclet;
1302 }
1303 }
1304 // If we didn't find the sibling we were looking for then the
1305 // unwind destination is not a clone of one of child's siblings.
1306 // That's unexpected.
1307 assert(TargetSibling && "Funclet unwinds to unexpected destination.");
1308
1309 // Update the terminator instruction to unwind to the correct sibling.
1310 if (auto *I = dyn_cast(Terminator))
1311 I->setUnwindDest(TargetSibling);
1312 else if (auto *I = dyn_cast(Terminator))
1313 I->setUnwindDest(TargetSibling);
1314 else if (auto *I = dyn_cast(Terminator))
1315 I->setUnwindDest(TargetSibling);
1316 }
1317 }
1318
1319 // Invoke remapping can't be done correctly until after all of their
1320 // other sibling-to-sibling unwinds have been remapped.
1321 for (BasicBlock *ChildFunclet : FuncletChildren[CurFunclet]) {
1322 bool NeedOrigInvokeRemapping = false;
1323 for (auto *BB : FuncletBlocks[ChildFunclet]) {
1324 TerminatorInst *Terminator = BB->getTerminator();
1325 auto *II = dyn_cast(Terminator);
1326 if (!II)
1327 continue;
1328
1329 BasicBlock *UnwindDest = II->getUnwindDest();
1330 assert(UnwindDest && "Invoke unwinds to a null destination.");
1331 assert(UnwindDest->isEHPad() && "Invoke does not unwind to an EH pad.");
1332 auto *EHPadInst = UnwindDest->getFirstNonPHI();
1333 if (isa(EHPadInst)) {
1334 // An invoke that unwinds to a cleanup end pad must be in a cleanup pad.
1335 assert(isa(ChildFunclet->getFirstNonPHI()) &&
1336 "Unwinding to cleanup end pad from a non cleanup pad funclet.");
1337 // The funclet cloning should have remapped the destination to the cloned
1338 // cleanup end pad.
1339 assert(FuncletBlocks[ChildFunclet].count(UnwindDest) &&
1340 "Unwind destination for invoke was not updated during cloning.");
1341 } else if (isa(EHPadInst)) {
1342 // If the invoke unwind destination is the unwind destination for
1343 // the current child catch pad funclet, there is nothing to be done.
1344 BasicBlock *OrigFunclet = Funclet2Orig[ChildFunclet];
1345 auto *CurCatch = cast(ChildFunclet->getFirstNonPHI());
1346 auto *OrigCatch = cast(OrigFunclet->getFirstNonPHI());
1347 if (OrigCatch->getUnwindDest() == UnwindDest) {
1348 // If the invoke unwinds to a catch end pad that is the unwind
1349 // destination for the original catch pad, the cloned invoke should
1350 // unwind to the cloned catch end pad.
1351 II->setUnwindDest(CurCatch->getUnwindDest());
1352 } else if (CurCatch->getUnwindDest() == UnwindDest) {
1353 // If the invoke unwinds to a catch end pad that is the unwind
1354 // destination for the clone catch pad, the original invoke should
1355 // unwind to the unwind destination of the original catch pad.
1356 // This happens when the catch end pad is matched to the clone
1357 // parent when the catchpad instruction is cloned and the original
1358 // invoke instruction unwinds to the original catch end pad (which
1359 // is now the unwind destination of the cloned catch pad).
1360 NeedOrigInvokeRemapping = true;
1361 } else {
1362 // Otherwise, the invoke unwinds to a catch end pad that is the unwind
1363 // destination another catch pad in the unwind chain from either the
1364 // current catch pad or one of its clones. If it is already the
1365 // catch end pad at the end unwind chain from the current catch pad,
1366 // we'll need to check the invoke instructions in the original funclet
1367 // later. Otherwise, we need to remap this invoke now.
1368 assert((getEndPadForCatch(OrigCatch) == UnwindDest ||
1369 getEndPadForCatch(CurCatch) == UnwindDest) &&
1370 "Invoke within catch pad unwinds to an invalid catch end pad.");
1371 BasicBlock *CurCatchEnd = getEndPadForCatch(CurCatch);
1372 if (CurCatchEnd == UnwindDest)
1373 NeedOrigInvokeRemapping = true;
1374 else
1375 II->setUnwindDest(CurCatchEnd);
1376 }
1377 }
1378 }
1379 if (NeedOrigInvokeRemapping) {
1380 // To properly remap invoke instructions that unwind to catch end pads
1381 // that are not the unwind destination of the catch pad funclet in which
1382 // the invoke appears, we must also look at the uncloned invoke in the
1383 // original funclet. If we saw an invoke that was already properly
1384 // unwinding to a sibling's catch end pad, we need to check the invokes
1385 // in the original funclet.
1386 BasicBlock *OrigFunclet = Funclet2Orig[ChildFunclet];
1387 for (auto *BB : FuncletBlocks[OrigFunclet]) {
1388 auto *II = dyn_cast(BB->getTerminator());
1389 if (!II)
1390 continue;
1391
1392 BasicBlock *UnwindDest = II->getUnwindDest();
1393 assert(UnwindDest && "Invoke unwinds to a null destination.");
1394 assert(UnwindDest->isEHPad() && "Invoke does not unwind to an EH pad.");
1395 auto *CEP = dyn_cast(UnwindDest->getFirstNonPHI());
1396 if (!CEP)
1397 continue;
1398
1399 // If the invoke unwind destination is the unwind destination for
1400 // the original catch pad funclet, there is nothing to be done.
1401 auto *OrigCatch = cast(OrigFunclet->getFirstNonPHI());
1402
1403 // If the invoke unwinds to a catch end pad that is neither the unwind
1404 // destination of OrigCatch or the destination another catch pad in the
1405 // unwind chain from current catch pad, we need to remap the invoke.
1406 BasicBlock *OrigCatchEnd = getEndPadForCatch(OrigCatch);
1407 if (OrigCatchEnd != UnwindDest)
1408 II->setUnwindDest(OrigCatchEnd);
1409 }
1410 }
1411 }
1412 }
1413
1414 void WinEHPrepare::resolveFuncletAncestry(
1415 Function &F, SmallVectorImpl &EntryBlocks) {
1416 // Most of the time this will be unnecessary. If the conditions arise that
1417 // require this work, this flag will be set.
1418 if (!FuncletCloningRequired)
1419 return;
1420
1421 // Funclet2Orig is used to map any cloned funclets back to the original
1422 // funclet from which they were cloned. The map is seeded with the
1423 // original funclets mapping to themselves.
1424 std::map Funclet2Orig;
1425 for (auto *Funclet : EntryBlocks)
1426 Funclet2Orig[Funclet] = Funclet;
1427
1428 // Start with the entry funclet and walk the funclet parent-child tree.
1429 SmallVector FuncletPath;
1430 FuncletPath.push_back(&(F.getEntryBlock()));
1431 resolveFuncletAncestryForPath(F, FuncletPath, Funclet2Orig);
1432 }
1433
1434 // Walks the funclet control flow, cloning any funclets that have more than one
1435 // parent funclet and breaking any cyclic unwind chains so that the path becomes
1436 // unreachable at the point where a funclet would have unwound to a funclet that
1437 // was already in the chain.
1438 void WinEHPrepare::resolveFuncletAncestryForPath(
1439 Function &F, SmallVectorImpl &FuncletPath,
1440 std::map &Funclet2Orig) {
1441 bool ClonedAnyChildren = false;
1442 BasicBlock *CurFunclet = FuncletPath.back();
1443 // Copy the children vector because we might changing it.
1444 std::vector Children(FuncletChildren[CurFunclet]);
1445 for (BasicBlock *ChildFunclet : Children) {
1446 // Don't allow the funclet chain to unwind back on itself.
1447 // If this funclet is already in the current funclet chain, make the
1448 // path to it through the current funclet unreachable.
1449 bool IsCyclic = false;
1450 BasicBlock *ChildIdentity = Funclet2Orig[ChildFunclet];
1451 for (BasicBlock *Ancestor : FuncletPath) {
1452 BasicBlock *AncestorIdentity = Funclet2Orig[Ancestor];
1453 if (AncestorIdentity == ChildIdentity) {
1454 IsCyclic = true;
1455 break;
1456 }
1457 }
1458 // If the unwind chain wraps back on itself, break the chain.
1459 if (IsCyclic) {
1460 makeFuncletEdgeUnreachable(CurFunclet, ChildFunclet);
1461 continue;
1462 }
1463 // If this child funclet has other parents, clone the entire funclet.
1464 if (FuncletParents[ChildFunclet].size() > 1) {
1465 ChildFunclet = cloneFuncletForParent(F, ChildFunclet, CurFunclet);
1466 Funclet2Orig[ChildFunclet] = ChildIdentity;
1467 ClonedAnyChildren = true;
1468 }
1469 FuncletPath.push_back(ChildFunclet);
1470 resolveFuncletAncestryForPath(F, FuncletPath, Funclet2Orig);
1471 FuncletPath.pop_back();
1472 }
1473 // If we didn't clone any children, we can return now.
1474 if (!ClonedAnyChildren)
1475 return;
1476
1477 updateSiblingToSiblingUnwind(CurFunclet, BlockColors, FuncletBlocks,
1478 FuncletParents, FuncletChildren, Funclet2Orig);
1479 }
1480
1481 void WinEHPrepare::colorFunclets(Function &F,
1482 SmallVectorImpl &EntryBlocks) {
1483 ::colorFunclets(F, EntryBlocks, BlockColors, FuncletBlocks);
6511484
6521485 // The processing above actually accumulated the parent set for this
6531486 // funclet into the color set for its entry; use the parent set to
6551488 // the funclet itself (no instruction can target a funclet entry except on
6561489 // that transitions to the child funclet).
6571490 for (BasicBlock *FuncletEntry : EntryBlocks) {
658 std::set &ColorMapItem = BlockColors[FuncletEntry];
659 for (BasicBlock *Parent : ColorMapItem)
660 FuncletChildren[Parent].insert(FuncletEntry);
1491 SetVector &ColorMapItem = BlockColors[FuncletEntry];
1492 // It will be rare for funclets to have multiple parents, but if any
1493 // do we need to clone the funclet later to address that. Here we
1494 // set a flag indicating that this case has arisen so that we don't
1495 // have to do a lot of checking later to handle the more common case.
1496 if (ColorMapItem.size() > 1)
1497 FuncletCloningRequired = true;
1498 for (BasicBlock *Parent : ColorMapItem) {
1499 assert(std::find(FuncletChildren[Parent].begin(),
1500 FuncletChildren[Parent].end(),
1501 FuncletEntry) == std::end(FuncletChildren[Parent]));
1502 FuncletChildren[Parent].push_back(FuncletEntry);
1503 assert(std::find(FuncletParents[FuncletEntry].begin(),
1504 FuncletParents[FuncletEntry].end(),
1505 Parent) == std::end(FuncletParents[FuncletEntry]));
1506 FuncletParents[FuncletEntry].push_back(Parent);
1507 }
6611508 ColorMapItem.clear();
6621509 ColorMapItem.insert(FuncletEntry);
6631510 }
664 }
665
666 void WinEHPrepare::colorFunclets(Function &F,
667 SmallVectorImpl &EntryBlocks) {
668 ::colorFunclets(F, EntryBlocks, BlockColors, FuncletBlocks, FuncletChildren);
6691511 }
6701512
6711513 void llvm::calculateCatchReturnSuccessorColors(const Function *Fn,
6751517 // findFuncletEntryPoints.
6761518 findFuncletEntryPoints(const_cast(*Fn), EntryBlocks);
6771519
678 std::mapstd::set> BlockColors;
1520 std::mapSetVector> BlockColors;
6791521 std::map> FuncletBlocks;
680 std::map> FuncletChildren;
6811522 // Figure out which basic blocks belong to which funclets.
6821523 colorFunclets(const_cast(*Fn), EntryBlocks, BlockColors,
683 FuncletBlocks, FuncletChildren);
1524 FuncletBlocks);
1525
1526 // The static colorFunclets routine assigns multiple colors to funclet entries
1527 // because that information is needed to calculate funclets' parent-child
1528 // relationship, but we don't need those relationship here and ultimately the
1529 // entry blocks should have the color of the funclet they begin.
1530 for (BasicBlock *FuncletEntry : EntryBlocks) {
1531 BlockColors[FuncletEntry].clear();
1532 BlockColors[FuncletEntry].insert(FuncletEntry);
1533 }
6841534
6851535 // We need to find the catchret successors. To do this, we must first find
6861536 // all the catchpad funclets.
6991549 if (!CatchReturn)
7001550 continue;
7011551 BasicBlock *CatchRetSuccessor = CatchReturn->getSuccessor();
702 std::set &SuccessorColors = BlockColors[CatchRetSuccessor];
1552 SetVector &SuccessorColors = BlockColors[CatchRetSuccessor];
7031553 assert(SuccessorColors.size() == 1 && "Expected BB to be monochrome!");
7041554 BasicBlock *Color = *SuccessorColors.begin();
7051555 // Record the catchret successor's funclet membership.
7411591 // Turn all inter-funclet uses of a Value into loads and stores.
7421592 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) {
7431593 BasicBlock *BB = &*FI++;
744 std::set &ColorsForBB = BlockColors[BB];
1594 SetVector &ColorsForBB = BlockColors[BB];
7451595 for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
7461596 Instruction *I = &*BI++;
7471597 // Funclets are permitted to use static allocas.
7561606
7571607 void WinEHPrepare::demoteArgumentUses(Function &F) {
7581608 // Also demote function parameters used in funclets.
759 std::set &ColorsForEntry = BlockColors[&F.getEntryBlock()];
1609 SetVector &ColorsForEntry = BlockColors[&F.getEntryBlock()];
7601610 for (Argument &Arg : F.args())
7611611 demoteNonlocalUses(&Arg, ColorsForEntry, F);
7621612 }
7711621
7721622 std::map Orig2Clone;
7731623 ValueToValueMapTy VMap;
774 for (BasicBlock *BB : BlocksInFunclet) {
775 std::set &ColorsForBB = BlockColors[BB];
1624 for (auto BlockIt = BlocksInFunclet.begin(),
1625 BlockEnd = BlocksInFunclet.end();
1626 BlockIt != BlockEnd;) {
1627 // Increment the iterator inside the loop because we might be removing
1628 // blocks from the set.
1629 BasicBlock *BB = *BlockIt++;
1630 SetVector &ColorsForBB = BlockColors[BB];
7761631 // We don't need to do anything if the block is monochromatic.
7771632 size_t NumColorsForBB = ColorsForBB.size();
7781633 if (NumColorsForBB == 1)
7791634 continue;
1635
1636 // If this block is a catchendpad, it shouldn't be cloned.
1637 // We will only see a catchendpad with multiple colors in the case where
1638 // some funclet has multiple parents. In that case, the color will be
1639 // resolved during the resolveFuncletAncestry processing.
1640 // For now, find the catchpad that unwinds to this block and assign
1641 // that catchpad's first parent to be the color for this block.
1642 if (isa(BB->getFirstNonPHI())) {
1643 assert(
1644 FuncletCloningRequired &&
1645 "Found multi-colored catchendpad with no multi-parent funclets.");
1646 BasicBlock *CatchParent = nullptr;
1647 // There can only be one catchpad predecessor for a catchendpad.
1648 for (BasicBlock *PredBB : predecessors(BB)) {
1649 if (isa(PredBB->getTerminator())) {
1650 CatchParent = PredBB;
1651 break;
1652 }
1653 }
1654 // There must be one catchpad predecessor for a catchendpad.
1655 assert(CatchParent && "No catchpad found for catchendpad.");
1656
1657 // If the catchpad has multiple parents, we'll clone the catchendpad
1658 // when we clone the catchpad funclet and insert it into the correct
1659 // funclet. For now, we just select the first parent of the catchpad
1660 // and give the catchendpad that color.
1661 BasicBlock *CorrectColor = FuncletParents[CatchParent].front();
1662 assert(FuncletBlocks[CorrectColor].count(BB));
1663 assert(BlockColors[BB].count(CorrectColor));
1664
1665 // Remove this block from the FuncletBlocks set of any funclet that
1666 // isn't the funclet whose color we just selected.
1667 for (auto It = BlockColors[BB].begin(), End = BlockColors[BB].end();
1668 It != End; ) {
1669 // The iterator must be incremented here because we are removing
1670 // elements from the set we're walking.
1671 auto Temp = It++;
1672 BasicBlock *ContainingFunclet = *Temp;
1673 if (ContainingFunclet != CorrectColor) {
1674 FuncletBlocks[ContainingFunclet].erase(BB);
1675 BlockColors[BB].remove(ContainingFunclet);
1676 }
1677 }
1678
1679 // This should leave just one color for BB.
1680 assert(BlockColors[BB].size() == 1);
1681 continue;
1682 }
1683
1684 DEBUG_WITH_TYPE("winehprepare-coloring",
1685 dbgs() << " Cloning block \'" << BB->getName()
1686 << "\' for funclet \'" << FuncletPadBB->getName()
1687 << "\'.\n");
7801688
7811689 // Create a new basic block and copy instructions into it!
7821690 BasicBlock *CBB =
8051713 BlocksInFunclet.insert(NewBlock);
8061714 BlockColors[NewBlock].insert(FuncletPadBB);
8071715
1716 DEBUG_WITH_TYPE("winehprepare-coloring",
1717 dbgs() << " Assigned color \'" << FuncletPadBB->getName()
1718 << "\' to block \'" << NewBlock->getName()
1719 << "\'.\n");
1720
8081721 BlocksInFunclet.erase(OldBlock);
809 BlockColors[OldBlock].erase(FuncletPadBB);
1722 BlockColors[OldBlock].remove(FuncletPadBB);
1723
1724 DEBUG_WITH_TYPE("winehprepare-coloring",
1725 dbgs() << " Removed color \'" << FuncletPadBB->getName()
1726 << "\' from block \'" << OldBlock->getName()
1727 << "\'.\n");
1728
1729 // If we are cloning a funclet that might share a child funclet with
1730 // another funclet, look to see if the cloned block is reached from a
1731 // catchret instruction. If so, save this association so we can retrieve
1732 // the possibly orphaned clone when we clone the child funclet.
1733 if (FuncletCloningRequired) {
1734 for (auto *Pred : predecessors(OldBlock)) {
1735 auto *Terminator = Pred->getTerminator();
1736 if (!isa(Terminator))
1737 continue;
1738 // If this block is reached from a catchret instruction in a funclet
1739 // that has multiple parents, it will have a color for each of those
1740 // parents. We just removed the color of one of the parents, but
1741 // the cloned block will be unreachable until we clone the child
1742 // funclet that contains the catchret instruction. In that case we
1743 // need to create a mapping that will let us find the cloned block
1744 // later and associate it with the cloned child funclet.
1745 bool BlockWillBeEstranged = false;
1746 for (auto *Color : BlockColors[Pred]) {
1747 if (FuncletParents[Color].size() > 1) {
1748 BlockWillBeEstranged = true;
1749 break; // Breaks out of the color loop
1750 }
1751 }
1752 if (BlockWillBeEstranged) {
1753 EstrangedBlocks[FuncletPadBB][OldBlock] = NewBlock;
1754 DEBUG_WITH_TYPE("winehprepare-coloring",
1755 dbgs() << " Saved mapping of estranged block \'"
1756 << NewBlock->getName() << "\' for \'"
1757 << FuncletPadBB->getName() << "\'.\n");
1758 break; // Breaks out of the predecessor loop
1759 }
1760 }
1761 }
8101762 }
8111763
8121764 // Loop over all of the instructions in this funclet, fixing up operand
8641816 for (Use &U : OldI->uses()) {
8651817 Instruction *UserI = cast(U.getUser());
8661818 BasicBlock *UserBB = UserI->getParent();
867 std::set &ColorsForUserBB = BlockColors[UserBB];
1819 SetVector &ColorsForUserBB = BlockColors[UserBB];
8681820 assert(!ColorsForUserBB.empty());
8691821 if (ColorsForUserBB.size() > 1 ||
8701822 *ColorsForUserBB.begin() != FuncletPadBB)
9931945
9941946 cloneCommonBlocks(F, EntryBlocks);
9951947
1948 resolveFuncletAncestry(F, EntryBlocks);
1949
9961950 if (!DisableCleanups) {
9971951 removeImplausibleTerminators(F);
9981952
10041958 BlockColors.clear();
10051959 FuncletBlocks.clear();
10061960 FuncletChildren.clear();
1961 FuncletParents.clear();
1962 EstrangedBlocks.clear();
1963 FuncletCloningRequired = false;
10071964
10081965 return true;
10091966 }
10982055 new StoreInst(PredVal, SpillSlot, PredBlock->getTerminator());
10992056 }
11002057
2058 // The SetVector == operator uses the std::vector == operator, so it doesn't
2059 // actually tell us whether or not the two sets contain the same colors. This
2060 // function does that.
2061 // FIXME: Would it be better to add a isSetEquivalent() method to SetVector?
2062 static bool isBlockColorSetEquivalent(SetVector &SetA,
2063 SetVector &SetB) {
2064 if (SetA.size() != SetB.size())
2065 return false;
2066 for (auto *Color : SetA)
2067 if (!SetB.count(Color))
2068 return false;
2069 return true;
2070 }
2071
11012072 // TODO: Share loads for same-funclet uses (requires dominators if funclets
11022073 // aren't properly nested).
11032074 void WinEHPrepare::demoteNonlocalUses(Value *V,
1104 std::set &ColorsForBB,
2075 SetVector &ColorsForBB,
11052076 Function &F) {
11062077 // Tokens can only be used non-locally due to control flow involving
11072078 // unreachable edges. Don't try to demote the token usage, we'll simply
11192090 // Is the Use inside a block which is colored the same as the Def?
11202091 // If so, we don't need to escape the Def because we will clone
11212092 // ourselves our own private copy.
1122 std::set &ColorsForUsingBB = BlockColors[UsingBB];
1123 if (ColorsForUsingBB == ColorsForBB)
2093 SetVector &ColorsForUsingBB = BlockColors[UsingBB];
2094 if (isBlockColorSetEquivalent(ColorsForUsingBB, ColorsForBB))
11242095 continue;
11252096
11262097 replaceUseWithLoad(V, U, SpillSlot, Loads, F);
11442115 BasicBlock *NewBlock = SplitCriticalEdge(II, SuccNum);
11452116 assert(NewBlock && "Unable to split critical edge.");
11462117 // Update the color mapping for the newly split edge.
1147 std::set &ColorsForUsingBB = BlockColors[II->getParent()];
2118 SetVector &ColorsForUsingBB = BlockColors[II->getParent()];
11482119 BlockColors[NewBlock] = ColorsForUsingBB;
11492120 for (BasicBlock *FuncletPad : ColorsForUsingBB)
11502121 FuncletBlocks[FuncletPad].insert(NewBlock);
12112182 Goto->setSuccessor(0, PHIBlock);
12122183 CatchRet->setSuccessor(NewBlock);
12132184 // Update the color mapping for the newly split edge.
1214 std::set &ColorsForPHIBlock = BlockColors[PHIBlock];
2185 SetVector &ColorsForPHIBlock = BlockColors[PHIBlock];
12152186 BlockColors[NewBlock] = ColorsForPHIBlock;
12162187 for (BasicBlock *FuncletPad : ColorsForPHIBlock)
12172188 FuncletBlocks[FuncletPad].insert(NewBlock);
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_RIGHT]]:
300 ; CHECK: catchendpad unwind to caller
301 ; CHECK: [[INNER_END_LEFT]]:
302 ; CHECK: catchendpad unwind label %[[LEFT_END]]
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_RIGHT]]:
372 ; CHECK: catchendpad unwind to caller
373 ; CHECK: [[INNER_END_LEFT]]:
374 ; CHECK: catchendpad unwind label %[[LEFT_END]]
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_RIGHT]]:
456 ; CHECK: catchendpad unwind to caller
457 ; CHECK: [[INNER_END_LEFT]]:
458 ; CHECK: catchendpad unwind label %[[LEFT_END]]
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_RIGHT]]:
532 ; CHECK: catchendpad unwind label %[[INNER_SIBLING_RIGHT:.+]]
533 ; CHECK: [[INNER_END_LEFT]]:
534 ; CHECK: catchendpad unwind label %[[INNER_SIBLING_LEFT:.+]]
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_RIGHT]]:
813 ; CHECK: catchendpad unwind to caller
814 ; CHECK: [[INNER_END_LEFT]]:
815 ; CHECK: catchendpad unwind label %[[LEFT_END]]
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_RIGHT]]:
885 ; CHECK: catchendpad unwind label %[[RIGHT_END]]
886 ; CHECK: [[INNER_END_LEFT]]:
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_RIGHT]]:
1152 ; CHECK: catchendpad unwind to caller
1153 ; CHECK: [[INNER_END_LEFT]]:
1154 ; CHECK: catchendpad unwind label %[[LEFT_END]]
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