Skip to content

Commit 253f730

Browse files
authored
Merge pull request #80506 from eeckstein/fix-simplify-alloc-stack
Fix two bugs in alloc_stack simplification
2 parents a452a41 + f495597 commit 253f730

File tree

6 files changed

+33
-7
lines changed

6 files changed

+33
-7
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyAllocStack.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,11 +257,15 @@ private extension AllocStackInst {
257257
case is CheckedCastAddrBranchInst, is UnconditionalCheckedCastAddrInst:
258258
// To construct a new cast instruction we need a formal type.
259259
requiresLegalFormalType = true
260-
fallthrough
261-
case is UncheckedAddrCastInst:
262260
if use != use.instruction.operands[0] {
263261
return nil
264262
}
263+
case is UncheckedAddrCastInst:
264+
if self.type.isExistential {
265+
// Bail if the address of the original existential escapes.
266+
// This is not a problem if the alloc_stack already contains the opened existential.
267+
return nil
268+
}
265269
default:
266270
return nil
267271
}

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,7 @@ final public class AllocStackInst : SingleValueInstruction, Allocation, DebugVar
13461346
public var hasDynamicLifetime: Bool { bridged.AllocStackInst_hasDynamicLifetime() }
13471347
public var isFromVarDecl: Bool { bridged.AllocStackInst_isFromVarDecl() }
13481348
public var usesMoveableValueDebugInfo: Bool { bridged.AllocStackInst_usesMoveableValueDebugInfo() }
1349+
public override var isLexical: Bool { bridged.AllocStackInst_isLexical() }
13491350

13501351
public var varDecl: VarDecl? {
13511352
bridged.AllocStack_getDecl().getAs(VarDecl.self)

include/swift/SIL/SILBridging.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,7 @@ struct BridgedInstruction {
772772
BRIDGED_INLINE bool AllocStackInst_hasDynamicLifetime() const;
773773
BRIDGED_INLINE bool AllocStackInst_isFromVarDecl() const;
774774
BRIDGED_INLINE bool AllocStackInst_usesMoveableValueDebugInfo() const;
775+
BRIDGED_INLINE bool AllocStackInst_isLexical() const;
775776
BRIDGED_INLINE bool AllocRefInstBase_isObjc() const;
776777
BRIDGED_INLINE bool AllocRefInstBase_canAllocOnStack() const;
777778
BRIDGED_INLINE SwiftInt AllocRefInstBase_getNumTailTypes() const;

include/swift/SIL/SILBridgingImpl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,6 +1305,10 @@ bool BridgedInstruction::AllocStackInst_usesMoveableValueDebugInfo() const {
13051305
return getAs<swift::AllocStackInst>()->usesMoveableValueDebugInfo();
13061306
}
13071307

1308+
bool BridgedInstruction::AllocStackInst_isLexical() const {
1309+
return getAs<swift::AllocStackInst>()->isLexical();
1310+
}
1311+
13081312
bool BridgedInstruction::AllocRefInstBase_isObjc() const {
13091313
return getAs<swift::AllocRefInstBase>()->isObjC();
13101314
}

test/SILOptimizer/sil_combine_concrete_existential_noncopyable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public struct S: P {
1111
}
1212

1313
// CHECK-LABEL: sil @$s44sil_combine_concrete_existential_noncopyable1gyyF : $@convention(thin) () -> () {
14-
// CHECK: [[S_ADDR:%.*]] = alloc_stack [var_decl] $S
14+
// CHECK: [[S_ADDR:%.*]] = alloc_stack [lexical] [var_decl] $S
1515
// CHECK: [[INIT_FN:%.*]] = function_ref @$s44sil_combine_concrete_existential_noncopyable1SVACycfC : $@convention(method) (@thin S.Type) -> S
1616
// CHECK: [[S:%.*]] = apply [[INIT_FN]]({{%.*}}) : $@convention(method) (@thin S.Type) -> S
1717
// CHECK: store [[S]] to [[S_ADDR]]

test/SILOptimizer/simplify_alloc_stack.sil

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ sil [ossa] @use_mp : $@convention(thin) (@in_guaranteed MP) -> ()
4141
sil [ossa] @use_c2 : $@convention(thin) (@in_guaranteed C2) -> ()
4242

4343
// CHECK-LABEL: sil [ossa] @expand_alloc_stack_of_enum1 :
44-
// CHECK: [[A:%[0-9]+]] = alloc_stack $S
44+
// CHECK: [[A:%[0-9]+]] = alloc_stack [lexical] $S
4545
// CHECK: bb1:
4646
// CHECK-NEXT: store %0 to [trivial] [[A]]
4747
// CHECK: bb2:
@@ -51,7 +51,7 @@ sil [ossa] @use_c2 : $@convention(thin) (@in_guaranteed C2) -> ()
5151
// CHECK: } // end sil function 'expand_alloc_stack_of_enum1'
5252
sil [ossa] @expand_alloc_stack_of_enum1 : $@convention(method) (S) -> () {
5353
bb0(%0 : $S):
54-
%1 = alloc_stack $MP
54+
%1 = alloc_stack [lexical] $MP
5555
cond_br undef, bb1, bb2
5656

5757
bb1:
@@ -215,7 +215,7 @@ bb0(%0 : $S):
215215
}
216216

217217
// CHECK-LABEL: sil [ossa] @replace_archetype :
218-
// CHECK: [[S:%.*]] = alloc_stack $T
218+
// CHECK: [[S:%.*]] = alloc_stack [lexical] $T
219219
// CHECK: debug_value [[S]]
220220
// CHECK: unchecked_addr_cast [[S]]
221221
// CHECK: destroy_addr [[S]]
@@ -225,7 +225,7 @@ bb0(%0 : @owned $T):
225225
%1 = metatype $@thick T.Type
226226
%2 = init_existential_metatype %1, $@thick P.Type
227227
%3 = open_existential_metatype %2 to $@thick (@opened("82105EE0-DCB0-11E5-865D-C8E0EB309913", P) Self).Type
228-
%4 = alloc_stack $@opened("82105EE0-DCB0-11E5-865D-C8E0EB309913", P) Self
228+
%4 = alloc_stack [lexical] $@opened("82105EE0-DCB0-11E5-865D-C8E0EB309913", P) Self
229229
debug_value %4, var, name "x"
230230
%5 = unchecked_addr_cast %4 to $*T
231231
store %0 to [init] %5
@@ -365,3 +365,19 @@ bb0(%0 : @owned $C2):
365365
dealloc_stack %1
366366
return %5
367367
}
368+
369+
// CHECK-LABEL: sil [ossa] @dont_replace_existential_with_escaping_addr :
370+
// CHECK: alloc_stack $any P
371+
// CHECK: } // end sil function 'dont_replace_existential_with_escaping_addr'
372+
sil [ossa] @dont_replace_existential_with_escaping_addr : $@convention(thin) <V> (@thick V.Type, @owned C2) -> @out V {
373+
bb0(%0 : $*V, %1 : $@thick V.Type, %2 : @owned $C2):
374+
%114 = alloc_stack $any P
375+
%117 = init_existential_addr %114, $C2
376+
store %2 to [init] %117
377+
%129 = unchecked_addr_cast %114 to $*V
378+
copy_addr %129 to [init] %0
379+
destroy_addr %114
380+
dealloc_stack %114
381+
%137 = tuple ()
382+
return %137
383+
}

0 commit comments

Comments
 (0)