Skip to content

Commit 7753b0f

Browse files
committed
[LICM] Bail on unrefable storage.
When computing an access path, if a struct with unreferenceable storage is encountered, bail out. Otherwise, an attempt will be made to construct such a struct via the struct instruction which isn't possible. rdar://127013278
1 parent 8981f2d commit 7753b0f

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

lib/SILOptimizer/LoopTransforms/LICM.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,8 +1048,13 @@ computeInnerAccessPath(AccessPath::PathNode outerPath,
10481048
if (outerPath == innerPath)
10491049
return true;
10501050

1051-
if (!isa<StructElementAddrInst>(innerAddress)
1052-
&& !isa<TupleElementAddrInst>(innerAddress)) {
1051+
auto *sea = dyn_cast<StructElementAddrInst>(innerAddress);
1052+
1053+
if (sea && sea->getStructDecl()->hasUnreferenceableStorage()) {
1054+
return false;
1055+
}
1056+
1057+
if (!sea && !isa<TupleElementAddrInst>(innerAddress)) {
10531058
return false;
10541059
}
10551060
assert(ProjectionIndex(innerAddress).Index
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// RUN: %target-sil-opt -enable-sil-verify-all %s -licm | %FileCheck %s
2+
3+
// REQUIRES: objc_interop
4+
5+
//--- input.sil
6+
sil_stage canonical
7+
8+
import Builtin
9+
import Swift
10+
import Foundation
11+
12+
typealias Mantissa = (UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16)
13+
14+
// CHECK-LABEL: sil @struct_extract_from_decimal : {{.*}} {
15+
// CHECK: bb0([[POINTER:%[^,]+]] :
16+
// CHECK-SAME: [[NEW_MANTISSA:%[^,]+]] :
17+
// CHECK: [[ADDR:%[^,]+]] = pointer_to_address [[POINTER]]
18+
// CHECK: [[A_ADDR:%[^,]+]] = struct_element_addr [[ADDR]]
19+
// CHECK-SAME: #Decimal._mantissa
20+
// CHECK: br [[BODY:bb[0-9]+]]
21+
// CHECK: [[BODY]]:
22+
// CHECK: [[VALUE_2:%[^,]+]] = load [[ADDR]] : $*Decimal
23+
// CHECK: [[MANTISSA:%[^,]+]] = struct_extract [[VALUE_2]]
24+
// CHECK-SAME: #Decimal._mantissa
25+
// CHECK: store [[NEW_MANTISSA]] to [[A_ADDR]]
26+
// CHECK: cond_br undef, [[BACKEDGE:bb[0-9]+]], [[EXIT:bb[0-9]+]]
27+
// CHECK: [[BACKEDGE]]:
28+
// CHECK: br [[BODY]]
29+
// CHECK: [[EXIT]]:
30+
// CHECK: return [[MANTISSA]]
31+
// CHECK-LABEL: } // end sil function 'struct_extract_from_decimal'
32+
sil @struct_extract_from_decimal : $@convention(thin) (Builtin.RawPointer, Mantissa) -> (Mantissa) {
33+
bb0(%pointer : $Builtin.RawPointer, %newMantissa : $Mantissa):
34+
%addr = pointer_to_address %pointer : $Builtin.RawPointer to $*Decimal
35+
br bb1
36+
37+
bb1:
38+
%value2 = load %addr : $*Decimal
39+
%a = struct_extract %value2 : $Decimal, #Decimal._mantissa
40+
%a_addr = struct_element_addr %addr : $*Decimal, #Decimal._mantissa
41+
store %newMantissa to %a_addr : $*Mantissa
42+
cond_br undef, bb2, bb3
43+
44+
bb2:
45+
br bb1
46+
47+
bb3:
48+
return %a : $Mantissa
49+
}

0 commit comments

Comments
 (0)