@@ -9,6 +9,7 @@ import Builtin
9
9
//////////////////
10
10
11
11
typealias AnyObject = Builtin.AnyObject
12
+ protocol Error {}
12
13
13
14
enum MyNever {}
14
15
enum FakeOptional<T> {
@@ -1525,3 +1526,107 @@ bb3(%7 : @owned $FakeOptional<Builtin.NativeObject>):
1525
1526
%9999 = tuple()
1526
1527
return %9999 : $()
1527
1528
}
1529
+
1530
+ // SemanticARCOptVisitor::performGuaranteedCopyValueOptimization should not optimize this case.
1531
+ //
1532
+ // CHECK-LABEL: sil [ossa] @testDeadInterleavedBorrow : $@convention(c) (@owned FakeOptional<AnyObject>) -> () {
1533
+ // CHECK: [[B:%.*]] = begin_borrow [lexical] %0 : $FakeOptional<AnyObject>
1534
+ // CHECK: copy_value
1535
+ // CHECK: switch_enum
1536
+ // CHECK: bb{{.*}}([[COPY:%.*]] : @owned $AnyObject):
1537
+ // CHECK: begin_borrow [lexical] [[COPY]] : $AnyObject
1538
+ // CHECK: end_borrow [[B]] : $FakeOptional<AnyObject>
1539
+ // CHECK: end_borrow
1540
+ // CHECK: destroy_value [[COPY]] : $AnyObject
1541
+ // CHECK-LABEL: } // end sil function 'testDeadInterleavedBorrow'
1542
+ sil [ossa] @testDeadInterleavedBorrow : $@convention(c) (@owned FakeOptional<AnyObject>) -> () {
1543
+ bb0(%opt : @owned $FakeOptional<AnyObject>):
1544
+ %opt_borrow = begin_borrow [lexical] %opt : $FakeOptional<AnyObject>
1545
+ %opt_borrow_copy = copy_value %opt_borrow : $FakeOptional<AnyObject>
1546
+ switch_enum %opt_borrow_copy : $FakeOptional<AnyObject>, case #FakeOptional.some!enumelt: some, case #FakeOptional.none!enumelt: none
1547
+
1548
+ some(%obj : @owned $AnyObject):
1549
+ %_borrow = begin_borrow [lexical] %obj : $AnyObject
1550
+ end_borrow %opt_borrow : $FakeOptional<AnyObject>
1551
+ end_borrow %_borrow : $AnyObject
1552
+ destroy_value %obj : $AnyObject
1553
+ br die
1554
+
1555
+ die:
1556
+ unreachable
1557
+
1558
+ none:
1559
+ end_borrow %opt_borrow : $FakeOptional<AnyObject>
1560
+ br exit
1561
+
1562
+ exit:
1563
+ destroy_value %opt : $FakeOptional<AnyObject>
1564
+ %res = tuple ()
1565
+ return %res : $()
1566
+ }
1567
+
1568
+ // SemanticARCOptVisitor::performGuaranteedCopyValueOptimization should not optimize this case.
1569
+ //
1570
+ // CHECK-LABEL: sil [ossa] @testDeadAndAliveInterleavedBorrow : $@convention(c) (@owned FakeOptional<AnyObject>) -> () {
1571
+ // CHECK: [[B:%.*]] = begin_borrow [lexical] %0 : $FakeOptional<AnyObject>
1572
+ // CHECK: copy_value
1573
+ // CHECK: switch_enum
1574
+ //
1575
+ // CHECK: bb{{.*}}([[COPY:%.*]] : @owned $AnyObject):
1576
+ // CHECK: [[BB:%.*]] = begin_borrow [lexical] [[COPY]] : $AnyObject
1577
+ //
1578
+ // CHECK: try_apply undef
1579
+ //
1580
+ // CHECK: [[RESULT:%.*]] = apply undef(%{{.*}}) : $@convention(method) (@guaranteed AnyObject) -> @owned FakeOptional<AnyObject>
1581
+ // CHECK: switch_enum [[RESULT]] : $FakeOptional<AnyObject>, case #FakeOptional.some!enumelt: {{.*}}, case #FakeOptional.none!enumelt: [[NONEBB:bb[0-9]?]]
1582
+ //
1583
+ // CHECK: [[NONEBB]]:
1584
+ // CHECK: end_borrow [[B]] : $FakeOptional<AnyObject>
1585
+ // CHECK: end_borrow [[BB]] : $AnyObject
1586
+ // CHECK: destroy_value [[COPY]] : $AnyObject
1587
+ // CHECK: destroy_value %0 : $FakeOptional<AnyObject>
1588
+ // CHECK-LABEL: } // end sil function 'testDeadAndAliveInterleavedBorrow'
1589
+ sil [ossa] @testDeadAndAliveInterleavedBorrow : $@convention(c) (@owned FakeOptional<AnyObject>) -> () {
1590
+ bb0(%opt : @owned $FakeOptional<AnyObject>):
1591
+ %opt_borrow = begin_borrow [lexical] %opt : $FakeOptional<AnyObject>
1592
+ %opt_borrow_copy = copy_value %opt_borrow : $FakeOptional<AnyObject>
1593
+ switch_enum %opt_borrow_copy : $FakeOptional<AnyObject>, case #FakeOptional.some!enumelt: some, case #FakeOptional.none!enumelt: none
1594
+
1595
+ some(%obj : @owned $AnyObject):
1596
+ %obj_borrow = begin_borrow [lexical] %obj : $AnyObject
1597
+ %obj_borrow_copy = copy_value %obj_borrow : $AnyObject
1598
+ try_apply undef(%obj_borrow_copy) : $@convention(method) (@owned AnyObject) -> (@owned AnyObject, @error Error), normal good, error bad
1599
+
1600
+ good(%obj2 : @owned $AnyObject):
1601
+ %obj3 = apply undef(%obj2) : $@convention(method) (@guaranteed AnyObject) -> @owned FakeOptional<AnyObject>
1602
+ destroy_value %obj2 : $AnyObject
1603
+ switch_enum %obj3 : $FakeOptional<AnyObject>, case #FakeOptional.some!enumelt: good_some, case #FakeOptional.none!enumelt: good_none
1604
+
1605
+ good_some(%obj4 : @owned $AnyObject):
1606
+ destroy_value %obj4 : $AnyObject
1607
+ end_borrow %obj_borrow : $AnyObject
1608
+ destroy_value %obj : $AnyObject
1609
+ br exit
1610
+
1611
+ good_none:
1612
+ end_borrow %opt_borrow : $FakeOptional<AnyObject>
1613
+ end_borrow %obj_borrow : $AnyObject
1614
+ destroy_value %obj : $AnyObject
1615
+ destroy_value %opt : $FakeOptional<AnyObject>
1616
+ br die
1617
+
1618
+ bad(%error1 : @owned $Error):
1619
+ br die
1620
+
1621
+ die:
1622
+ unreachable
1623
+
1624
+ none:
1625
+ br exit
1626
+
1627
+ exit:
1628
+ end_borrow %opt_borrow : $FakeOptional<AnyObject>
1629
+ destroy_value %opt : $FakeOptional<AnyObject>
1630
+ %res = tuple ()
1631
+ return %res : $()
1632
+ }
0 commit comments