Commit b575e5a
committed
Fix OwnershipLiveRange for @owned values getting transformed to none values via switch_enum
rdar://95039799
We are currently not computing OwnershipLiveRange correctly in the presence of switch_enum transforming the owned value to a none value.
We can end up with illegal SIL with LoadCopyToLoadBorrowOptimization, due to this.
Example:
sil [ossa] @switch_enum_test : $@convention(thin) (@inout StructWithEnum) -> () {
bb0(%0 : $*StructWithEnum):
%1 = struct_element_addr %0 : $*StructWithEnum, #StructWithEnum.val
%2 = struct_element_addr %0 : $*StructWithEnum, #StructWithEnum.val
%3 = load [copy] %2 : $*EnumA
destroy_addr %1 : $*EnumA
switch_enum %3 : $EnumA, case #EnumA.sometrivial!enumelt: bb1, case #EnumA.somenontrivial!enumelt:bb2, case #EnumA.none!enumelt: bb3
bb1(%6 : $TrivialStruct):
%f = function_ref @get_enum : $@convention(thin) () -> @owned EnumA
%r = apply %f() : $@convention(thin) () -> @owned EnumA
%ele = struct_element_addr %0 : $*StructWithEnum, #StructWithEnum.val
store %r to [init] %ele :$*EnumA
%9999 = tuple()
return %9999 : $()
bb2(%7 : @owned $NonTrivialStruct):
unreachable
bb3:
unreachable
}
can get transformed to:
sil [ossa] @switch_enum_test : $@convention(thin) (@inout StructWithEnum) -> () {
bb0(%0 : $*StructWithEnum):
%1 = struct_element_addr %0 : $*StructWithEnum, #StructWithEnum.val
%2 = struct_element_addr %0 : $*StructWithEnum, #StructWithEnum.val
%3 = load_borrow %2 : $*EnumA
destroy_addr %1 : $*EnumA
switch_enum %3 : $EnumA, case #EnumA.sometrivial!enumelt: bb1, case #EnumA.somenontrivial!enumelt: bb2, case #EnumA.none!enumelt: bb3
bb1(%6 : $TrivialStruct):
end_borrow %3 : $EnumA
%8 = function_ref @get_enum : $@convention(thin) () -> @owned EnumA
%9 = apply %8() : $@convention(thin) () -> @owned EnumA
%10 = struct_element_addr %0 : $*StructWithEnum, #StructWithEnum.val
store %9 to [init] %10 : $*EnumA
%12 = tuple ()
return %12 : $()
bb2(%14 : @guaranteed $NonTrivialStruct):
unreachable
bb3:
unreachable
}
which is incorrect:
Write: destroy_addr %1 : $*EnumA
SIL verification failed: Found load borrow that is invalidated by a local write?!: loadBorrowImmutabilityAnalysis.isImmutable(LBI)
Verifying instruction:
%2 = struct_element_addr %0 : $*StructWithEnum, #StructWithEnum.val
-> %3 = load_borrow %2 : $*EnumA
switch_enum %3 : $EnumA, case #EnumA.sometrivial!enumelt: bb1, case #EnumA.somenontrivial!enumelt: bb2, case #EnumA.none!enumelt: bb3
end_borrow %3 : $EnumA1 parent 8e4c2c0 commit b575e5a
File tree
2 files changed
+45
-2
lines changed- lib/SILOptimizer/SemanticARC
- test/SILOptimizer
2 files changed
+45
-2
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
124 | 124 | | |
125 | 125 | | |
126 | 126 | | |
127 | | - | |
128 | | - | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
129 | 133 | | |
| 134 | + | |
130 | 135 | | |
131 | 136 | | |
132 | 137 | | |
| |||
Lines changed: 38 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| 30 | + | |
30 | 31 | | |
31 | 32 | | |
32 | 33 | | |
| |||
104 | 105 | | |
105 | 106 | | |
106 | 107 | | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
107 | 120 | | |
108 | 121 | | |
109 | 122 | | |
| |||
1514 | 1527 | | |
1515 | 1528 | | |
1516 | 1529 | | |
| 1530 | + | |
| 1531 | + | |
| 1532 | + | |
| 1533 | + | |
| 1534 | + | |
| 1535 | + | |
| 1536 | + | |
| 1537 | + | |
| 1538 | + | |
| 1539 | + | |
| 1540 | + | |
| 1541 | + | |
| 1542 | + | |
| 1543 | + | |
| 1544 | + | |
| 1545 | + | |
| 1546 | + | |
| 1547 | + | |
| 1548 | + | |
| 1549 | + | |
| 1550 | + | |
| 1551 | + | |
| 1552 | + | |
| 1553 | + | |
| 1554 | + | |
0 commit comments