@@ -29,6 +29,7 @@ sil @get_nativeobject_pair : $@convention(thin) () -> @owned NativeObjectPair
29
29
class Klass {}
30
30
sil @guaranteed_klass_user : $@convention(thin) (@guaranteed Klass) -> ()
31
31
sil @guaranteed_fakeoptional_klass_user : $@convention(thin) (@guaranteed FakeOptional<Klass>) -> ()
32
+ sil @guaranteed_fakeoptional_classlet_user : $@convention(thin) (@guaranteed FakeOptional<ClassLet>) -> ()
32
33
33
34
struct MyInt {
34
35
var value: Builtin.Int32
@@ -1499,4 +1500,160 @@ bb2:
1499
1500
bb3:
1500
1501
%9999 = tuple()
1501
1502
return %9999 : $()
1502
- }
1503
+ }
1504
+
1505
+ // CHECK-LABEL: sil [ossa] @convert_load_copy_to_load_borrow_despite_switch_enum_functionarg : $@convention(thin) (@guaranteed FakeOptional<ClassLet>) -> () {
1506
+ // CHECK-NOT: load [copy]
1507
+ // CHECK: load_borrow
1508
+ // CHECK-NOT: load [copy]
1509
+ // CHECK: } // end sil function 'convert_load_copy_to_load_borrow_despite_switch_enum_functionarg'
1510
+ sil [ossa] @convert_load_copy_to_load_borrow_despite_switch_enum_functionarg : $@convention(thin) (@guaranteed FakeOptional<ClassLet>) -> () {
1511
+ bb0(%0 : @guaranteed $FakeOptional<ClassLet>):
1512
+ %f = function_ref @black_hole : $@convention(thin) (@guaranteed Klass) -> ()
1513
+ switch_enum %0 : $FakeOptional<ClassLet>, case #FakeOptional.some!enumelt.1: bb1, case #FakeOptional.none!enumelt: bb2
1514
+
1515
+ bb1(%1 : @guaranteed $ClassLet):
1516
+ %2 = ref_element_addr %1 : $ClassLet, #ClassLet.aLet
1517
+ %3 = load [copy] %2 : $*Klass
1518
+ apply %f(%3) : $@convention(thin) (@guaranteed Klass) -> ()
1519
+ destroy_value %3 : $Klass
1520
+ br bb3
1521
+
1522
+ bb2:
1523
+ br bb3
1524
+
1525
+ bb3:
1526
+ %9999 = tuple()
1527
+ return %9999 : $()
1528
+ }
1529
+
1530
+ // CHECK-LABEL: sil [ossa] @convert_load_copy_to_load_borrow_despite_switch_enum_beginborrow : $@convention(thin) (@owned FakeOptional<ClassLet>) -> () {
1531
+ // CHECK-NOT: load [copy]
1532
+ // CHECK: load_borrow
1533
+ // CHECK-NOT: load [copy]
1534
+ // CHECK: } // end sil function 'convert_load_copy_to_load_borrow_despite_switch_enum_beginborrow'
1535
+ sil [ossa] @convert_load_copy_to_load_borrow_despite_switch_enum_beginborrow : $@convention(thin) (@owned FakeOptional<ClassLet>) -> () {
1536
+ bb0(%0 : @owned $FakeOptional<ClassLet>):
1537
+ %f = function_ref @black_hole : $@convention(thin) (@guaranteed Klass) -> ()
1538
+ %0a = begin_borrow %0 : $FakeOptional<ClassLet>
1539
+ switch_enum %0a : $FakeOptional<ClassLet>, case #FakeOptional.some!enumelt.1: bb1, case #FakeOptional.none!enumelt: bb2
1540
+
1541
+ bb1(%1 : @guaranteed $ClassLet):
1542
+ %2 = ref_element_addr %1 : $ClassLet, #ClassLet.aLet
1543
+ %3 = load [copy] %2 : $*Klass
1544
+ apply %f(%3) : $@convention(thin) (@guaranteed Klass) -> ()
1545
+ destroy_value %3 : $Klass
1546
+ br bb3
1547
+
1548
+ bb2:
1549
+ br bb3
1550
+
1551
+ bb3:
1552
+ end_borrow %0a : $FakeOptional<ClassLet>
1553
+ destroy_value %0 : $FakeOptional<ClassLet>
1554
+ %9999 = tuple()
1555
+ return %9999 : $()
1556
+ }
1557
+
1558
+ // CHECK-LABEL: sil [ossa] @convert_load_copy_to_load_borrow_despite_switch_enum_loadborrow : $@convention(thin) (@in_guaranteed FakeOptional<ClassLet>) -> () {
1559
+ // CHECK-NOT: load [copy]
1560
+ // CHECK: load_borrow
1561
+ // CHECK-NOT: load [copy]
1562
+ // CHECK: load_borrow
1563
+ // CHECK-NOT: load [copy]
1564
+ // CHECK: } // end sil function 'convert_load_copy_to_load_borrow_despite_switch_enum_loadborrow'
1565
+ sil [ossa] @convert_load_copy_to_load_borrow_despite_switch_enum_loadborrow : $@convention(thin) (@in_guaranteed FakeOptional<ClassLet>) -> () {
1566
+ bb0(%0 : $*FakeOptional<ClassLet>):
1567
+ %f = function_ref @black_hole : $@convention(thin) (@guaranteed Klass) -> ()
1568
+ %0a = load_borrow %0 : $*FakeOptional<ClassLet>
1569
+ switch_enum %0a : $FakeOptional<ClassLet>, case #FakeOptional.some!enumelt.1: bb1, case #FakeOptional.none!enumelt: bb2
1570
+
1571
+ bb1(%1 : @guaranteed $ClassLet):
1572
+ %2 = ref_element_addr %1 : $ClassLet, #ClassLet.aLet
1573
+ %3 = load [copy] %2 : $*Klass
1574
+ apply %f(%3) : $@convention(thin) (@guaranteed Klass) -> ()
1575
+ destroy_value %3 : $Klass
1576
+ br bb3
1577
+
1578
+ bb2:
1579
+ br bb3
1580
+
1581
+ bb3:
1582
+ end_borrow %0a : $FakeOptional<ClassLet>
1583
+ %9999 = tuple()
1584
+ return %9999 : $()
1585
+ }
1586
+
1587
+ // TODO: We can support this in a little bit once the rest of SemanticARCOpts is
1588
+ // guaranteed to be safe with guaranteed phis.
1589
+ //
1590
+ // CHECK-LABEL: sil [ossa] @convert_load_copy_to_load_borrow_despite_switch_enum_guaranteedphi_1 : $@convention(thin) (@owned FakeOptional<ClassLet>) -> () {
1591
+ // CHECK: load [copy]
1592
+ // CHECK: } // end sil function 'convert_load_copy_to_load_borrow_despite_switch_enum_guaranteedphi_1'
1593
+ sil [ossa] @convert_load_copy_to_load_borrow_despite_switch_enum_guaranteedphi_1 : $@convention(thin) (@owned FakeOptional<ClassLet>) -> () {
1594
+ bb0(%0 : @owned $FakeOptional<ClassLet>):
1595
+ %f = function_ref @black_hole : $@convention(thin) (@guaranteed Klass) -> ()
1596
+ cond_br undef, bb0a, bb0b
1597
+
1598
+ bb0a:
1599
+ %0a = begin_borrow %0 : $FakeOptional<ClassLet>
1600
+ br bb0c(%0a : $FakeOptional<ClassLet>)
1601
+
1602
+ bb0b:
1603
+ %0b = begin_borrow %0 : $FakeOptional<ClassLet>
1604
+ br bb0c(%0b : $FakeOptional<ClassLet>)
1605
+
1606
+ bb0c(%0c : @guaranteed $FakeOptional<ClassLet>):
1607
+ switch_enum %0c : $FakeOptional<ClassLet>, case #FakeOptional.some!enumelt.1: bb1, case #FakeOptional.none!enumelt: bb2
1608
+
1609
+ bb1(%1 : @guaranteed $ClassLet):
1610
+ %2 = ref_element_addr %1 : $ClassLet, #ClassLet.aLet
1611
+ %3 = load [copy] %2 : $*Klass
1612
+ apply %f(%3) : $@convention(thin) (@guaranteed Klass) -> ()
1613
+ destroy_value %3 : $Klass
1614
+ br bb3
1615
+
1616
+ bb2:
1617
+ br bb3
1618
+
1619
+ bb3:
1620
+ end_borrow %0c : $FakeOptional<ClassLet>
1621
+ destroy_value %0 : $FakeOptional<ClassLet>
1622
+ %9999 = tuple()
1623
+ return %9999 : $()
1624
+ }
1625
+
1626
+ // Make sure that if begin_borrow has a consuming end scope use, we can still
1627
+ // eliminate load [copy].
1628
+ //
1629
+ // CHECK-LABEL: sil [ossa] @convert_load_copy_to_load_borrow_despite_switch_enum_guaranteedphi_2 : $@convention(thin) (@owned FakeOptional<ClassLet>) -> () {
1630
+ // CHECK-NOT: load [copy]
1631
+ // CHECK: load_borrow
1632
+ // CHECK-NOT: load [copy]
1633
+ // CHECK: } // end sil function 'convert_load_copy_to_load_borrow_despite_switch_enum_guaranteedphi_2'
1634
+ sil [ossa] @convert_load_copy_to_load_borrow_despite_switch_enum_guaranteedphi_2 : $@convention(thin) (@owned FakeOptional<ClassLet>) -> () {
1635
+ bb0(%0 : @owned $FakeOptional<ClassLet>):
1636
+ %f = function_ref @black_hole : $@convention(thin) (@guaranteed Klass) -> ()
1637
+ cond_br undef, bb1, bb2
1638
+
1639
+ bb1:
1640
+ %0a = begin_borrow %0 : $FakeOptional<ClassLet>
1641
+ br bb3(%0a : $FakeOptional<ClassLet>)
1642
+
1643
+ bb2:
1644
+ %0b = begin_borrow %0 : $FakeOptional<ClassLet>
1645
+ %0b2 = unchecked_enum_data %0b : $FakeOptional<ClassLet>, #FakeOptional.some!enumelt.1
1646
+ %2 = ref_element_addr %0b2 : $ClassLet, #ClassLet.aLet
1647
+ %3 = load [copy] %2 : $*Klass
1648
+ apply %f(%3) : $@convention(thin) (@guaranteed Klass) -> ()
1649
+ destroy_value %3 : $Klass
1650
+ br bb3(%0b : $FakeOptional<ClassLet>)
1651
+
1652
+ bb3(%0c : @guaranteed $FakeOptional<ClassLet>):
1653
+ %f2 = function_ref @guaranteed_fakeoptional_classlet_user : $@convention(thin) (@guaranteed FakeOptional<ClassLet>) -> ()
1654
+ apply %f2(%0c) : $@convention(thin) (@guaranteed FakeOptional<ClassLet>) -> ()
1655
+ end_borrow %0c : $FakeOptional<ClassLet>
1656
+ destroy_value %0 : $FakeOptional<ClassLet>
1657
+ %9999 = tuple()
1658
+ return %9999 : $()
1659
+ }
0 commit comments