Skip to content

Commit 1daa09e

Browse files
authored
Merge pull request swiftlang#30770 from eeckstein/fix-escape-analysis
EscapeAnalysis: fix a problem with unchecked_addr_cast
2 parents 59368a6 + 5a5cbf7 commit 1daa09e

File tree

4 files changed

+67
-1
lines changed

4 files changed

+67
-1
lines changed

lib/SILOptimizer/Analysis/EscapeAnalysis.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ SILValue EscapeAnalysis::getPointerBase(SILValue value) {
141141
case ValueKind::RefToRawPointerInst:
142142
case ValueKind::RefToBridgeObjectInst:
143143
case ValueKind::BridgeObjectToRefInst:
144-
case ValueKind::UncheckedAddrCastInst:
145144
case ValueKind::UnconditionalCheckedCastInst:
146145
// DO NOT use LOADABLE_REF_STORAGE because unchecked references don't have
147146
// retain/release instructions that trigger the 'default' case.
@@ -151,6 +150,20 @@ SILValue EscapeAnalysis::getPointerBase(SILValue value) {
151150
#include "swift/AST/ReferenceStorage.def"
152151
return cast<SingleValueInstruction>(value)->getOperand(0);
153152

153+
case ValueKind::UncheckedAddrCastInst: {
154+
auto *uac = cast<UncheckedAddrCastInst>(value);
155+
SILValue op = uac->getOperand();
156+
SILType srcTy = op->getType().getObjectType();
157+
SILType destTy = value->getType().getObjectType();
158+
SILFunction *f = uac->getFunction();
159+
// If the source and destination of the cast don't agree on being a pointer,
160+
// we bail. Otherwise we would miss important edges in the connection graph:
161+
// e.g. loads of non-pointers are ignored, while it could be an escape of
162+
// the value (which could be a pointer before the cast).
163+
if (findCachedPointerKind(srcTy, *f) != findCachedPointerKind(destTy, *f))
164+
return SILValue();
165+
return op;
166+
}
154167
case ValueKind::TupleExtractInst: {
155168
auto *TEI = cast<TupleExtractInst>(value);
156169
// Special handling for extracting the pointer-result from an
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
struct S {
2+
int i;
3+
};
4+
5+
union U {
6+
struct S *p;
7+
};
8+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift -O %s -import-objc-header %S/Inputs/dse_with_union.h -o %t/a.out
3+
// RUN: %target-run %t/a.out | %FileCheck %s
4+
5+
// REQUIRES: executable_test
6+
7+
// Check that EscapeAnalysis does not mess up with a union.
8+
9+
@inline(never)
10+
func printit(_ u: inout U) {
11+
print(u.p![0])
12+
}
13+
14+
@inline(never)
15+
func testit(s: S) {
16+
var vs = s
17+
withUnsafeMutablePointer(to: &vs) {
18+
// A C union is an opaque type in swift and not considered as a "pointer"
19+
// in escape analysis. Converting between pointer and non-pointer resulted
20+
// in a wrong connection graph.
21+
var u = U(p: $0)
22+
printit(&u)
23+
}
24+
}
25+
26+
// CHECK: S(i: 27)
27+
testit(s: S(i: 27))
28+

test/SILOptimizer/escape_analysis.sil

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,6 +1127,23 @@ bb0(%0 : $*U, %1 : $*T, %2 : $@thick U.Type):
11271127
return %5 : $()
11281128
}
11291129

1130+
// CHECK-LABEL: CG of test_unchecked_addr_cast
1131+
// CHECK-NEXT: Arg [ref] %0 Esc: G, Succ:
1132+
// CHECK-NEXT: Val %1 Esc: , Succ: (%1.1)
1133+
// CHECK-NEXT: Con [ref] %1.1 Esc: G, Succ:
1134+
// CHECK-NEXT: Val %2 Esc: , Succ: (%2.1)
1135+
// CHECK-NEXT: Con [ref] %2.1 Esc: G, Succ: %0
1136+
// CHECK-NEXT: End
1137+
sil @test_unchecked_addr_cast : $@convention(thin) (@guaranteed AnyObject) -> Int {
1138+
bb0(%0 : $AnyObject):
1139+
%1 = alloc_stack $Int
1140+
%2 = unchecked_addr_cast %1 : $*Int to $*AnyObject
1141+
store %0 to %2 : $*AnyObject
1142+
%4 = load %1 : $*Int
1143+
dealloc_stack %1 : $*Int
1144+
return %4 : $Int
1145+
}
1146+
11301147
sil_global @global_y : $SomeData
11311148

11321149
// CHECK-LABEL: CG of test_node_merge_during_struct_inst

0 commit comments

Comments
 (0)