mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
I also removed the -verify-sil-ownership flag in favor of a disable flag -disable-sil-ownership-verifier. I used this on only two tests that still need work to get them to pass with ownership, but whose problems are well understood, small corner cases. I am going to fix them in follow on commits. I detail them below: 1. SILOptimizer/definite_init_inout_super_init.swift. This is a test case where DI is supposed to error. The only problem is that we crash before we error since the code emitting by SILGen to trigger this error does not pass ownership invariants. I have spoken with JoeG about this and he suggested that I fix this earlier in the compiler. Since we do not run the ownership verifier without asserts enabled, this should not affect compiler users. Given that it has triggered DI errors previously I think it is safe to disable ownership here. 2. PrintAsObjC/extensions.swift. In this case, the signature generated by type lowering for one of the thunks here uses an unsafe +0 return value instead of doing an autorelease return. The ownership checker rightly flags this leak. This is going to require either an AST level change or a change to TypeLowering. I think it is safe to turn this off since it is such a corner case that it was found by a test that has nothing to do with it. rdar://43398898
519 lines
18 KiB
Plaintext
519 lines
18 KiB
Plaintext
// RUN: %target-sil-opt -inline -verify %s | %FileCheck %s
|
|
// RUN: %target-sil-opt -mandatory-inlining -verify %s | %FileCheck %s
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
sil @marker : $(Builtin.Int32) -> ()
|
|
|
|
class SomeClass {}
|
|
sil_vtable SomeClass {}
|
|
|
|
class SomeSubclass : SomeClass {}
|
|
sil_vtable SomeSubclass {}
|
|
|
|
// This is designed to be formally indirect.
|
|
struct Indirect<T: AnyObject> {
|
|
var x: Any
|
|
var y: T
|
|
}
|
|
|
|
sil @make_indirect : $<T: SomeClass> () -> (@out Indirect<T>)
|
|
|
|
sil [transparent] [ossa] @test_one_yield : $@yield_once <C: SomeClass> () -> (@yields @in Indirect<C>) {
|
|
entry:
|
|
%marker = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()
|
|
%1000 = integer_literal $Builtin.Int32, 1000
|
|
apply %marker(%1000) : $@convention(thin) (Builtin.Int32) -> ()
|
|
%temp = alloc_stack $Indirect<C>
|
|
%make = function_ref @make_indirect : $@convention(thin) <T: SomeClass> () -> (@out Indirect<T>)
|
|
apply %make<C>(%temp) : $@convention(thin) <T: SomeClass> () -> (@out Indirect<T>)
|
|
yield %temp : $*Indirect<C>, resume resume, unwind unwind
|
|
|
|
resume:
|
|
%2000 = integer_literal $Builtin.Int32, 2000
|
|
apply %marker(%2000) : $@convention(thin) (Builtin.Int32) -> ()
|
|
dealloc_stack %temp : $*Indirect<C>
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
|
|
unwind:
|
|
%3000 = integer_literal $Builtin.Int32, 3000
|
|
apply %marker(%3000) : $@convention(thin) (Builtin.Int32) -> ()
|
|
dealloc_stack %temp : $*Indirect<C>
|
|
unwind
|
|
}
|
|
|
|
// CHECK-LABEL: sil @test_simple_call
|
|
// CHECK: bb0(%0 : $Builtin.Int1):
|
|
// CHECK: [[MARKER:%.*]] = function_ref @marker
|
|
// CHECK: [[MARKER2:%.*]] = function_ref @marker
|
|
// CHECK: [[I:%.*]] = integer_literal $Builtin.Int32, 1000
|
|
// CHECK: apply [[MARKER2]]([[I]]) : $@convention(thin) (Builtin.Int32) -> ()
|
|
// CHECK: [[TEMP:%.*]] = alloc_stack $Indirect<SomeSubclass>
|
|
// CHECK: [[MK_IND:%.*]] = function_ref @make_indirect
|
|
// CHECK: apply [[MK_IND]]<SomeSubclass>([[TEMP]])
|
|
// CHECK: destroy_addr [[TEMP]] : $*Indirect<SomeSubclass>
|
|
// CHECK: cond_br %0, bb1, bb2
|
|
|
|
// CHECK: bb1:
|
|
// CHECK: [[I4:%.*]] = integer_literal $Builtin.Int32, 10
|
|
// CHECK: apply [[MARKER]]([[I4]])
|
|
// CHECK: [[I2:%.*]] = integer_literal $Builtin.Int32, 2000
|
|
// CHECK: apply [[MARKER2]]([[I2]])
|
|
// CHECK: dealloc_stack [[TEMP]] : $*Indirect<SomeSubclass>
|
|
// CHECK: [[I5:%.*]] = integer_literal $Builtin.Int32, 20
|
|
// CHECK: apply [[MARKER]]([[I5]])
|
|
// CHECK: br bb3
|
|
|
|
// CHECK: bb2:
|
|
// CHECK: [[I6:%.*]] = integer_literal $Builtin.Int32, 11
|
|
// CHECK: apply [[MARKER]]([[I6]])
|
|
// CHECK: [[I3:%.*]] = integer_literal $Builtin.Int32, 3000
|
|
// CHECK: apply [[MARKER2]]([[I3]])
|
|
// CHECK: dealloc_stack [[TEMP]] : $*Indirect<SomeSubclass>
|
|
// CHECK: [[I7:%.*]] = integer_literal $Builtin.Int32, 21
|
|
// CHECK: [[MARKER]]([[I7]])
|
|
// CHECK: br bb3
|
|
|
|
// CHECK:bb3:
|
|
// CHECK: return
|
|
// CHECK:}
|
|
|
|
sil @test_simple_call : $(Builtin.Int1) -> () {
|
|
entry(%flag : $Builtin.Int1):
|
|
%marker = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()
|
|
%0 = function_ref @test_one_yield : $@convention(thin) @yield_once <T: SomeClass> () -> (@yields @in Indirect<T>)
|
|
(%value, %token) = begin_apply %0<SomeSubclass>() : $@convention(thin) @yield_once <T: SomeClass> () -> (@yields @in Indirect<T>)
|
|
destroy_addr %value : $*Indirect<SomeSubclass>
|
|
cond_br %flag, yes, no
|
|
|
|
yes:
|
|
%10 = integer_literal $Builtin.Int32, 10
|
|
apply %marker(%10) : $@convention(thin) (Builtin.Int32) -> ()
|
|
end_apply %token
|
|
%20 = integer_literal $Builtin.Int32, 20
|
|
apply %marker(%20) : $@convention(thin) (Builtin.Int32) -> ()
|
|
br cont
|
|
|
|
no:
|
|
%11 = integer_literal $Builtin.Int32, 11
|
|
apply %marker(%11) : $@convention(thin) (Builtin.Int32) -> ()
|
|
abort_apply %token
|
|
%21 = integer_literal $Builtin.Int32, 21
|
|
apply %marker(%21) : $@convention(thin) (Builtin.Int32) -> ()
|
|
br cont
|
|
|
|
cont:
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
sil [transparent] [ossa] @test_two_yield : $@yield_once <C: SomeClass> (Builtin.Int1) -> (@yields @in Indirect<C>, @yields Builtin.Int64) {
|
|
entry(%0 : $Builtin.Int1):
|
|
%marker = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()
|
|
%1000 = integer_literal $Builtin.Int32, 1000
|
|
apply %marker(%1000) : $@convention(thin) (Builtin.Int32) -> ()
|
|
%temp = alloc_stack $Indirect<C>
|
|
%make = function_ref @make_indirect : $@convention(thin) <T: SomeClass> () -> (@out Indirect<T>)
|
|
cond_br %0, yield1, yield2
|
|
|
|
yield1:
|
|
apply %make<C>(%temp) : $@convention(thin) <T: SomeClass> () -> (@out Indirect<T>)
|
|
%res = integer_literal $Builtin.Int64, 31
|
|
yield (%temp : $*Indirect<C>, %res: $Builtin.Int64), resume resume1, unwind unwind1
|
|
|
|
yield2:
|
|
apply %make<C>(%temp) : $@convention(thin) <T: SomeClass> () -> (@out Indirect<T>)
|
|
%res2 = integer_literal $Builtin.Int64, 32
|
|
yield (%temp : $*Indirect<C>, %res2: $Builtin.Int64), resume resume2, unwind unwind2
|
|
|
|
resume1:
|
|
br resume
|
|
resume2:
|
|
br resume
|
|
|
|
resume:
|
|
%2000 = integer_literal $Builtin.Int32, 2000
|
|
apply %marker(%2000) : $@convention(thin) (Builtin.Int32) -> ()
|
|
dealloc_stack %temp : $*Indirect<C>
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
|
|
unwind1:
|
|
br unwind
|
|
unwind2:
|
|
br unwind
|
|
|
|
unwind:
|
|
%3000 = integer_literal $Builtin.Int32, 3000
|
|
apply %marker(%3000) : $@convention(thin) (Builtin.Int32) -> ()
|
|
dealloc_stack %temp : $*Indirect<C>
|
|
unwind
|
|
}
|
|
|
|
// We don't support inlining functions with multiple yields yet.
|
|
// CHECK-LABEL: sil @test_simple_call_two_yields : $@convention(thin) (Builtin.Int1, Builtin.Int1) -> () {
|
|
// CHECK: bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int1):
|
|
// CHECK: begin_apply
|
|
// CHECK: return
|
|
|
|
sil @test_simple_call_two_yields : $(Builtin.Int1, Builtin.Int1) -> () {
|
|
entry(%flag : $Builtin.Int1, %flag2 : $Builtin.Int1):
|
|
%marker = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()
|
|
%0 = function_ref @test_two_yield : $@convention(thin) @yield_once <T: SomeClass> (Builtin.Int1) -> (@yields @in Indirect<T>, @yields Builtin.Int64)
|
|
(%value, %value2, %token) = begin_apply %0<SomeSubclass>(%flag) : $@convention(thin) @yield_once <T: SomeClass> (Builtin.Int1) -> (@yields @in Indirect<T>, @yields Builtin.Int64)
|
|
destroy_addr %value : $*Indirect<SomeSubclass>
|
|
cond_br %flag2, yes, no
|
|
|
|
yes:
|
|
end_apply %token
|
|
br cont
|
|
|
|
no:
|
|
abort_apply %token
|
|
br cont
|
|
|
|
cont:
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_simple_call_yield_owned : $@convention(thin) (Builtin.Int1, @owned SomeClass) -> () {
|
|
// CHECK: bb0(%0 : $Builtin.Int1, %1 : @owned $SomeClass):
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: %2 = function_ref @marker
|
|
// CHECK-NEXT: %3 = integer_literal $Builtin.Int32, 1000
|
|
// CHECK-NEXT: %4 = apply %2(%3)
|
|
// CHECK-NEXT: destroy_value %1
|
|
// CHECK-NEXT: cond_br %0, bb1, bb2
|
|
// CHECK: bb1:
|
|
// CHECK-NEXT: [[T0:%.*]] = integer_literal $Builtin.Int32, 2000
|
|
// CHECK-NEXT: apply %2([[T0]])
|
|
// CHECK-NEXT: tuple ()
|
|
// CHECK-NEXT: br bb3
|
|
// CHECK: bb2:
|
|
// CHECK-NEXT: [[T1:%.*]] = integer_literal $Builtin.Int32, 3000
|
|
// CHECK-NEXT: apply %2([[T1]])
|
|
// CHECK-NEXT: br bb3
|
|
// CHECK: bb3:
|
|
// CHECK-NEXT: [[T0:%.*]] = tuple ()
|
|
// CHECK-NEXT: return [[T0]] : $()
|
|
|
|
sil [transparent] [ossa] @yield_owned : $@yield_once(@owned SomeClass) -> (@yields @owned SomeClass) {
|
|
entry(%0 : @owned $SomeClass):
|
|
%marker = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()
|
|
%1000 = integer_literal $Builtin.Int32, 1000
|
|
apply %marker(%1000) : $@convention(thin) (Builtin.Int32) -> ()
|
|
yield %0 : $SomeClass, resume resume, unwind unwind
|
|
|
|
resume:
|
|
%2000 = integer_literal $Builtin.Int32, 2000
|
|
apply %marker(%2000) : $@convention(thin) (Builtin.Int32) -> ()
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
|
|
unwind:
|
|
%3000 = integer_literal $Builtin.Int32, 3000
|
|
apply %marker(%3000) : $@convention(thin) (Builtin.Int32) -> ()
|
|
unwind
|
|
}
|
|
|
|
sil [ossa] @test_simple_call_yield_owned : $(Builtin.Int1, @owned SomeClass) -> () {
|
|
entry(%flag : $Builtin.Int1, %c: @owned $SomeClass):
|
|
%0 = function_ref @yield_owned : $@convention(thin) @yield_once(@owned SomeClass) -> (@yields @owned SomeClass)
|
|
(%value, %token) = begin_apply %0(%c) : $@convention(thin) @yield_once(@owned SomeClass) -> (@yields @owned SomeClass)
|
|
destroy_value %value : $SomeClass
|
|
cond_br %flag, yes, no
|
|
|
|
yes:
|
|
end_apply %token
|
|
br cont
|
|
|
|
no:
|
|
abort_apply %token
|
|
br cont
|
|
|
|
cont:
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
sil @use : $@convention(thin) (@in Builtin.Int8) -> ()
|
|
|
|
sil [transparent] [ossa] [ossa] @yield_inout : $@yield_once() -> (@yields @inout Builtin.Int8) {
|
|
entry:
|
|
%addr = alloc_stack $Builtin.Int8
|
|
%8 = integer_literal $Builtin.Int8, 8
|
|
store %8 to [trivial] %addr : $*Builtin.Int8
|
|
yield %addr : $*Builtin.Int8, resume resume, unwind unwind
|
|
|
|
resume:
|
|
%use = function_ref @use : $@convention(thin) (@in Builtin.Int8) -> ()
|
|
apply %use(%addr) : $@convention(thin) (@in Builtin.Int8) -> ()
|
|
dealloc_stack %addr: $*Builtin.Int8
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
|
|
unwind:
|
|
%3000 = integer_literal $Builtin.Int32, 3000
|
|
%marker = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()
|
|
apply %marker(%3000) : $@convention(thin) (Builtin.Int32) -> ()
|
|
dealloc_stack %addr: $*Builtin.Int8
|
|
unwind
|
|
}
|
|
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_simple_call_yield_inout : $@convention(thin) (Builtin.Int1) -> () {
|
|
// CHECK: bb0(%0 : $Builtin.Int1):
|
|
// CHECK-NEXT: %1 = alloc_stack $Builtin.Int8
|
|
// CHECK-NEXT: %2 = integer_literal $Builtin.Int8, 8
|
|
// CHECK-NEXT: store %2 to [trivial] %1 : $*Builtin.Int8
|
|
// CHECK-NEXT: cond_br %0, bb1, bb2
|
|
|
|
// CHECK: bb1:
|
|
// CHECK-NEXT: [[T0:%.*]] = integer_literal $Builtin.Int8, 8
|
|
// CHECK-NEXT: store [[T0]] to [trivial] %1 : $*Builtin.Int8
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: [[USE:%.*]] = function_ref @use : $@convention(thin) (@in Builtin.Int8) -> ()
|
|
// CHECK-NEXT: apply [[USE]](%1) : $@convention(thin) (@in Builtin.Int8) -> ()
|
|
// CHECK-NEXT: dealloc_stack %1 : $*Builtin.Int8
|
|
// CHECK-NEXT: tuple ()
|
|
// CHECK-NEXT: br bb3
|
|
|
|
// CHECK: bb2:
|
|
// CHECK-NEXT: [[T0:%.*]] = integer_literal $Builtin.Int32, 3000
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: [[MARKER:%.*]] = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()
|
|
// CHECK-NEXT: apply [[MARKER]]([[T0]]) : $@convention(thin) (Builtin.Int32) -> ()
|
|
// CHECK-NEXT: dealloc_stack %1 : $*Builtin.Int8
|
|
// CHECK-NEXT: br bb3
|
|
|
|
// CHECK: bb3:
|
|
// CHECK-NEXT: [[T0:%.*]] = tuple ()
|
|
// CHECK-NEXT: return [[T0]] : $()
|
|
// CHECK: }
|
|
|
|
sil [ossa] @test_simple_call_yield_inout : $(Builtin.Int1) -> () {
|
|
entry(%flag : $Builtin.Int1):
|
|
%0 = function_ref @yield_inout : $@convention(thin) @yield_once() -> (@yields @inout Builtin.Int8)
|
|
(%addr, %token) = begin_apply %0() : $@convention(thin) @yield_once() -> (@yields @inout Builtin.Int8)
|
|
cond_br %flag, yes, no
|
|
|
|
yes:
|
|
%8 = integer_literal $Builtin.Int8, 8
|
|
store %8 to [trivial] %addr : $*Builtin.Int8
|
|
end_apply %token
|
|
br cont
|
|
|
|
no:
|
|
abort_apply %token
|
|
br cont
|
|
|
|
cont:
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
// We can't inline yet if there are multiple ends.
|
|
// CHECK-LABEL: sil [ossa] @test_multi_end_yield_inout : $@convention(thin) (Builtin.Int1) -> () {
|
|
// CHECK: [[T0:%.*]] = function_ref @yield_inout
|
|
// CHECK: begin_apply [[T0]]
|
|
sil [ossa] @test_multi_end_yield_inout : $(Builtin.Int1) -> () {
|
|
entry(%flag : $Builtin.Int1):
|
|
%0 = function_ref @yield_inout : $@convention(thin) @yield_once() -> (@yields @inout Builtin.Int8)
|
|
(%addr, %token) = begin_apply %0() : $@convention(thin) @yield_once() -> (@yields @inout Builtin.Int8)
|
|
cond_br %flag, yes, no
|
|
|
|
yes:
|
|
end_apply %token
|
|
br cont
|
|
|
|
no:
|
|
end_apply %token
|
|
br cont
|
|
|
|
cont:
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
// We can't inline yet if there are multiple aborts.
|
|
// CHECK-LABEL: sil [ossa] @test_multi_abort_yield_inout : $@convention(thin) (Builtin.Int1) -> () {
|
|
// CHECK: [[T0:%.*]] = function_ref @yield_inout
|
|
// CHECK: begin_apply [[T0]]
|
|
sil [ossa] @test_multi_abort_yield_inout : $(Builtin.Int1) -> () {
|
|
entry(%flag : $Builtin.Int1):
|
|
%0 = function_ref @yield_inout : $@convention(thin) @yield_once() -> (@yields @inout Builtin.Int8)
|
|
(%addr, %token) = begin_apply %0() : $@convention(thin) @yield_once() -> (@yields @inout Builtin.Int8)
|
|
cond_br %flag, yes, no
|
|
|
|
yes:
|
|
abort_apply %token
|
|
br cont
|
|
|
|
no:
|
|
abort_apply %token
|
|
br cont
|
|
|
|
cont:
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
sil [transparent] [ossa] @no_yields : $@yield_once () -> (@yields @inout Builtin.Int8) {
|
|
entry:
|
|
%3000 = integer_literal $Builtin.Int32, 3000
|
|
%marker = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()
|
|
apply %marker(%3000) : $@convention(thin) (Builtin.Int32) -> ()
|
|
unreachable
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_simple_call_no_yields : $@convention(thin) () -> () {
|
|
// CHECK: bb0:
|
|
// CHECK-NEXT: [[T0:%.*]] = integer_literal $Builtin.Int32, 3000
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: [[MARKER:%.*]] = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()
|
|
// CHECK-NEXT: apply [[MARKER]]([[T0]]) : $@convention(thin) (Builtin.Int32) -> ()
|
|
// CHECK-NEXT: unreachable
|
|
// CHECK: bb1:
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: [[USE:%.*]] = function_ref @use : $@convention(thin) (@in Builtin.Int8) -> ()
|
|
// CHECK-NEXT: apply [[USE]](undef) : $@convention(thin) (@in Builtin.Int8) -> ()
|
|
// CHECK-NEXT: unreachable
|
|
// CHECK: bb2:
|
|
// CHECK-NEXT: [[T0:%.*]] = tuple ()
|
|
// CHECK-NEXT: return [[T0]] : $()
|
|
// CHECK: }
|
|
sil [ossa] @test_simple_call_no_yields : $() -> () {
|
|
entry:
|
|
%0 = function_ref @no_yields : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int8)
|
|
(%addr, %token) = begin_apply %0() : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int8)
|
|
%use = function_ref @use : $@convention(thin) (@in Builtin.Int8) -> ()
|
|
apply %use(%addr) : $@convention(thin) (@in Builtin.Int8) -> ()
|
|
end_apply %token
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
sil [transparent] [ossa] @stack_overlap : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int32) {
|
|
entry:
|
|
%marker = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()
|
|
%temp = alloc_stack $Builtin.Int32
|
|
%1000 = integer_literal $Builtin.Int32, 1000
|
|
store %1000 to [trivial] %temp : $*Builtin.Int32
|
|
%2000 = integer_literal $Builtin.Int32, 2000
|
|
apply %marker(%2000) : $@convention(thin) (Builtin.Int32) -> ()
|
|
yield %temp : $*Builtin.Int32, resume resume, unwind unwind
|
|
|
|
resume:
|
|
%3000 = integer_literal $Builtin.Int32, 3000
|
|
apply %marker(%3000) : $@convention(thin) (Builtin.Int32) -> ()
|
|
dealloc_stack %temp : $*Builtin.Int32
|
|
%4000 = integer_literal $Builtin.Int32, 4000
|
|
apply %marker(%4000) : $@convention(thin) (Builtin.Int32) -> ()
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
|
|
unwind:
|
|
dealloc_stack %temp : $*Builtin.Int32
|
|
unwind
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_stack_overlap_dealloc
|
|
// CHECK: bb0:
|
|
// CHECK-NEXT: [[A16:%.*]] = alloc_stack $Builtin.Int16
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: [[MARKER:%.*]] = function_ref @marker
|
|
// CHECK-NEXT: [[A32:%.*]] = alloc_stack $Builtin.Int32
|
|
// CHECK-NEXT: [[I1000:%.*]] = integer_literal $Builtin.Int32, 1000
|
|
// CHECK-NEXT: store [[I1000]] to [trivial] [[A32]]
|
|
// CHECK-NEXT: [[I2000:%.*]] = integer_literal $Builtin.Int32, 2000
|
|
// CHECK-NEXT: apply [[MARKER]]([[I2000]])
|
|
// CHECK-NEXT: [[I3000:%.*]] = integer_literal $Builtin.Int32, 3000
|
|
// CHECK-NEXT: apply [[MARKER]]([[I3000]])
|
|
// CHECK-NEXT: dealloc_stack [[A32]] : $*Builtin.Int32
|
|
// Note that this has been delayed to follow stack discipline.
|
|
// CHECK-NEXT: dealloc_stack [[A16]] : $*Builtin.Int16
|
|
// CHECK-NEXT: [[I4000:%.*]] = integer_literal $Builtin.Int32, 4000
|
|
// CHECK-NEXT: apply [[MARKER]]([[I4000]])
|
|
// CHECK-NEXT: tuple ()
|
|
// CHECK-NEXT: [[RET:%.*]] = tuple ()
|
|
// CHECK-NEXT: return [[RET]] : $()
|
|
// CHECK-LABEL: // end sil function 'test_stack_overlap_dealloc'
|
|
sil [ossa] @test_stack_overlap_dealloc : $() -> () {
|
|
bb0:
|
|
%stack = alloc_stack $Builtin.Int16
|
|
%0 = function_ref @stack_overlap : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int32)
|
|
(%value, %token) = begin_apply %0() : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int32)
|
|
dealloc_stack %stack : $*Builtin.Int16
|
|
end_apply %token
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_stack_overlap_alloc
|
|
// CHECK: bb0:
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: [[MARKER:%.*]] = function_ref @marker
|
|
// CHECK-NEXT: [[A32:%.*]] = alloc_stack $Builtin.Int32
|
|
// CHECK-NEXT: [[I1000:%.*]] = integer_literal $Builtin.Int32, 1000
|
|
// CHECK-NEXT: store [[I1000]] to [trivial] [[A32]]
|
|
// CHECK-NEXT: [[I2000:%.*]] = integer_literal $Builtin.Int32, 2000
|
|
// CHECK-NEXT: apply [[MARKER]]([[I2000]])
|
|
// CHECK-NEXT: [[A16:%.*]] = alloc_stack $Builtin.Int16
|
|
// CHECK-NEXT: [[I3000:%.*]] = integer_literal $Builtin.Int32, 3000
|
|
// CHECK-NEXT: apply [[MARKER]]([[I3000]])
|
|
// CHECK-NEXT: [[I4000:%.*]] = integer_literal $Builtin.Int32, 4000
|
|
// CHECK-NEXT: apply [[MARKER]]([[I4000]])
|
|
// CHECK-NEXT: tuple ()
|
|
// CHECK-NEXT: dealloc_stack [[A16]] : $*Builtin.Int16
|
|
// Note that this has been delayed to follow stack discipline.
|
|
// CHECK-NEXT: dealloc_stack [[A32]] : $*Builtin.Int32
|
|
// CHECK-NEXT: [[RET:%.*]] = tuple ()
|
|
// CHECK-NEXT: return [[RET]] : $()
|
|
// CHECK-LABEL: // end sil function 'test_stack_overlap_alloc'
|
|
sil [ossa] @test_stack_overlap_alloc : $() -> () {
|
|
bb0:
|
|
%0 = function_ref @stack_overlap : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int32)
|
|
(%value, %token) = begin_apply %0() : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int32)
|
|
%stack = alloc_stack $Builtin.Int16
|
|
end_apply %token
|
|
dealloc_stack %stack : $*Builtin.Int16
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_stack_overlap_unreachable
|
|
// CHECK: bb0:
|
|
// CHECK: [[A16:%.*]] = alloc_stack $Builtin.Int16
|
|
// CHECK: [[A32:%.*]] = alloc_stack $Builtin.Int32
|
|
// CHECK: bb1:
|
|
// CHECK: dealloc_stack [[A32]] : $*Builtin.Int32
|
|
// CHECK: unreachable
|
|
// CHECK: bb2:
|
|
// CHECK: unreachable
|
|
// CHECK: bb3:
|
|
// CHECK: dealloc_stack [[A32]] : $*Builtin.Int32
|
|
// CHECK: dealloc_stack [[A16]] : $*Builtin.Int16
|
|
// CHECK: return
|
|
// CHECK-LABEL: // end sil function 'test_stack_overlap_unreachable'
|
|
sil [ossa] @test_stack_overlap_unreachable : $() -> () {
|
|
bb0:
|
|
%stack = alloc_stack $Builtin.Int16
|
|
%0 = function_ref @stack_overlap : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int32)
|
|
(%value, %token) = begin_apply %0() : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int32)
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
dealloc_stack %stack : $*Builtin.Int16
|
|
unreachable
|
|
|
|
bb2:
|
|
end_apply %token
|
|
dealloc_stack %stack : $*Builtin.Int16
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|