@@ -1878,14 +1878,38 @@ static bool onlyForwardsNone(SILBasicBlock *noneBB, SILBasicBlock *someBB,
1878
1878
// / \ ... (more bbs?)
1879
1879
// / \ /
1880
1880
// / ulimateBB
1881
- static bool hasSameUlitmateSuccessor (SILBasicBlock *noneBB, SILBasicBlock *someBB) {
1881
+ static bool hasSameUltimateSuccessor (SILBasicBlock *noneBB, SILBasicBlock *someBB) {
1882
+ // Make sure that both our some, none blocks both have single successors that
1883
+ // are not themselves (which can happen due to single block loops).
1882
1884
auto *someSuccessorBB = someBB->getSingleSuccessorBlock ();
1883
- if (!someSuccessorBB)
1885
+ if (!someSuccessorBB || someSuccessorBB == someBB )
1884
1886
return false ;
1885
1887
auto *noneSuccessorBB = noneBB->getSingleSuccessorBlock ();
1886
- while (noneSuccessorBB != nullptr && noneSuccessorBB != someSuccessorBB)
1887
- noneSuccessorBB = noneSuccessorBB->getSingleSuccessorBlock ();
1888
- return noneSuccessorBB == someSuccessorBB;
1888
+ if (!noneSuccessorBB || noneSuccessorBB == noneBB)
1889
+ return false ;
1890
+
1891
+ // If we immediately find a diamond, return true. We are done.
1892
+ if (noneSuccessorBB == someSuccessorBB)
1893
+ return true ;
1894
+
1895
+ // Otherwise, lets keep looking down the none case.
1896
+ auto *next = noneSuccessorBB;
1897
+ while (next != someSuccessorBB) {
1898
+ noneSuccessorBB = next;
1899
+ next = noneSuccessorBB->getSingleSuccessorBlock ();
1900
+
1901
+ // If we find another single successor and it is not our own block (due to a
1902
+ // self-loop), continue.
1903
+ if (next && next != noneSuccessorBB)
1904
+ continue ;
1905
+
1906
+ // Otherwise, we either have multiple successors or a self-loop. We do not
1907
+ // support this, return false.
1908
+ return false ;
1909
+ }
1910
+
1911
+ // At this point, we know that next must be someSuccessorBB.
1912
+ return true ;
1889
1913
}
1890
1914
1891
1915
// / Simplify switch_enums on class enums that branch to objc_method calls on
@@ -1920,7 +1944,7 @@ bool SimplifyCFG::simplifySwitchEnumOnObjcClassOptional(SwitchEnumInst *SEI) {
1920
1944
if (SEI->getCaseDestination (someDecl) != someBB)
1921
1945
std::swap (someBB, noneBB);
1922
1946
1923
- if (!hasSameUlitmateSuccessor (noneBB, someBB))
1947
+ if (!hasSameUltimateSuccessor (noneBB, someBB))
1924
1948
return false ;
1925
1949
1926
1950
if (!onlyForwardsNone (noneBB, someBB, SEI))
0 commit comments