blob: 73f6e7bea85dcc1b8e586f5c5922943d35f71f9a [file] [log] [blame]
// RUN: %target-sil-opt -enable-sil-verify-all %s -capture-promotion | %FileCheck %s
sil_stage raw
import Builtin
import Swift
// top_level_code
sil private @top_level_code : $() -> () {
bb0:
%0 = tuple ()
return %0 : $()
}
/*
func test_reachability_1(b: Builtin.Int1, x: Builtin.Int64, y: Builtin.Int64) {
if (b) {
x = y
}
var t : () -> Builtin.Int64 = { x } // promotable
if (b) {
t = { x } // promotable
}
}
*/
// CHECK-LABEL: sil @test_reachability_1
sil @test_reachability_1 : $@convention(thin) (Builtin.Int1, Builtin.Int64, Builtin.Int64) -> () {
bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int64, %2 : $Builtin.Int64):
%3 = alloc_box $_0_0> { var τ_0_0 } <Builtin.Int1>
%3a = project_box %3 : $_0_0> { var τ_0_0 } <Builtin.Int1>, 0
%4 = alloc_box $_0_0> { var τ_0_0 } <Builtin.Int64>
%4a = project_box %4 : $_0_0> { var τ_0_0 } <Builtin.Int64>, 0
%5 = alloc_box $_0_0> { var τ_0_0 } <Builtin.Int64>
%5a = project_box %5 : $_0_0> { var τ_0_0 } <Builtin.Int64>, 0
store %0 to %3a : $*Builtin.Int1
store %1 to %4a : $*Builtin.Int64
store %2 to %5a : $*Builtin.Int64
%9 = load %3a : $*Builtin.Int1
cond_br %9, bb1, bb2
bb1:
%11 = load %5a : $*Builtin.Int64
assign %11 to %4a : $*Builtin.Int64
br bb2
bb2:
%14 = alloc_box $_0_0> { var τ_0_0 } <@callee_owned () -> Builtin.Int64>
%14a = project_box %14 : $_0_0> { var τ_0_0 } <@callee_owned () -> Builtin.Int64>, 0
// CHECK: [[CLOSURE0_PROMOTE0:%.*]] = function_ref @$s8closure0Tf2i_n :
%15 = function_ref @closure0 : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64
strong_retain %4 : $_0_0> { var τ_0_0 } <Builtin.Int64>
// CHECK: partial_apply [[CLOSURE0_PROMOTE0]]({{%.*}})
%17 = partial_apply %15(%4) : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64
store %17 to %14a : $*@callee_owned () -> Builtin.Int64
%19 = load %3a : $*Builtin.Int1
cond_br %19, bb3, bb4
bb3:
// CHECK: [[CLOSURE1_PROMOTE0:%.*]] = function_ref @$s8closure1Tf2i_n :
%21 = function_ref @closure1 : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64
strong_retain %4 : $_0_0> { var τ_0_0 } <Builtin.Int64>
// CHECK: partial_apply [[CLOSURE1_PROMOTE0]]({{%.*}})
%23 = partial_apply %21(%4) : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64
assign %23 to %14a : $*@callee_owned () -> Builtin.Int64
br bb4
bb4:
strong_release %14 : $_0_0> { var τ_0_0 } <@callee_owned () -> Builtin.Int64>
strong_release %5 : $_0_0> { var τ_0_0 } <Builtin.Int64>
strong_release %4 : $_0_0> { var τ_0_0 } <Builtin.Int64>
strong_release %3 : $_0_0> { var τ_0_0 } <Builtin.Int1>
%30 = tuple ()
return %30 : $()
}
// closure0
sil private @closure0 : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64 {
bb0(%0 : $_0_0> { var τ_0_0 } <Builtin.Int64>):
%1 = project_box %0 : $_0_0> { var τ_0_0 } <Builtin.Int64>, 0
%2 = tuple ()
%3 = load %1 : $*Builtin.Int64
strong_release %0 : $_0_0> { var τ_0_0 } <Builtin.Int64>
return %3 : $Builtin.Int64
}
// closure1
sil private @closure1 : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64 {
bb0(%0 : $_0_0> { var τ_0_0 } <Builtin.Int64>):
%1 = project_box %0 : $_0_0> { var τ_0_0 } <Builtin.Int64>, 0
%2 = tuple ()
%3 = load %1 : $*Builtin.Int64
strong_release %0 : $_0_0> { var τ_0_0 } <Builtin.Int64>
return %3 : $Builtin.Int64
}
/*
func test_reachability_2(b: Builtin.Int1, x: Builtin.Int64, y: Builtin.Int64) {
var t : () -> Builtin.Int64 = { x } // unpromotable
if (b) {
x = y
}
if (b) {
t = { x } // promotable
}
}
*/
// CHECK-LABEL: sil @test_reachability_2
sil @test_reachability_2 : $@convention(thin) (Builtin.Int1, Builtin.Int64, Builtin.Int64) -> () {
bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int64, %2 : $Builtin.Int64):
%3 = alloc_box $_0_0> { var τ_0_0 } <Builtin.Int1>
%3a = project_box %3 : $_0_0> { var τ_0_0 } <Builtin.Int1>, 0
%4 = alloc_box $_0_0> { var τ_0_0 } <Builtin.Int64>
%4a = project_box %4 : $_0_0> { var τ_0_0 } <Builtin.Int64>, 0
%5 = alloc_box $_0_0> { var τ_0_0 } <Builtin.Int64>
%5a = project_box %5 : $_0_0> { var τ_0_0 } <Builtin.Int64>, 0
store %0 to %3a : $*Builtin.Int1
store %1 to %4a : $*Builtin.Int64
store %2 to %5a : $*Builtin.Int64
%9 = alloc_box $_0_0> { var τ_0_0 } <@callee_owned () -> Builtin.Int64>
%9a = project_box %9 : $_0_0> { var τ_0_0 } <@callee_owned () -> Builtin.Int64>, 0
// CHECK: [[CLOSURE2:%.*]] = function_ref @closure2 :
%10 = function_ref @closure2 : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64
strong_retain %4 : $_0_0> { var τ_0_0 } <Builtin.Int64>
// CHECK: partial_apply [[CLOSURE2]]({{%.*}})
%12 = partial_apply %10(%4) : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64
store %12 to %9a : $*@callee_owned () -> Builtin.Int64
%14 = load %3a : $*Builtin.Int1
cond_br %14, bb1, bb2
bb1:
%16 = load %5a : $*Builtin.Int64
assign %16 to %4a : $*Builtin.Int64
br bb2
bb2:
%19 = load %3a : $*Builtin.Int1
cond_br %19, bb3, bb4
bb3:
// CHECK: [[CLOSURE3_PROMOTE0:%.*]] = function_ref @$s8closure3Tf2i_n :
%21 = function_ref @closure3 : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64
strong_retain %4 : $_0_0> { var τ_0_0 } <Builtin.Int64>
// CHECK: partial_apply [[CLOSURE3_PROMOTE0]]({{%.*}})
%23 = partial_apply %21(%4) : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64
assign %23 to %9a : $*@callee_owned () -> Builtin.Int64
br bb4
bb4:
strong_release %9 : $_0_0> { var τ_0_0 } <@callee_owned () -> Builtin.Int64>
strong_release %5 : $_0_0> { var τ_0_0 } <Builtin.Int64>
strong_release %4 : $_0_0> { var τ_0_0 } <Builtin.Int64>
strong_release %3 : $_0_0> { var τ_0_0 } <Builtin.Int1>
%30 = tuple ()
return %30 : $()
}
// closure2
sil private @closure2 : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64 {
bb0(%0 : $_0_0> { var τ_0_0 } <Builtin.Int64>):
%1 = project_box %0 : $_0_0> { var τ_0_0 } <Builtin.Int64>, 0
%2 = tuple ()
%3 = load %1 : $*Builtin.Int64
strong_release %0 : $_0_0> { var τ_0_0 } <Builtin.Int64>
return %3 : $Builtin.Int64
}
// closure3
sil private @closure3 : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64 {
bb0(%0 : $_0_0> { var τ_0_0 } <Builtin.Int64>):
%1 = project_box %0 : $_0_0> { var τ_0_0 } <Builtin.Int64>, 0
%2 = tuple ()
%3 = load %1 : $*Builtin.Int64
strong_release %0 : $_0_0> { var τ_0_0 } <Builtin.Int64>
return %3 : $Builtin.Int64
}
/*
func test_reachability_3(b: Builtin.Int1, x: Builtin.Int64, y: Builtin.Int64) {
var t : () -> Builtin.Int64 = { x } // unpromotable
if (b) {
t = { x } // unpromotable
}
if (b) {
x = y
}
}
*/
// CHECK-LABEL: sil @test_reachability_3
sil @test_reachability_3 : $@convention(thin) (Builtin.Int1, Builtin.Int64, Builtin.Int64) -> () {
bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int64, %2 : $Builtin.Int64):
%3 = alloc_box $_0_0> { var τ_0_0 } <Builtin.Int1>
%3a = project_box %3 : $_0_0> { var τ_0_0 } <Builtin.Int1>, 0
%4 = alloc_box $_0_0> { var τ_0_0 } <Builtin.Int64>
%4a = project_box %4 : $_0_0> { var τ_0_0 } <Builtin.Int64>, 0
%5 = alloc_box $_0_0> { var τ_0_0 } <Builtin.Int64>
%5a = project_box %5 : $_0_0> { var τ_0_0 } <Builtin.Int64>, 0
store %0 to %3a : $*Builtin.Int1
store %1 to %4a : $*Builtin.Int64
store %2 to %5a : $*Builtin.Int64
%9 = alloc_box $_0_0> { var τ_0_0 } <@callee_owned () -> Builtin.Int64>
%9a = project_box %9 : $_0_0> { var τ_0_0 } <@callee_owned () -> Builtin.Int64>, 0
// CHECK: [[CLOSURE4:%.*]] = function_ref @closure4 :
%10 = function_ref @closure4 : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64
strong_retain %4 : $_0_0> { var τ_0_0 } <Builtin.Int64>
// CHECK: partial_apply [[CLOSURE4]]({{%.*}})
%12 = partial_apply %10(%4) : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64
store %12 to %9a : $*@callee_owned () -> Builtin.Int64
%14 = load %3a : $*Builtin.Int1
cond_br %14, bb1, bb2
bb1:
// CHECK: [[CLOSURE5:%.*]] = function_ref @closure5 :
%16 = function_ref @closure5 : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64
strong_retain %4 : $_0_0> { var τ_0_0 } <Builtin.Int64>
// CHECK: partial_apply [[CLOSURE5]]({{%.*}})
%18 = partial_apply %16(%4) : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64
assign %18 to %9a : $*@callee_owned () -> Builtin.Int64
br bb2
bb2:
%21 = load %3a : $*Builtin.Int1
cond_br %21, bb3, bb4
bb3:
%23 = load %5a : $*Builtin.Int64
assign %23 to %4a : $*Builtin.Int64
br bb4
bb4:
strong_release %9 : $_0_0> { var τ_0_0 } <@callee_owned () -> Builtin.Int64>
strong_release %5 : $_0_0> { var τ_0_0 } <Builtin.Int64>
strong_release %4 : $_0_0> { var τ_0_0 } <Builtin.Int64>
strong_release %3 : $_0_0> { var τ_0_0 } <Builtin.Int1>
%30 = tuple ()
return %30 : $()
}
// closure4
sil private @closure4 : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64 {
bb0(%0 : $_0_0> { var τ_0_0 } <Builtin.Int64>):
%1 = project_box %0 : $_0_0> { var τ_0_0 } <Builtin.Int64>, 0
%2 = tuple ()
%3 = load %1 : $*Builtin.Int64
strong_release %0 : $_0_0> { var τ_0_0 } <Builtin.Int64>
return %3 : $Builtin.Int64
}
// closure5
sil private @closure5 : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64 {
bb0(%0 : $_0_0> { var τ_0_0 } <Builtin.Int64>):
%1 = project_box %0 : $_0_0> { var τ_0_0 } <Builtin.Int64>, 0
%2 = tuple ()
%3 = load %1 : $*Builtin.Int64
strong_release %0 : $_0_0> { var τ_0_0 } <Builtin.Int64>
return %3 : $Builtin.Int64
}
/*
func test_reachability_4(b: Builtin.Int1, x: Builtin.Int64, y: Builtin.Int64) {
var t : () -> Builtin.Int64 = { x } // unpromotable
while (b) {
x = y
t = { x } // unpromotable
}
}
*/
// CHECK-LABEL: sil @test_reachability_4
sil @test_reachability_4 : $@convention(thin) (Builtin.Int1, Builtin.Int64, Builtin.Int64) -> () {
bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int64, %2 : $Builtin.Int64):
%3 = alloc_box $_0_0> { var τ_0_0 } <Builtin.Int1>
%3a = project_box %3 : $_0_0> { var τ_0_0 } <Builtin.Int1>, 0
%4 = alloc_box $_0_0> { var τ_0_0 } <Builtin.Int64>
%4a = project_box %4 : $_0_0> { var τ_0_0 } <Builtin.Int64>, 0
%5 = alloc_box $_0_0> { var τ_0_0 } <Builtin.Int64>
%5a = project_box %5 : $_0_0> { var τ_0_0 } <Builtin.Int64>, 0
store %0 to %3a : $*Builtin.Int1
store %1 to %4a : $*Builtin.Int64
store %2 to %5a : $*Builtin.Int64
%9 = alloc_box $_0_0> { var τ_0_0 } <@callee_owned () -> Builtin.Int64>
%9a = project_box %9 : $_0_0> { var τ_0_0 } <@callee_owned () -> Builtin.Int64>, 0
// CHECK: [[CLOSURE6:%.*]] = function_ref @closure6 :
%10 = function_ref @closure6 : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64
strong_retain %4 : $_0_0> { var τ_0_0 } <Builtin.Int64>
// CHECK: partial_apply [[CLOSURE6]]({{%.*}})
%12 = partial_apply %10(%4) : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64
store %12 to %9a : $*@callee_owned () -> Builtin.Int64
br bb1
bb1:
%15 = load %3a : $*Builtin.Int1
cond_br %15, bb2, bb3
bb2:
%17 = load %5a : $*Builtin.Int64
assign %17 to %4a : $*Builtin.Int64
// CHECK: [[CLOSURE7:%.*]] = function_ref @closure7 :
%19 = function_ref @closure7 : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64
strong_retain %4 : $_0_0> { var τ_0_0 } <Builtin.Int64>
// CHECK: partial_apply [[CLOSURE7]]({{%.*}})
%21 = partial_apply %19(%4) : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64
assign %21 to %9a : $*@callee_owned () -> Builtin.Int64
br bb1
bb3:
strong_release %9 : $_0_0> { var τ_0_0 } <@callee_owned () -> Builtin.Int64>
strong_release %5 : $_0_0> { var τ_0_0 } <Builtin.Int64>
strong_release %4 : $_0_0> { var τ_0_0 } <Builtin.Int64>
strong_release %3 : $_0_0> { var τ_0_0 } <Builtin.Int1>
%28 = tuple ()
return %28 : $()
}
// closure6
sil private @closure6 : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64 {
bb0(%0 : $_0_0> { var τ_0_0 } <Builtin.Int64>):
%1 = project_box %0 : $_0_0> { var τ_0_0 } <Builtin.Int64>, 0
%2 = tuple ()
%3 = load %1 : $*Builtin.Int64
strong_release %0 : $_0_0> { var τ_0_0 } <Builtin.Int64>
return %3 : $Builtin.Int64
}
// closure7
sil private @closure7 : $@convention(thin) (@owned _0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64 {
bb0(%0 : $_0_0> { var τ_0_0 } <Builtin.Int64>):
%1 = project_box %0 : $_0_0> { var τ_0_0 } <Builtin.Int64>, 0
%2 = tuple ()
%3 = load %1 : $*Builtin.Int64
strong_release %0 : $_0_0> { var τ_0_0 } <Builtin.Int64>
return %3 : $Builtin.Int64
}