blob: 78d1ee5758dd6e43964a5d9e5e828398c023874b [file] [log] [blame]
// RUN: %target-sil-opt -enable-sil-verify-all %s -mandatory-inlining | FileCheck %s
import Builtin
import Swift
protocol CP : class {
func f() -> Self
}
sil @plus : $@convention(thin) (Int64, Int64) -> Int64
sil @fromLiteral : $@convention(thin) (Builtin.Int128, @thin Int64.Type) -> Int64
// CHECK-LABEL: sil [transparent] @test_add : $@convention(thin) (Int64) -> Int64 {
sil [transparent] @test_add : $@convention(thin) (Int64) -> Int64 {
bb0(%0 : $Int64):
%1 = alloc_box $Int64
store %0 to %1#1 : $*Int64
%3 = function_ref @plus : $@convention(thin) (Int64, Int64) -> Int64
%4 = load %1#1 : $*Int64
%5 = function_ref @fromLiteral : $@convention(thin) (Builtin.Int128, @thin Int64.Type) -> Int64
%6 = metatype $@thin Int64.Type
%7 = integer_literal $Builtin.Int128, 20
%8 = apply %5(%7, %6) : $@convention(thin) (Builtin.Int128, @thin Int64.Type) -> Int64
%9 = apply %3(%4, %8) : $@convention(thin) (Int64, Int64) -> Int64
strong_release %1#0 : $@box Int64
return %9 : $Int64
}
// CHECK-LABEL: sil @inline_test_add : $@convention(thin) (Int64) -> Int64 {
sil @inline_test_add : $@convention(thin) (Int64) -> Int64 {
// CHECK: [[BB0:.*]]([[VAL0:%.*]] : $Int64):
// CHECK: [[VAL1:%.*]] = alloc_box $Int64
// CHECK: store [[VAL0]] to [[VAL1]]#1
// CHECK: [[VAL3:%.*]] = function_ref @plus
// CHECK: [[VAL4:%.*]] = function_ref @plus
// CHECK: [[VAL5:%.*]] = load [[VAL1]]#1
// CHECK: [[VAL6:%.*]] = function_ref @fromLiteral
// CHECK: [[VAL7:%.*]] = metatype $@thin Int64.Type
// CHECK: [[VAL8:%.*]] = integer_literal $Builtin.Int128, 10
// CHECK: [[VAL9:%.*]] = apply [[VAL6]]([[VAL8]], [[VAL7]])
// CHECK: [[VAL10:%.*]] = apply [[VAL4]]([[VAL5]], [[VAL9]])
// CHECK: [[VAL11:%.*]] = alloc_box $Int64
// CHECK: store [[VAL10]] to [[VAL11]]#1
// CHECK: [[VAL13:%.*]] = function_ref @plus
// CHECK: [[VAL14:%.*]] = load [[VAL11]]#1
// CHECK: [[VAL15:%.*]] = function_ref @fromLiteral
// CHECK: [[VAL16:%.*]] = metatype $@thin Int64.Type
// CHECK: [[VAL17:%.*]] = integer_literal $Builtin.Int128, 20
// CHECK: [[VAL18:%.*]] = apply [[VAL15]]([[VAL17]], [[VAL16]])
// CHECK: [[VAL19:%.*]] = apply [[VAL13]]([[VAL14]], [[VAL18]])
// CHECK: strong_release [[VAL11]]#0
// CHECK: [[VAL21:%.*]] = function_ref @fromLiteral
// CHECK: [[VAL22:%.*]] = metatype $@thin Int64.Type
// CHECK: [[VAL23:%.*]] = integer_literal $Builtin.Int128, 30
// CHECK: [[VAL24:%.*]] = apply [[VAL21]]([[VAL23]], [[VAL22]])
// CHECK: [[VAL25:%.*]] = apply [[VAL3]]([[VAL19]], [[VAL24]])
// CHECK: strong_release [[VAL1]]#0
// CHECK: return [[VAL25]]
bb0(%0 : $Int64):
%1 = alloc_box $Int64
store %0 to %1#1 : $*Int64
%3 = function_ref @plus : $@convention(thin) (Int64, Int64) -> Int64
%4 = function_ref @test_add : $@convention(thin) (Int64) -> Int64
%5 = function_ref @plus : $@convention(thin) (Int64, Int64) -> Int64
%6 = load %1#1 : $*Int64
%7 = function_ref @fromLiteral : $@convention(thin) (Builtin.Int128, @thin Int64.Type) -> Int64
%8 = metatype $@thin Int64.Type
%9 = integer_literal $Builtin.Int128, 10
%10 = apply %7(%9, %8) : $@convention(thin) (Builtin.Int128, @thin Int64.Type) -> Int64
%11 = apply %5(%6, %10) : $@convention(thin) (Int64, Int64) -> Int64
%12 = apply %4(%11) : $@convention(thin) (Int64) -> Int64
%13 = function_ref @fromLiteral : $@convention(thin) (Builtin.Int128, @thin Int64.Type) -> Int64
%14 = metatype $@thin Int64.Type
%15 = integer_literal $Builtin.Int128, 30
%16 = apply %13(%15, %14) : $@convention(thin) (Builtin.Int128, @thin Int64.Type) -> Int64
%17 = apply %3(%12, %16) : $@convention(thin) (Int64, Int64) -> Int64
strong_release %1#0 : $@box Int64
return %17 : $Int64
}
// CHECK-LABEL: sil @inline_twice_test_add : $@convention(thin) (Int64) -> Int64 {
sil @inline_twice_test_add : $@convention(thin) (Int64) -> Int64 {
// CHECK: [[BB0:.*]]([[VAL0:%.*]] : $Int64):
// CHECK: [[VAL1:%.*]] = alloc_box $Int64
// CHECK: store [[VAL0]] to [[VAL1]]#1
// CHECK: [[VAL3:%.*]] = function_ref @plus
// CHECK: [[VAL4:%.*]] = function_ref @plus
// CHECK: [[VAL5:%.*]] = load [[VAL1]]#1
// CHECK: [[VAL6:%.*]] = function_ref @fromLiteral
// CHECK: [[VAL7:%.*]] = metatype $@thin Int64.Type
// CHECK: [[VAL8:%.*]] = integer_literal $Builtin.Int128, 10
// CHECK: [[VAL9:%.*]] = apply [[VAL6]]([[VAL8]], [[VAL7]])
// CHECK: [[VAL10:%.*]] = apply [[VAL4]]([[VAL5]], [[VAL9]])
// CHECK: [[VAL11:%.*]] = alloc_box $Int64
// CHECK: store [[VAL10]] to [[VAL11]]#1
// CHECK: [[VAL13:%.*]] = function_ref @plus
// CHECK: [[VAL14:%.*]] = load [[VAL11]]#1
// CHECK: [[VAL15:%.*]] = function_ref @fromLiteral
// CHECK: [[VAL16:%.*]] = metatype $@thin Int64.Type
// CHECK: [[VAL17:%.*]] = integer_literal $Builtin.Int128, 20
// CHECK: [[VAL18:%.*]] = apply [[VAL15]]([[VAL17]], [[VAL16]])
// CHECK: [[VAL19:%.*]] = apply [[VAL13]]([[VAL14]], [[VAL18]])
// CHECK: strong_release [[VAL11]]#0
// CHECK: [[VAL21:%.*]] = alloc_box $Int64
// CHECK: store [[VAL19]] to [[VAL21]]#1
// CHECK: [[VAL23:%.*]] = function_ref @plus
// CHECK: [[VAL24:%.*]] = load [[VAL21]]#1
// CHECK: [[VAL25:%.*]] = function_ref @fromLiteral
// CHECK: [[VAL26:%.*]] = metatype $@thin Int64.Type
// CHECK: [[VAL27:%.*]] = integer_literal $Builtin.Int128, 20
// CHECK: [[VAL28:%.*]] = apply [[VAL25]]([[VAL27]], [[VAL26]])
// CHECK: [[VAL29:%.*]] = apply [[VAL23]]([[VAL24]], [[VAL28]])
// CHECK: strong_release [[VAL21]]#0
// CHECK: [[VAL31:%.*]] = function_ref @fromLiteral
// CHECK: [[VAL32:%.*]] = metatype $@thin Int64.Type
// CHECK: [[VAL33:%.*]] = integer_literal $Builtin.Int128, 30
// CHECK: [[VAL34:%.*]] = apply [[VAL31]]([[VAL33]], [[VAL32]])
// CHECK: [[VAL35:%.*]] = apply [[VAL3]]([[VAL29]], [[VAL34]])
// CHECK: strong_release [[VAL1]]#0
// CHECK: return [[VAL35]]
bb0(%0 : $Int64):
%1 = alloc_box $Int64
store %0 to %1#1 : $*Int64
%3 = function_ref @plus : $@convention(thin) (Int64, Int64) -> Int64
%4 = function_ref @test_add : $@convention(thin) (Int64) -> Int64
%5 = function_ref @test_add : $@convention(thin) (Int64) -> Int64
%6 = function_ref @plus : $@convention(thin) (Int64, Int64) -> Int64
%7 = load %1#1 : $*Int64
%8 = function_ref @fromLiteral : $@convention(thin) (Builtin.Int128, @thin Int64.Type) -> Int64
%9 = metatype $@thin Int64.Type
%10 = integer_literal $Builtin.Int128, 10
%11 = apply %8(%10, %9) : $@convention(thin) (Builtin.Int128, @thin Int64.Type) -> Int64
%12 = apply %6(%7, %11) : $@convention(thin) (Int64, Int64) -> Int64
%13 = apply %5(%12) : $@convention(thin) (Int64) -> Int64
%14 = apply %4(%13) : $@convention(thin) (Int64) -> Int64
%15 = function_ref @fromLiteral : $@convention(thin) (Builtin.Int128, @thin Int64.Type) -> Int64
%16 = metatype $@thin Int64.Type
%17 = integer_literal $Builtin.Int128, 30
%18 = apply %15(%17, %16) : $@convention(thin) (Builtin.Int128, @thin Int64.Type) -> Int64
%19 = apply %3(%14, %18) : $@convention(thin) (Int64, Int64) -> Int64
strong_release %1#0 : $@box Int64
return %19 : $Int64
}
protocol SomeProtocol {
}
// CHECK-LABEL: sil [transparent] @test_existential_metatype : $@convention(thin) (@in SomeProtocol) -> @thick SomeProtocol.Type
sil [transparent] @test_existential_metatype : $@convention(thin) (@in SomeProtocol) -> @thick SomeProtocol.Type {
bb0(%0 : $*SomeProtocol):
%1 = alloc_box $SomeProtocol
copy_addr [take] %0 to [initialization] %1#1 : $*SomeProtocol
%4 = alloc_stack $SomeProtocol
copy_addr %1#1 to [initialization] %4#1 : $*SomeProtocol
%6 = existential_metatype $@thick SomeProtocol.Type, %4#1 : $*SomeProtocol
destroy_addr %4#1 : $*SomeProtocol
dealloc_stack %4#0 : $*@local_storage SomeProtocol
strong_release %1#0 : $@box SomeProtocol
return %6 : $@thick SomeProtocol.Type
}
// CHECK-LABEL: sil @inline_test_existential_metatype : $@convention(thin) (@in SomeProtocol) -> @thick SomeProtocol.Type
sil @inline_test_existential_metatype : $@convention(thin) (@in SomeProtocol) -> @thick SomeProtocol.Type {
// CHECK: [[BB0:.*]]([[VAL0:%.*]] : $*SomeProtocol):
// CHECK: [[VAL1:%.*]] = alloc_box $SomeProtocol
// CHECK: copy_addr [take] %0 to [initialization] [[VAL1]]#1
// CHECK: [[VAL4:%.*]] = alloc_stack $SomeProtocol
// CHECK: copy_addr [[VAL1]]#1 to [initialization] [[VAL4]]#1
// CHECK: [[VAL6:%.*]] = existential_metatype $@thick SomeProtocol.Type, [[VAL4]]#1
// CHECK: destroy_addr [[VAL4]]#1
// CHECK: dealloc_stack [[VAL4]]#0
// CHECK: strong_release [[VAL1]]#0
// CHECK: return [[VAL6]]
bb0(%0 : $*SomeProtocol):
%1 = function_ref @test_existential_metatype : $@convention(thin) (@in SomeProtocol) -> @thick SomeProtocol.Type
%2 = apply %1(%0) : $@convention(thin) (@in SomeProtocol) -> @thick SomeProtocol.Type
%3 = return %2 : $@thick SomeProtocol.Type
}
sil private @top_level_code : $() -> () {
bb0:
%0 = tuple ()
return %0 : $()
}
sil @get_logic_value : $@convention(method) (@inout Bool) -> Builtin.Int1
sil @add_floats : $@convention(thin) (Float32, Float32) -> Float32
sil @convertFromBuiltinFloatLiteral : $@convention(thin) (Builtin.FPIEEE64, @thin Float32.Type) -> Float32
sil @sub_floats : $@convention(thin) (Float32, Float32) -> Float32
sil @foo : $@convention(thin) (Float32, Float32) -> Bool
sil @bar : $@convention(thin) (Float32) -> Bool
// CHECK-LABEL: sil [transparent] @test_control_flow : $@convention(thin) (Float, Float) -> Float
sil [transparent] @test_control_flow : $@convention(thin) (Float, Float) -> Float {
bb0(%0 : $Float, %1 : $Float):
%2 = alloc_box $Float
%3 = alloc_box $Float
store %0 to %2#1 : $*Float
store %1 to %3#1 : $*Float
%6 = function_ref @get_logic_value : $@convention(method) (@inout Bool) -> Builtin.Int1
%7 = function_ref @foo : $@convention(thin) (Float, Float) -> Bool
%8 = load %2#1 : $*Float
%9 = load %3#1 : $*Float
%10 = apply %7(%8, %9) : $@convention(thin) (Float, Float) -> Bool
%11 = alloc_stack $Bool
store %10 to %11#1 : $*Bool
%13 = apply %6(%11#1) : $@convention(method) (@inout Bool) -> Builtin.Int1
dealloc_stack %11#0 : $*@local_storage Bool
cond_br %13, bb1, bb2
bb1:
%16 = load %2#1 : $*Float
unreachable
bb2:
br bb3
bb3:
%19 = function_ref @get_logic_value : $@convention(method) (@inout Bool) -> Builtin.Int1
%20 = function_ref @bar : $@convention(thin) (Float) -> Bool
%21 = load %3#1 : $*Float
%22 = apply %20(%21) : $@convention(thin) (Float) -> Bool
%23 = alloc_stack $Bool
store %22 to %23#1 : $*Bool
%25 = apply %19(%23#1) : $@convention(method) (@inout Bool) -> Builtin.Int1
dealloc_stack %23#0 : $*@local_storage Bool
cond_br %25, bb4, bb5
bb4:
%28 = function_ref @add_floats : $@convention(thin) (Float, Float) -> Float
%29 = load %3#1 : $*Float
%30 = function_ref @convertFromBuiltinFloatLiteral : $@convention(thin) (Builtin.FPIEEE64, @thin Float.Type) -> Float
%31 = metatype $@thin Float.Type
%32 = float_literal $Builtin.FPIEEE64, 0x3FF0000000000000
%33 = apply %30(%32, %31) : $@convention(thin) (Builtin.FPIEEE64, @thin Float.Type) -> Float
%34 = apply %28(%29, %33) : $@convention(thin) (Float, Float) -> Float
store %34 to %3#1 : $*Float
br bb3
bb5:
%37 = load %3#1 : $*Float
br bb6(%37 : $Float)
bb6(%39 : $Float):
strong_release %3#0 : $@box Float
strong_release %2#0 : $@box Float
return %39 : $Float
}
// CHECK-LABEL: sil @inline_test_control_flow : $@convention(thin) (Float) -> Float
sil @inline_test_control_flow : $@convention(thin) (Float) -> Float {
// CHECK: [[BB0:.*]]([[VAL0:%.*]] : $Float):
// CHECK: [[VAL1:%.*]] = alloc_box $Float
// CHECK: store [[VAL0]] to [[VAL1]]#1
// CHECK: [[VAL3:%.*]] = function_ref @sub_floats
// CHECK: [[VAL4:%.*]] = function_ref @add_floats
// CHECK: [[VAL5:%.*]] = load [[VAL1]]#1
// CHECK: [[VAL6:%.*]] = function_ref @convertFromBuiltinFloatLiteral
// CHECK: [[VAL7:%.*]] = metatype $@thin Float.Type
// CHECK: [[VAL8:%.*]] = float_literal $Builtin.FPIEEE64, 0x3FF0000000000000
// CHECK: [[VAL9:%.*]] = apply [[VAL6]]([[VAL8]], [[VAL7]])
// CHECK: [[VAL10:%.*]] = apply [[VAL4]]([[VAL5]], [[VAL9]])
// CHECK: [[VAL11:%.*]] = function_ref @convertFromBuiltinFloatLiteral
// CHECK: [[VAL12:%.*]] = metatype $@thin Float.Type
// CHECK: [[VAL13:%.*]] = float_literal $Builtin.FPIEEE64, 0x4000000000000000
// CHECK: [[VAL14:%.*]] = apply [[VAL11]]([[VAL13]], [[VAL12]])
// CHECK: [[VAL15:%.*]] = alloc_box $Float
// CHECK: [[VAL16:%.*]] = alloc_box $Float
// CHECK: store [[VAL10]] to [[VAL15]]#1
// CHECK: store [[VAL14]] to [[VAL16]]#1
// CHECK: [[VAL19:%.*]] = function_ref @get_logic_value
// CHECK: [[VAL20:%.*]] = function_ref @foo
// CHECK: [[VAL21:%.*]] = load [[VAL15]]#1
// CHECK: [[VAL22:%.*]] = load [[VAL16]]#1
// CHECK: [[VAL23:%.*]] = apply [[VAL20]]([[VAL21]], [[VAL22]])
// CHECK: [[VAL24:%.*]] = alloc_stack $Bool
// CHECK: store [[VAL23]] to [[VAL24]]#1
// CHECK: [[VAL26:%.*]] = apply [[VAL19]]([[VAL24]]#1)
// CHECK: dealloc_stack [[VAL24]]#0
// CHECK: cond_br [[VAL26]], [[BB1:bb[0-9]+]], [[BB2:bb[0-9]+]]
// CHECK: [[BB1]]:
// CHECK: [[VAL29:%.*]] = load [[VAL15]]#1
// CHECK: unreachable
// CHECK: [[BB2]]:
// CHECK: br [[BB3:bb[0-9]+]]
// CHECK: [[BB3]]:
// CHECK: [[VAL32:%.*]] = function_ref @get_logic_value
// CHECK: [[VAL33:%.*]] = function_ref @bar
// CHECK: [[VAL34:%.*]] = load [[VAL16]]#1
// CHECK: [[VAL35:%.*]] = apply [[VAL33]]([[VAL34]])
// CHECK: [[VAL36:%.*]] = alloc_stack $Bool
// CHECK: store [[VAL35]] to [[VAL36]]#1
// CHECK: [[VAL38:%.*]] = apply [[VAL32]]([[VAL36]]#1)
// CHECK: dealloc_stack [[VAL36]]#0
// CHECK: cond_br [[VAL38]], [[BB4:bb[0-9]+]], [[BB5:bb[0-9]+]]
// CHECK: [[BB4]]:
// CHECK: [[VAL41:%.*]] = function_ref @add_floats
// CHECK: [[VAL42:%.*]] = load [[VAL16]]#1
// CHECK: [[VAL43:%.*]] = function_ref @convertFromBuiltinFloatLiteral
// CHECK: [[VAL44:%.*]] = metatype $@thin Float.Type
// CHECK: [[VAL45:%.*]] = float_literal $Builtin.FPIEEE64, 0x3FF0000000000000
// CHECK: [[VAL46:%.*]] = apply [[VAL43]]([[VAL45]], [[VAL44]])
// CHECK: [[VAL47:%.*]] = apply [[VAL41]]([[VAL42]], [[VAL46]])
// CHECK: store [[VAL47]] to [[VAL16]]#1
// CHECK: br [[BB3]]
// CHECK: [[BB5]]:
// CHECK: [[VAL50:%.*]] = load [[VAL16]]#1
// CHECK: br [[BB6:.*]]([[VAL50]]
// CHECK: [[BB6]]([[VAL52:%.*]] : $Float):
// CHECK: strong_release [[VAL16]]#0
// CHECK: strong_release [[VAL15]]#0
// CHECK: br [[BB7:.*]]([[VAL52]]
// CHECK: [[BB7]]([[VAL56:%.*]] : $Float):
// CHECK: [[VAL57:%.*]] = function_ref @convertFromBuiltinFloatLiteral
// CHECK: [[VAL58:%.*]] = metatype $@thin Float.Type
// CHECK: [[VAL59:%.*]] = float_literal $Builtin.FPIEEE64, 0x4008000000000000
// CHECK: [[VAL60:%.*]] = apply [[VAL57]]([[VAL59]], [[VAL58]])
// CHECK: [[VAL61:%.*]] = apply [[VAL3]]([[VAL56]], [[VAL60]])
// CHECK: strong_release [[VAL1]]#0
// CHECK: return [[VAL61]]
bb0(%0 : $Float):
%1 = alloc_box $Float
store %0 to %1#1 : $*Float
%3 = function_ref @sub_floats : $@convention(thin) (Float, Float) -> Float
%4 = function_ref @test_control_flow : $@convention(thin) (Float, Float) -> Float
%5 = function_ref @add_floats : $@convention(thin) (Float, Float) -> Float
%6 = load %1#1 : $*Float
%7 = function_ref @convertFromBuiltinFloatLiteral : $@convention(thin) (Builtin.FPIEEE64, @thin Float.Type) -> Float
%8 = metatype $@thin Float.Type
%9 = float_literal $Builtin.FPIEEE64, 0x3FF0000000000000
%10 = apply %7(%9, %8) : $@convention(thin) (Builtin.FPIEEE64, @thin Float.Type) -> Float
%11 = apply %5(%6, %10) : $@convention(thin) (Float, Float) -> Float
%12 = function_ref @convertFromBuiltinFloatLiteral : $@convention(thin) (Builtin.FPIEEE64, @thin Float.Type) -> Float
%13 = metatype $@thin Float.Type
%14 = float_literal $Builtin.FPIEEE64, 0x4000000000000000
%15 = apply %12(%14, %13) : $@convention(thin) (Builtin.FPIEEE64, @thin Float.Type) -> Float
%16 = apply %4(%11, %15) : $@convention(thin) (Float, Float) -> Float
%17 = function_ref @convertFromBuiltinFloatLiteral : $@convention(thin) (Builtin.FPIEEE64, @thin Float.Type) -> Float
%18 = metatype $@thin Float.Type
%19 = float_literal $Builtin.FPIEEE64, 0x4008000000000000
%20 = apply %17(%19, %18) : $@convention(thin) (Builtin.FPIEEE64, @thin Float.Type) -> Float
%21 = apply %3(%16, %20) : $@convention(thin) (Float, Float) -> Float
strong_release %1#0 : $@box Float
return %21 : $Float
}
// CHECK-LABEL: [transparent] @test_recursive_foo : $@convention(thin) (Float) -> Float
sil [transparent] @test_recursive_foo : $@convention(thin) (Float) -> Float {
// CHECK-NOT: function_ref
// CHECK-NOT: apply
// CHECK: return
bb0(%0 : $Float):
%3 = function_ref @test_recursive_bar : $@convention(thin) (Float) -> Float
%5 = apply %3(%0) : $@convention(thin) (Float) -> Float
return %5 : $Float
}
// CHECK-LABEL: sil [transparent] @test_recursive_bar : $@convention(thin) (Float) -> Float
sil [transparent] @test_recursive_bar : $@convention(thin) (Float) -> Float {
// CHECK-NOT: function_ref
// CHECK-NOT: apply
// CHECK: return
bb0(%0 : $Float):
%3 = function_ref @test_recursive_baz : $@convention(thin) (Float) -> Float
%5 = apply %3(%0) : $@convention(thin) (Float) -> Float
return %5 : $Float
}
// CHECK-LABEL: sil [transparent] @test_recursive_baz : $@convention(thin) (Float) -> Float
sil [transparent] @test_recursive_baz : $@convention(thin) (Float) -> Float {
// CHECK-NOT: function_ref
// CHECK-NOT: apply
// CHECK: return
bb0(%0 : $Float):
return %0 : $Float
}
// CHECK-LABEL: sil [transparent] @test_partial_foo : $@convention(thin) (Int64) -> Int64 {
sil [transparent] @test_partial_foo : $@convention(thin) (Int64) -> Int64 {
// CHECK: [[BB0:.*]]([[VAL0:%.*]] : $Int64):
// CHECK: [[VAL1:%.*]] = function_ref @plus
// CHECK: [[VAL2:%.*]] = apply [[VAL1]]([[VAL0]], [[VAL0]])
// CHECK: return [[VAL2]]
bb0(%0 : $Int64):
%2 = function_ref @test_partial_bar : $@convention(thin) (@callee_owned (Int64) -> Int64, Int64) -> Int64
%3 = function_ref @test_partial_baz : $@convention(thin) (Int64, Int64) -> Int64
%5 = partial_apply %3(%0) : $@convention(thin) (Int64, Int64) -> Int64
%13 = apply %2(%5, %0) : $@convention(thin) (@callee_owned (Int64) -> Int64, Int64) -> Int64
return %13 : $Int64
}
sil [transparent] @test_partial_baz : $@convention(thin) (Int64, Int64) -> Int64 {
bb0(%0 : $Int64, %1 : $Int64):
%6 = function_ref @plus : $@convention(thin) (Int64, Int64) -> Int64
%7 = apply %6(%0, %1) : $@convention(thin) (Int64, Int64) -> Int64
return %7 : $Int64
}
sil [transparent] @test_partial_bar : $@convention(thin) (@callee_owned (Int64) -> Int64, Int64) -> Int64 {
bb0(%0 : $@callee_owned (Int64) -> Int64, %1 : $Int64):
%7 = apply %0(%1) : $@callee_owned (Int64) -> Int64
return %7 : $Int64
}
sil @true_getter : $@convention(thin) () -> Bool
sil [transparent] @short_circuit_or : $@convention(thin) (Bool, @callee_owned () -> Bool) -> Bool {
bb0(%0 : $Bool, %1 : $@callee_owned () -> Bool):
%2 = alloc_box $Bool
%3 = alloc_box $@callee_owned () -> Bool
store %0 to %2#1 : $*Bool
store %1 to %3#1 : $*@callee_owned () -> Bool
%6 = function_ref @get_logic_value : $@convention(method) (@inout Bool) -> Builtin.Int1
%7 = apply %6(%2#1) : $@convention(method) (@inout Bool) -> Builtin.Int1
cond_br %7, bb1, bb2
bb1:
%9 = function_ref @true_getter : $@convention(thin) () -> Bool
%10 = apply %9() : $@convention(thin) () -> Bool
br bb3(%10 : $Bool)
bb2:
%12 = load %3#1 : $*@callee_owned () -> Bool
strong_retain %12 : $@callee_owned () -> Bool
%14 = apply %12() : $@callee_owned () -> Bool
br bb3(%14 : $Bool)
bb3(%16 : $Bool):
strong_release %3#0 : $@box @callee_owned () -> Bool
strong_release %2#0 : $@box Bool
return %16 : $Bool
}
sil private [transparent] @closure0 : $@convention(thin) (@owned @box Bool) -> Bool {
bb0(%0 : $@box Bool):
%1 = project_box %0 : $@box Bool
%2 = tuple ()
%3 = load %1 : $*Bool
strong_release %0 : $@box Bool
return %3 : $Bool
}
sil @test_short_circuit : $@convention(thin) (Bool, Bool) -> Bool {
// CHECK-LABEL: sil @test_short_circuit : $@convention(thin) (Bool, Bool) -> Bool {
// CHECK: cond_br {{%.*}}, [[BB1:bb[0-9]+]], [[BB3:bb[0-9]+]]
// CHECK: bb1:
// CHECK: br [[BB2:.*]](
// CHECK: [[BB2]](
// CHECK: br [[BB4:.*]](
// CHECK: [[BB3]]:
// CHECK: strong_retain [[VAL3:.*]]#0
// CHECK: [[ADDR3:%.*]] = project_box [[VAL3]]#0
// CHECK: {{%.*}} = tuple ()
// CHECK: {{%.*}} = load [[ADDR3]]
// CHECK: strong_release [[VAL3]]#0
// CHECK: br [[BB2]](
// CHECK: [[BB4]](
// CHECK: strong_release [[VAL3]]#0
// CHECK: return {{.*}}
bb0(%0 : $Bool, %1 : $Bool):
%2 = alloc_box $Bool
%3 = alloc_box $Bool
store %0 to %2#1 : $*Bool
store %1 to %3#1 : $*Bool
%6 = function_ref @short_circuit_or : $@convention(thin) (Bool, @callee_owned () -> Bool) -> Bool
%7 = load %2#1 : $*Bool
%8 = function_ref @closure0 : $@convention(thin) (@owned @box Bool) -> Bool
strong_retain %3#0 : $@box Bool
%10 = partial_apply %8(%3#0) : $@convention(thin) (@owned @box Bool) -> Bool
%11 = apply %6(%7, %10) : $@convention(thin) (Bool, @callee_owned () -> Bool) -> Bool
strong_release %3#0 : $@box Bool
strong_release %2#0 : $@box Bool
return %11 : $Bool
}
sil @test_short_circuit2 : $@convention(thin) (Bool, Bool) -> Bool {
// CHECK-LABEL: sil @test_short_circuit2 : $@convention(thin) (Bool, Bool) -> Bool {
// CHECK: cond_br {{%.*}}, [[BB1:bb[0-9]+]], [[BB3:bb[0-9]+]]
// CHECK: bb1:
// CHECK: br [[BB2:.*]](
// CHECK: [[BB2]](
// CHECK: br [[BB4:.*]](
// CHECK: [[BB3]]:
// CHECK: strong_retain [[VAL3:.*]]#0
// CHECK: [[ADDR3:%.*]] = project_box [[VAL3]]#0
// CHECK: {{%.*}} = tuple ()
// CHECK: {{%.*}} = load [[ADDR3]]
// CHECK: strong_release [[VAL3]]#0
// CHECK: br [[BB2]](
// CHECK: [[BB4]](
// CHECK: strong_release [[VAL3]]#0
// CHECK: return {{.*}}
bb0(%0 : $Bool, %1 : $Bool):
%2 = alloc_box $Bool
%3 = alloc_box $Bool
store %0 to %2#1 : $*Bool
store %1 to %3#1 : $*Bool
%6 = function_ref @short_circuit_or : $@convention(thin) (Bool, @callee_owned () -> Bool) -> Bool
%7 = load %2#1 : $*Bool
%8 = function_ref @closure0 : $@convention(thin) (@owned @box Bool) -> Bool
strong_retain %3#0 : $@box Bool
%10 = partial_apply %8(%3#0) : $@convention(thin) (@owned @box Bool) -> Bool
strong_retain %10 : $@callee_owned () -> Bool
%12 = tuple ()
%11 = apply %6(%7, %10) : $@convention(thin) (Bool, @callee_owned () -> Bool) -> Bool
strong_release %3#0 : $@box Bool
strong_release %2#0 : $@box Bool
return %11 : $Bool
}
sil [transparent] @convertFromBultinIntegerLiteral : $@convention(thin) (Builtin.Int2048, @thin Int64.Type) -> Int64 {
bb0(%0 : $Builtin.Int2048, %1 : $@thin Int64.Type):
%3 = builtin "s_to_s_checked_trunc_Int2048_Int64"(%0 : $Builtin.Int2048) : $(Builtin.Int64, Builtin.Int1)
%4 = tuple_extract %3 : $(Builtin.Int64, Builtin.Int1), 0
%5 = struct $Int64 (%4 : $Builtin.Int64)
return %5 : $Int64
}
sil @test_with_dead_argument : $@convention(thin) () -> () {
bb0:
%0 = tuple ()
%1 = alloc_box $Int64
%2 = function_ref @convertFromBultinIntegerLiteral : $@convention(thin) (Builtin.Int2048, @thin Int64.Type) -> Int64
%3 = metatype $@thin Int64.Type
%4 = integer_literal $Builtin.Int2048, 1
%5 = apply %2(%4, %3) : $@convention(thin) (Builtin.Int2048, @thin Int64.Type) -> Int64
store %5 to %1#1 : $*Int64
strong_release %1#0 : $@box Int64
%8 = tuple ()
return %8 : $()
}
// CHECK-LABEL: sil @test_with_dead_argument : $@convention(thin) () -> () {
// CHECK-NOT: Type
sil [transparent] @_TF2t222inner_open_existentialFT2cpPS_2CP__T_ : $@convention(thin) (@owned CP) -> () {
bb0(%0 : $CP):
strong_retain %0 : $CP // id: %2
%3 = open_existential_ref %0 : $CP to $@opened("01234567-89ab-cdef-0123-000000000000") CP // user: %5
%9 = tuple () // user: %10
return %9 : $() // id: %10
}
// CHECK-LABEL: sil @_TF2t222outer_open_existentialFT3cp1PS_2CP_3cp2PS0___T_
sil @_TF2t222outer_open_existentialFT3cp1PS_2CP_3cp2PS0___T_ : $@convention(thin) (@owned CP, @owned CP) -> () {
bb0(%0 : $CP, %1 : $CP):
%4 = function_ref @_TF2t222inner_open_existentialFT2cpPS_2CP__T_ : $@convention(thin) (@owned CP) -> () // user: %6
strong_retain %0 : $CP // id: %5
// CHECK: open_existential_ref %0 : $CP to $@opened([[N1:".*"]]) CP
%6 = apply %4(%0) : $@convention(thin) (@owned CP) -> ()
%7 = function_ref @_TF2t222inner_open_existentialFT2cpPS_2CP__T_ : $@convention(thin) (@owned CP) -> () // user: %9
strong_retain %1 : $CP // id: %8
// CHECK: open_existential_ref %1 : $CP to $@opened([[N2:".*"]]) CP
%9 = apply %7(%1) : $@convention(thin) (@owned CP) -> ()
strong_release %1 : $CP // id: %10
strong_release %0 : $CP // id: %11
%12 = tuple () // user: %13
return %12 : $() // id: %13
}
class C : CP {
func f() -> Self
}
sil [transparent] @transparent_generic : $@convention(thin) <T where T : CP> (@owned T, @owned C) -> () {
bb0(%0 : $T, %1 : $C):
debug_value %0 : $T
debug_value %1 : $C
strong_release %1 : $C
strong_release %0 : $T
%6 = tuple ()
return %6 : $()
}
// CHECK-LABEL: sil @fully_concrete_call : $@convention(thin) (@owned C) -> () {
sil @fully_concrete_call : $@convention(thin) (@owned C) -> () {
bb0(%0 : $C):
debug_value %0 : $C
// CHECK-NOT: function_ref @transparent_generic
%2 = function_ref @transparent_generic : $@convention(thin) _0_0 where τ_0_0 : CP> (@owned τ_0_0, @owned C) -> ()
strong_retain %0 : $C
strong_retain %0 : $C
// CHECK-NOT: apply
%5 = apply %2<C>(%0, %0) : $@convention(thin) _0_0 where τ_0_0 : CP> (@owned τ_0_0, @owned C) -> ()
strong_release %0 : $C
%7 = tuple ()
return %7 : $()
}
// CHECK-LABEL: sil [transparent] @inner : $@convention(thin) <T1, T2> (@out T2, @in T1, @in T2) -> () {
sil [transparent] @inner : $@convention(thin) <T1, T2> (@out T2, @in T1, @in T2) -> () {
bb0(%0 : $*T2, %1 : $*T1, %2 : $*T2):
debug_value_addr %1 : $*T1
debug_value_addr %2 : $*T2
copy_addr [take] %2 to [initialization] %0 : $*T2
destroy_addr %1 : $*T1
%7 = tuple ()
return %7 : $()
}
// FIXME: We currently do not inline generics unless we have concrete types
// for all substitutions.
// CHECK-LABEL: sil [transparent] @middle : $@convention(thin) <T> (@out T, Int, @in T) -> () {
sil [transparent] @middle : $@convention(thin) <T> (@out T, Int, @in T) -> () {
bb0(%0 : $*T, %1 : $Int, %2 : $*T):
debug_value %1 : $Int
debug_value_addr %2 : $*T
// CHECK-NOT: [[REF:%[a-zA-Z0-9]+]] = function_ref @inner
%5 = function_ref @inner : $@convention(thin) _0_0, τ_0_1> (@out τ_0_1, @in τ_0_0, @in τ_0_1) -> ()
%6 = alloc_stack $Int
store %1 to %6#1 : $*Int
%8 = alloc_stack $T
copy_addr %2 to [initialization] %8#1 : $*T
// CHECK-NOT: apply
%10 = apply %5<Int, T>(%0, %6#1, %8#1) : $@convention(thin) <τ_0_0, τ_0_1> (@out τ_0_1, @in τ_0_0, @in τ_0_1) -> ()
dealloc_stack %8#0 : $*@local_storage T
dealloc_stack %6#0 : $*@local_storage Int
destroy_addr %2 : $*T
%14 = tuple ()
return %14 : $()
}
// CHECK-LABEL: sil [transparent] @outer : $@convention(thin) (Int) -> Int {
sil [transparent] @outer : $@convention(thin) (Int) -> Int {
bb0(%0 : $Int):
debug_value %0 : $Int
// CHECK-NOT: function_ref @middle
%2 = function_ref @middle : $@convention(thin) _0_0> (@out τ_0_0, Int, @in τ_0_0) -> ()
%7 = alloc_stack $Int
store %0 to %7#1 : $*Int
%9 = alloc_stack $Int
// CHECK-NOT: apply
%10 = apply %2<Int>(%9#1, %0, %7#1) : $@convention(thin) <τ_0_0> (@out τ_0_0, Int, @in τ_0_0) -> ()
%11 = load %9#1 : $*Int
dealloc_stack %9#0 : $*@local_storage Int
dealloc_stack %7#0 : $*@local_storage Int
return %11 : $Int
}
@objc protocol Foo { func foo() }
// CHECK-LABEL: sil hidden [transparent] @protocolConstrained
sil hidden [transparent] @protocolConstrained : $@convention(thin) <T where T : Foo> (@owned T) -> () {
bb0(%0 : $T):
debug_value %0 : $T
strong_retain %0 : $T
%3 = witness_method [volatile] $T, #Foo.foo!1.foreign : $@convention(objc_method) <τ_0_0 where τ_0_0 : Foo> (τ_0_0) -> ()
%4 = apply %3<T>(%0) : $@convention(objc_method) _0_0 where τ_0_0 : Foo> _0_0) -> ()
strong_release %0 : $T
strong_release %0 : $T
%7 = tuple ()
return %7 : $()
}
// CHECK-LABEL: sil hidden @protocolTypedParam
sil hidden @protocolTypedParam : $@convention(thin) (@owned Foo) -> () {
bb0(%0 : $Foo):
debug_value %0 : $Foo
// CHECK-NOT: function_ref @protocolConstrained
%2 = function_ref @protocolConstrained : $@convention(thin) _0_0 where τ_0_0 : Foo> (@owned τ_0_0) -> ()
strong_retain %0 : $Foo
// CHECK-NOT: apply
// CHECK: [[METHOD:%[a-zA-Z0-9]+]] = witness_method [volatile] $Foo, #Foo.foo!1.foreign : $@convention(objc_method) <τ_0_0 where τ_0_0 : Foo> (τ_0_0) -> ()
// CHECK: apply [[METHOD]]<Foo>(%0) : $@convention(objc_method) <τ_0_0 where τ_0_0 : Foo> (τ_0_0) -> ()
%4 = apply %2<Foo>(%0) : $@convention(thin) _0_0 where τ_0_0 : Foo> (@owned τ_0_0) -> ()
strong_release %0 : $Foo
%6 = tuple ()
return %6 : $()
}
// CHECK-LABEL: sil [transparent] @identity
sil [transparent] @identity : $@convention(thin) <T> (@out T, @in T) -> () {
bb0(%0 : $*T, %1 : $*T):
debug_value_addr %1 : $*T
copy_addr [take] %1 to [initialization] %0 : $*T
%4 = tuple ()
// CHECK: return
return %4 : $()
}
// CHECK-LABEL: sil @applyIdentity
sil @applyIdentity : $@convention(thin) <T> (@out T, @in T) -> () {
bb0(%0 : $*T, %1 : $*T):
debug_value_addr %1 : $*T
%3 = function_ref @identity : $@convention(thin) _0_0> (@out τ_0_0, @in τ_0_0) -> ()
%4 = alloc_stack $T
copy_addr %1 to [initialization] %4#1 : $*T
// CHECK-NOT: apply
%6 = apply %3<T>(%0, %4#1) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> ()
dealloc_stack %4#0 : $*@local_storage T
destroy_addr %1 : $*T
%9 = tuple ()
// CHECK: return
return %9 : $()
}
// CHECK-LABEL: sil [transparent] @partial
sil [transparent] @partial : $@convention(thin) <T, U> (@out U, @in T, @owned @callee_owned (@out U, @in T) -> ()) -> () {
bb0(%0 : $*U, %1 : $*T, %2 : $@callee_owned (@out U, @in T) -> ()):
debug_value_addr %1 : $*T
debug_value %2 : $@callee_owned (@out U, @in T) -> ()
strong_retain %2 : $@callee_owned (@out U, @in T) -> ()
%6 = alloc_stack $T
copy_addr %1 to [initialization] %6#1 : $*T
// CHECK: apply %2
%8 = apply %2(%0, %6#1) : $@callee_owned (@out U, @in T) -> ()
dealloc_stack %6#0 : $*@local_storage T
strong_release %2 : $@callee_owned (@out U, @in T) -> ()
destroy_addr %1 : $*T
%12 = tuple ()
// CHECK: return
return %12 : $()
}
// CHECK-LABEL: sil @applyPartial
sil @applyPartial : $@convention(thin) <U> (@out U, Builtin.Int32, @owned @callee_owned (@out U, Builtin.Int32) -> ()) -> () {
bb0(%0 : $*U, %1 : $Builtin.Int32, %2 : $@callee_owned (@out U, Builtin.Int32) -> ()):
debug_value %1 : $Builtin.Int32
debug_value %2 : $@callee_owned (@out U, Builtin.Int32) -> ()
%5 = function_ref @partial : $@convention(thin) _0_0, τ_0_1> (@out τ_0_1, @in τ_0_0, @owned @callee_owned (@out τ_0_1, @in τ_0_0) -> ()) -> ()
%6 = alloc_stack $Builtin.Int32
store %1 to %6#1 : $*Builtin.Int32
strong_retain %2 : $@callee_owned (@out U, Builtin.Int32) -> ()
// CHECK-NOT: function_ref @reabstractionThunk
%9 = function_ref @reabstractionThunk : $@convention(thin) _0_0> (@out τ_0_0, @in Builtin.Int32, @owned @callee_owned (@out τ_0_0, Builtin.Int32) -> ()) -> ()
// CHECK-NOT: partial_apply
%10 = partial_apply %9<U>(%2) : $@convention(thin) _0_0> (@out τ_0_0, @in Builtin.Int32, @owned @callee_owned (@out τ_0_0, Builtin.Int32) -> ()) -> ()
// CHECK-NOT: apply
// CHECK: apply %2
%11 = apply %5<Builtin.Int32, U>(%0, %6#1, %10) : $@convention(thin) <τ_0_0, τ_0_1> (@out τ_0_1, @in τ_0_0, @owned @callee_owned (@out τ_0_1, @in τ_0_0) -> ()) -> ()
dealloc_stack %6#0 : $*@local_storage Builtin.Int32
strong_release %2 : $@callee_owned (@out U, Builtin.Int32) -> ()
%14 = tuple ()
// CHECK: return
return %14 : $()
}
// CHECK-LABEL: sil [transparent] @reabstractionThunk
sil [transparent] @reabstractionThunk : $@convention(thin) <U> (@out U, @in Builtin.Int32, @owned @callee_owned (@out U, Builtin.Int32) -> ()) -> () {
bb0(%0 : $*U, %1 : $*Builtin.Int32, %2 : $@callee_owned (@out U, Builtin.Int32) -> ()):
%3 = load %1 : $*Builtin.Int32
%4 = apply %2(%0, %3) : $@callee_owned (@out U, Builtin.Int32) -> ()
// CHECK: return
return %4 : $()
}
// CHECK-LABEL: sil [transparent] @inner_transparent
sil [transparent] @inner_transparent : $@convention(thin) (@owned @callee_owned () -> Builtin.Int8) -> Builtin.Int8 {
// CHECK: bb0
bb0(%0 : $@callee_owned () -> Builtin.Int8):
strong_retain %0 : $@callee_owned () -> Builtin.Int8
%3 = apply %0() : $@callee_owned () -> Builtin.Int8
strong_release %0 : $@callee_owned () -> Builtin.Int8
// CHECK: return
return %3 : $Builtin.Int8
}
// CHECK-LABEL: sil [transparent] @outer_transparent
sil [transparent] @outer_transparent : $@convention(thin) (@owned @callee_owned () -> Builtin.Int8) -> Builtin.Int8 {
// CHECK: bb0
bb0(%0 : $@callee_owned () -> Builtin.Int8):
%2 = function_ref @inner_transparent : $@convention(thin) (@owned @callee_owned () -> Builtin.Int8) -> Builtin.Int8
strong_retain %0 : $@callee_owned () -> Builtin.Int8
%4 = apply %2(%0) : $@convention(thin) (@owned @callee_owned () -> Builtin.Int8) -> Builtin.Int8
strong_release %0 : $@callee_owned () -> Builtin.Int8
// CHECK: return
return %4 : $Builtin.Int8
}
// We remove everything here now.
// CHECK-LABEL: sil @testouter_transparent
sil @testouter_transparent : $@convention(thin) (Builtin.Int8) -> Builtin.Int8 {
// CHECK: bb0
// CHECK-NEXT: return
bb0(%0 : $Builtin.Int8):
%2 = function_ref @outer_transparent : $@convention(thin) (@owned @callee_owned () -> Builtin.Int8) -> Builtin.Int8
%3 = function_ref @identity_closure : $@convention(thin) (Builtin.Int8) -> Builtin.Int8
%4 = partial_apply %3(%0) : $@convention(thin) (Builtin.Int8) -> Builtin.Int8
%5 = apply %2(%4) : $@convention(thin) (@owned @callee_owned () -> Builtin.Int8) -> Builtin.Int8
return %5 : $Builtin.Int8
}
// We delete this now.
//
// CHECK-NOT: sil shared [transparent] @identity_closure
sil shared [transparent] @identity_closure : $@convention(thin) (Builtin.Int8) -> Builtin.Int8 {
bb0(%0 : $Builtin.Int8):
return %0 : $Builtin.Int8
}