Skip to content

Commit 9f1ccde

Browse files
committed
MemoryLifetime: support select_enum_addr, existential_metatype, value_metatype, is_unique and fix_lifetime
1 parent 45f08bd commit 9f1ccde

File tree

7 files changed

+109
-5
lines changed

7 files changed

+109
-5
lines changed

lib/SIL/Verifier/MemoryLifetime.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,11 @@ bool MemoryLocations::analyzeLocationUsesRecursively(SILValue V, unsigned locIdx
330330
return false;
331331
break;
332332
case SILInstructionKind::InjectEnumAddrInst:
333+
case SILInstructionKind::SelectEnumAddrInst:
334+
case SILInstructionKind::ExistentialMetatypeInst:
335+
case SILInstructionKind::ValueMetatypeInst:
336+
case SILInstructionKind::IsUniqueInst:
337+
case SILInstructionKind::FixLifetimeInst:
333338
case SILInstructionKind::LoadInst:
334339
case SILInstructionKind::StoreInst:
335340
case SILInstructionKind::StoreBorrowInst:
@@ -1154,7 +1159,13 @@ void MemoryLifetimeVerifier::checkBlock(SILBasicBlock *block, Bits &bits) {
11541159
break;
11551160
}
11561161
case SILInstructionKind::OpenExistentialAddrInst:
1157-
requireBitsSet(bits, cast<OpenExistentialAddrInst>(&I)->getOperand(), &I);
1162+
case SILInstructionKind::SelectEnumAddrInst:
1163+
case SILInstructionKind::ExistentialMetatypeInst:
1164+
case SILInstructionKind::ValueMetatypeInst:
1165+
case SILInstructionKind::IsUniqueInst:
1166+
case SILInstructionKind::FixLifetimeInst:
1167+
case SILInstructionKind::DebugValueAddrInst:
1168+
requireBitsSet(bits, I.getOperand(0), &I);
11581169
break;
11591170
case SILInstructionKind::UncheckedTakeEnumDataAddrInst: {
11601171
// Note that despite the name, unchecked_take_enum_data_addr does _not_
@@ -1214,9 +1225,6 @@ void MemoryLifetimeVerifier::checkBlock(SILBasicBlock *block, Bits &bits) {
12141225
}
12151226
break;
12161227
}
1217-
case SILInstructionKind::DebugValueAddrInst:
1218-
requireBitsSet(bits, cast<DebugValueAddrInst>(&I)->getOperand(), &I);
1219-
break;
12201228
case SILInstructionKind::DeallocStackInst: {
12211229
SILValue opVal = cast<DeallocStackInst>(&I)->getOperand();
12221230
if (isStoreBorrowLocation(opVal)) {

lib/SILOptimizer/Transforms/DestroyHoisting.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,11 @@ void DestroyHoisting::getUsedLocationsOfInst(Bits &bits, SILInstruction *I) {
348348
// ... or abort_apply.
349349
getUsedLocationsOfOperands(bits, cast<AbortApplyInst>(I)->getBeginApply());
350350
break;
351+
case SILInstructionKind::SelectEnumAddrInst:
352+
case SILInstructionKind::ExistentialMetatypeInst:
353+
case SILInstructionKind::ValueMetatypeInst:
354+
case SILInstructionKind::IsUniqueInst:
355+
case SILInstructionKind::FixLifetimeInst:
351356
case SILInstructionKind::LoadInst:
352357
case SILInstructionKind::StoreInst:
353358
case SILInstructionKind::StoreBorrowInst:

test/SIL/memory_lifetime.sil

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,14 @@ bb0(%0 : @owned $T):
464464
return %r : $()
465465
}
466466

467+
sil [ossa] @test_select_enum_addr : $@convention(thin) (@in_guaranteed Optional<T>) -> Builtin.Int1 {
468+
bb0(%0 : $*Optional<T>):
469+
%1 = integer_literal $Builtin.Int1, -1
470+
%2 = integer_literal $Builtin.Int1, 0
471+
%3 = select_enum_addr %0 : $*Optional<T>, case #Optional.some!enumelt: %1, case #Optional.none!enumelt: %2 : $Builtin.Int1
472+
return %3 : $Builtin.Int1
473+
}
474+
467475
sil [ossa] @closure : $@convention(thin) (@in_guaranteed T) -> ()
468476

469477
sil [ossa] @test_non_escaping_closure : $@convention(thin) (@in_guaranteed T) -> () {
@@ -592,3 +600,33 @@ bb0(%0 : $*U, %1 : $*V):
592600
%5 = tuple ()
593601
return %5 : $()
594602
}
603+
604+
sil [ossa] @test_existential_metatype : $@convention(thin) (@in_guaranteed P) -> () {
605+
bb0(%0 : $*P):
606+
%714 = existential_metatype $@thick P.Type, %0 : $*P
607+
%5 = tuple ()
608+
return %5 : $()
609+
}
610+
611+
sil [ossa] @test_value_metatype : $@convention(thin) <U> (@in_guaranteed U) -> () {
612+
bb0(%0 : $*U):
613+
%1 = value_metatype $@thick U.Type, %0 : $*U
614+
%5 = tuple ()
615+
return %5 : $()
616+
}
617+
618+
sil [ossa] @test_is_unique : $@convention(thin) (@in T) -> () {
619+
bb0(%0 : $*T):
620+
%1 = is_unique %0 : $*T
621+
destroy_addr %0 : $*T
622+
%5 = tuple ()
623+
return %5 : $()
624+
}
625+
626+
sil [ossa] @test_fix_lifetime : $@convention(thin) (@in_guaranteed T) -> () {
627+
bb0(%0 : $*T):
628+
fix_lifetime %0 : $*T
629+
%5 = tuple ()
630+
return %5 : $()
631+
}
632+

test/SIL/memory_lifetime_failures.sil

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,17 @@ bb0(%0 : @owned $T):
238238
return %r : $()
239239
}
240240

241+
// CHECK: SIL memory lifetime failure in @test_select_enum_addr: memory is not initialized, but should
242+
sil [ossa] @test_select_enum_addr : $@convention(thin) () -> Builtin.Int1 {
243+
bb0:
244+
%0 = alloc_stack $Optional<T>
245+
%1 = integer_literal $Builtin.Int1, -1
246+
%2 = integer_literal $Builtin.Int1, 0
247+
%3 = select_enum_addr %0 : $*Optional<T>, case #Optional.some!enumelt: %1, case #Optional.none!enumelt: %2 : $Builtin.Int1
248+
dealloc_stack %0 : $*Optional<T>
249+
return %3 : $Builtin.Int1
250+
}
251+
241252
sil [ossa] @closure : $@convention(thin) (@in_guaranteed T) -> ()
242253

243254
// CHECK: SIL memory lifetime failure in @test_non_escaping_closure: memory is initialized at function return but shouldn't
@@ -474,3 +485,43 @@ bb0(%0 : $*U):
474485
return %5 : $()
475486
}
476487

488+
// CHECK: SIL memory lifetime failure in @test_existential_metatype: memory is not initialized, but should
489+
sil [ossa] @test_existential_metatype : $@convention(thin) () -> () {
490+
bb0:
491+
%0 = alloc_stack $P
492+
%714 = existential_metatype $@thick P.Type, %0 : $*P
493+
dealloc_stack %0 : $*P
494+
%5 = tuple ()
495+
return %5 : $()
496+
}
497+
498+
// CHECK: SIL memory lifetime failure in @test_value_metatype: memory is not initialized, but should
499+
sil [ossa] @test_value_metatype : $@convention(thin) <U> (@in_guaranteed U) -> () {
500+
bb0(%0 : $*U):
501+
%1 = alloc_stack $U
502+
%2 = value_metatype $@thick U.Type, %1 : $*U
503+
dealloc_stack %1 : $*U
504+
%5 = tuple ()
505+
return %5 : $()
506+
}
507+
508+
// CHECK: SIL memory lifetime failure in @test_is_unique: memory is not initialized, but should
509+
sil [ossa] @test_is_unique : $@convention(thin) () -> () {
510+
bb0:
511+
%0 = alloc_stack $T
512+
%1 = is_unique %0 : $*T
513+
dealloc_stack %0 : $*T
514+
%5 = tuple ()
515+
return %5 : $()
516+
}
517+
518+
// CHECK: SIL memory lifetime failure in @test_fix_lifetime: memory is not initialized, but should
519+
sil [ossa] @test_fix_lifetime : $@convention(thin) () -> () {
520+
bb0:
521+
%0 = alloc_stack $T
522+
fix_lifetime %0 : $*T
523+
dealloc_stack %0 : $*T
524+
%5 = tuple ()
525+
return %5 : $()
526+
}
527+

test/SILOptimizer/cse_objc_ossa.sil

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ bb0(%0 : @owned $B, %1 : @owned $B):
260260
store %1 to [assign] %3 : $*B
261261
%7 = existential_metatype $@thick Any.Type, %2 : $*Any
262262
%99 = tuple (%5 : $@thick Any.Type, %7 : $@thick Any.Type)
263+
destroy_addr %2 : $*Any
263264
dealloc_stack %2 : $*Any
264265
return %99 : $(@thick Any.Type, @thick Any.Type)
265266
}

test/SILOptimizer/sil_combine_enum_addr_ossa.sil

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ bb0(%0 : $*Int, %1 : $*_Stdout, %1a : $*CustomStringConvertible):
2929
cond_br %13, bb2, bb1a
3030

3131
bb1a:
32+
destroy_addr %3 : $*Optional<CustomStringConvertible>
3233
copy_addr %1a to [initialization] %2 : $*CustomStringConvertible
3334
br bb1
3435

test/SILOptimizer/sil_combine_enums_ossa.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ enum G<T> {
130130
// CHECK-LABEL: sil [ossa] @canonicalize_select_enum_addr :
131131
// CHECK: select_enum_addr {{.*}} case #G.E2!enumelt:
132132
// CHECK: } // end sil function 'canonicalize_select_enum_addr'
133-
sil [ossa] @canonicalize_select_enum_addr : $@convention(thin) <T> (@in G<T>) -> Int32 {
133+
sil [ossa] @canonicalize_select_enum_addr : $@convention(thin) <T> (@in_guaranteed G<T>) -> Int32 {
134134
bb0(%0 : $*G<T>):
135135
%2 = integer_literal $Builtin.Int32, 0
136136
%3 = integer_literal $Builtin.Int32, 1

0 commit comments

Comments
 (0)