| // RUN: %target-sil-opt -address-lowering -enable-sil-opaque-values -optimize-opaque-address-lowering -emit-sorted-sil -assume-parsing-unqualified-ownership-sil %s | %FileCheck %s |
| |
| import Builtin |
| |
| sil_stage canonical |
| // CHECK: sil_stage lowered |
| |
| typealias AnyObject = Builtin.AnyObject |
| typealias Int = Builtin.Int64 |
| |
| // CHECK-LABEL: sil hidden @f010_addrlower_identity : $@convention(thin) <T> (@in T) -> @out T { |
| // CHECK: bb0(%0 : $*T, %1 : $*T): |
| // CHECK: copy_addr [take] %1 to [initialization] %0 : $*T |
| // CHECK: return %{{.*}} : $() |
| // CHECK-LABEL: } // end sil function 'f010_addrlower_identity' |
| sil hidden @f010_addrlower_identity : $@convention(thin) <T> (@in T) -> @out T { |
| bb0(%0 : $T): |
| return %0 : $T |
| } |
| |
| sil hidden [noinline] @f020_multiResult : $@convention(thin) <T> (@in T) -> (@out T, @out T, @out T) { |
| bb0(%0 : $T): |
| %2 = copy_value %0 : $T |
| %3 = copy_value %0 : $T |
| %4 = copy_value %0 : $T |
| destroy_value %0 : $T |
| %6 = tuple (%2 : $T, %3 : $T, %4 : $T) |
| return %6 : $(T, T, T) |
| } |
| |
| // Test returning an opaque tuple of tuples as a concrete tuple. |
| // The multiResult call is specialized, but the SIL result convention does not change. |
| // --- |
| // CHECK-LABEL: sil @f021_callMultiResult : $@convention(thin) (Builtin.Int64) -> (Builtin.Int64, Builtin.Int64, Builtin.Int64) { |
| // CHECK: bb0(%0 : $Builtin.Int64): |
| // CHECK: %[[FN:.*]] = function_ref @f020_multiResult : $@convention(thin) <τ_0_0> (@in τ_0_0) -> (@out τ_0_0, @out τ_0_0, @out τ_0_0) |
| // CHECK: %[[IN:.*]] = alloc_stack $Builtin.Int64 |
| // CHECK: store %0 to %[[IN]] : $*Builtin.Int64 |
| // CHECK: %[[OUT1:.*]] = alloc_stack $Builtin.Int64 |
| // CHECK: %[[OUT2:.*]] = alloc_stack $Builtin.Int64 |
| // CHECK: %[[OUT3:.*]] = alloc_stack $Builtin.Int64 |
| // CHECK: %{{.*}} = apply %[[FN]]<Builtin.Int64>(%[[OUT1]], %[[OUT2]], %[[OUT3]], %[[IN]]) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> (@out τ_0_0, @out τ_0_0, @out τ_0_0) |
| // CHECK: %[[R3:.*]] = load %[[OUT3]] : $*Builtin.Int64 |
| // CHECK: dealloc_stack %[[OUT3]] : $*Builtin.Int64 |
| // CHECK: %[[R2:.*]] = load %[[OUT2]] : $*Builtin.Int64 |
| // CHECK: dealloc_stack %[[OUT2]] : $*Builtin.Int64 |
| // CHECK: %[[R1:.*]] = load %[[OUT1]] : $*Builtin.Int64 |
| // CHECK: dealloc_stack %[[OUT1]] : $*Builtin.Int64 |
| // CHECK: dealloc_stack %[[IN]] : $*Builtin.Int64 |
| // CHECK: %[[R:.*]] = tuple (%[[R1]] : $Builtin.Int64, %[[R2]] : $Builtin.Int64, %[[R3]] : $Builtin.Int64) |
| // CHECK: return %[[R]] : $(Builtin.Int64, Builtin.Int64, Builtin.Int64) |
| // CHECK-LABEL: } // end sil function 'f021_callMultiResult' |
| sil @f021_callMultiResult : $@convention(thin) (Int) -> (Int, Int, Int) { |
| bb0(%0 : $Int): |
| %1 = function_ref @f020_multiResult : $@convention(thin) <τ_0_0> (@in τ_0_0) -> (@out τ_0_0, @out τ_0_0, @out τ_0_0) |
| %2 = apply %1<Int>(%0) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> (@out τ_0_0, @out τ_0_0, @out τ_0_0) |
| %3 = tuple_extract %2 : $(Int, Int, Int), 0 |
| %4 = tuple_extract %2 : $(Int, Int, Int), 1 |
| %5 = tuple_extract %2 : $(Int, Int, Int), 2 |
| %6 = tuple (%3 : $Int, %4 : $Int, %5 : $Int) |
| return %6 : $(Int, Int, Int) |
| } |
| |
| // CHECK-LABEL: sil @f030_returnPair : $@convention(thin) <T> (@in T) -> (@out T, @out T) { |
| // CHECK: bb0(%0 : $*T, %1 : $*T, %2 : $*T): |
| // CHECK: copy_addr %2 to [initialization] %0 : $*T |
| // CHECK: copy_addr [take] %2 to [initialization] %1 : $*T |
| // CHECK: %[[R:.*]] = tuple () |
| // CHECK: return %[[R]] : $() |
| // CHECK-LABEL: } // end sil function 'f030_returnPair' |
| sil @f030_returnPair : $@convention(thin) <T> (@in T) -> (@out T, @out T) { |
| bb0(%0 : $T): |
| %2 = copy_value %0 : $T |
| %3 = tuple (%2 : $T, %0 : $T) |
| return %3 : $(T, T) |
| } |
| |
| // CHECK-LABEL: sil @f031_unusedIndirect : $@convention(thin) <T> (@in T) -> @out T { |
| // CHECK: bb0(%0 : $*T, %1 : $*T): |
| // CHECK: %[[LOC0:.*]] = alloc_stack $T |
| // CHECK: %[[OUT1:.*]] = alloc_stack $T |
| // CHECK: %[[LOC1:.*]] = alloc_stack $T |
| // CHECK: %[[OUT2:.*]] = alloc_stack $T |
| // CHECK: // function_ref f030_returnPair |
| // CHECK: %[[F:.*]] = function_ref @f030_returnPair : $@convention(thin) <τ_0_0> (@in τ_0_0) -> (@out τ_0_0, @out τ_0_0) |
| // CHECK: copy_addr %1 to [initialization] %[[LOC0]] : $*T |
| // CHECK: %[[R0:.*]] = apply %[[F]]<T>(%[[OUT1]], %[[OUT2]], %[[LOC0]]) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> (@out τ_0_0, @out τ_0_0) |
| // CHECK: copy_addr %[[OUT1]] to [initialization] %[[LOC1]] : $*T |
| // CHECK: copy_addr %[[OUT2]] to [initialization] %0 : $*T |
| // CHECK: destroy_addr %[[OUT1]] : $*T |
| // CHECK: destroy_addr %[[OUT2]] : $*T |
| // CHECK: destroy_addr %[[LOC1]] : $*T |
| // CHECK: destroy_addr %1 : $*T |
| // CHECK: %[[R:.*]] = tuple () |
| // CHECK: dealloc_stack %[[OUT2]] : $*T |
| // CHECK: dealloc_stack %[[LOC1]] : $*T |
| // CHECK: dealloc_stack %[[OUT1]] : $*T |
| // CHECK: dealloc_stack %[[LOC0]] : $*T |
| // CHECK: return %[[R]] : $() |
| // CHECK-LABEL: } // end sil function 'f031_unusedIndirect' |
| sil @f031_unusedIndirect : $@convention(thin) <T> (@in T) -> @out T { |
| bb0(%0 : $T): |
| %2 = function_ref @f030_returnPair : $@convention(thin) <τ_0_0> (@in τ_0_0) -> (@out τ_0_0, @out τ_0_0) |
| %3 = copy_value %0 : $T |
| %4 = apply %2<T>(%3) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> (@out τ_0_0, @out τ_0_0) |
| %5 = tuple_extract %4 : $(T, T), 0 |
| %6 = copy_value %5 : $T |
| %7 = tuple_extract %4 : $(T, T), 1 |
| %8 = copy_value %7 : $T |
| destroy_value %4 : $(T, T) |
| destroy_value %6 : $T |
| destroy_value %0 : $T |
| return %8 : $T |
| } |
| |
| sil hidden @f040_consumeArg : $@convention(thin) <T> (@in T) -> () { |
| bb0(%0 : $T): |
| destroy_value %0 : $T |
| %3 = tuple () |
| return %3 : $() |
| } |
| |
| // CHECK-LABEL: sil @f041_opaqueArg : $@convention(thin) <T> (@in T) -> () { |
| // CHECK: bb0(%0 : $*T): |
| // CHECK: %[[LOC:.*]] = alloc_stack $T |
| // CHECK: %[[FN:.*]] = function_ref @f040_consumeArg : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () |
| // CHECK: copy_addr %0 to [initialization] %[[LOC]] : $*T |
| // CHECK: %{{.*}} = apply %[[FN]]<T>(%[[LOC]]) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () |
| // CHECK: destroy_addr %0 : $*T |
| // CHECK: %[[R:.*]] = tuple () |
| // CHECK: dealloc_stack %[[LOC]] : $*T |
| // CHECK: return %[[R]] : $() |
| // CHECK-LABEL: } // end sil function 'f041_opaqueArg' |
| sil @f041_opaqueArg : $@convention(thin) <T> (@in T) -> () { |
| bb0(%0 : $T): |
| %2 = function_ref @f040_consumeArg : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () |
| %3 = copy_value %0 : $T |
| %4 = apply %2<T>(%3) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () |
| destroy_value %0 : $T |
| %6 = tuple () |
| return %6 : $() |
| } |
| |
| // CHECK-LABEL: sil @f050_storeinout : $@convention(thin) <T> (@inout T, @inout T, @in T) -> () { |
| // CHECK: bb0(%0 : $*T, %1 : $*T, %2 : $*T): |
| // CHECK: %[[PREV1:.*]] = alloc_stack $T |
| // CHECK: %[[PREV2:.*]] = alloc_stack $T |
| // CHECK: debug_value_addr %0 : $*T, var, name "t", argno 1 |
| // CHECK: debug_value_addr %1 : $*T, var, name "u", argno 2 |
| // CHECK: debug_value_addr %2 : $*T |
| // CHECK: copy_addr [take] %0 to [initialization] %[[PREV1]] : $*T |
| // CHECK: copy_addr %2 to [initialization] %0 : $*T |
| // CHECK: destroy_addr %[[PREV1]] : $*T |
| // CHECK: copy_addr [take] %1 to [initialization] %[[PREV2]] : $*T |
| // CHECK: copy_addr %2 to [initialization] %1 : $*T |
| // CHECK: destroy_addr %[[PREV2]] : $*T |
| // CHECK: destroy_addr %2 : $*T |
| // CHECK: %[[R:.*]] = tuple () |
| // CHECK: dealloc_stack %[[PREV2]] : $*T |
| // CHECK: dealloc_stack %[[PREV1]] : $*T |
| // CHECK: return %[[R]] : $() |
| // CHECK-LABEL: } // end sil function 'f050_storeinout' |
| sil @f050_storeinout : $@convention(thin) <T> (@inout T, @inout T, @in T) -> () { |
| bb0(%0 : $*T, %1 : $*T, %2 : $T): |
| debug_value_addr %0 : $*T, var, name "t", argno 1 |
| debug_value_addr %1 : $*T, var, name "u", argno 2 |
| debug_value %2 : $T, let, name "x", argno 3 |
| %6 = copy_value %2 : $T |
| %7 = load %0 : $*T |
| store %6 to %0 : $*T |
| destroy_value %7 : $T |
| %10 = copy_value %2 : $T |
| %11 = load %1 : $*T |
| store %10 to %1 : $*T |
| destroy_value %11 : $T |
| destroy_value %2 : $T |
| %15 = tuple () |
| return %15 : $() |
| } |
| |
| sil hidden @f060_mutate : $@convention(thin) <T> (@inout T, @in T) -> () { |
| bb0(%0 : $*T, %1 : $T): |
| %4 = copy_value %1 : $T |
| %5 = load %0 : $*T |
| store %4 to %0 : $*T |
| destroy_value %5 : $T |
| destroy_value %1 : $T |
| %9 = tuple () |
| return %9 : $() |
| } |
| |
| // CHECK-LABEL: sil @f061_callinout : $@convention(thin) <T> (@in T) -> () { |
| // CHECK: bb0(%0 : $*T): |
| // CHECK: %[[LOC2:.*]] = alloc_stack $T |
| // CHECK: %[[LOC1:.*]] = alloc_stack $T |
| // CHECK: copy_addr %0 to [initialization] %[[LOC1]] : $*T |
| // CHECK: %[[FN:.*]] = function_ref @f060_mutate : $@convention(thin) <τ_0_0> (@inout τ_0_0, @in τ_0_0) -> () |
| // CHECK: copy_addr %0 to [initialization] %[[LOC2]] : $*T |
| // CHECK: %{{.*}} = apply %[[FN]]<T>(%[[LOC1]], %[[LOC2]]) : $@convention(thin) <τ_0_0> (@inout τ_0_0, @in τ_0_0) -> () |
| // CHECK: destroy_addr %[[LOC1]] : $*T |
| // CHECK: destroy_addr %0 : $*T |
| // CHECK: %[[R:.*]] = tuple () |
| // CHECK: dealloc_stack %[[LOC1]] : $*T |
| // CHECK: dealloc_stack %[[LOC2]] : $*T |
| // CHECK: return %[[R]] : $() |
| // CHECK-LABEL: } // end sil function 'f061_callinout' |
| sil @f061_callinout : $@convention(thin) <T> (@in T) -> () { |
| bb0(%0 : $T): |
| %1 = alloc_stack $T, var, name "u" |
| %3 = copy_value %0 : $T |
| store %3 to %1 : $*T |
| %5 = function_ref @f060_mutate : $@convention(thin) <τ_0_0> (@inout τ_0_0, @in τ_0_0) -> () |
| %6 = copy_value %0 : $T |
| %7 = apply %5<T>(%1, %6) : $@convention(thin) <τ_0_0> (@inout τ_0_0, @in τ_0_0) -> () |
| destroy_addr %1 : $*T |
| destroy_value %0 : $T |
| %10 = tuple () |
| dealloc_stack %1 : $*T |
| return %10 : $() |
| } |
| |
| public protocol C : class {} |
| |
| // CHECK-LABEL: sil @f070_mixedResult1 : $@convention(thin) <T> (@in T, @owned C) -> (@out T, @owned C) { |
| // CHECK: bb0(%0 : $*T, %1 : $*T, %2 : $C): |
| // CHECK: copy_addr [take] %1 to [initialization] %0 : $*T |
| // CHECK: return %2 : $C |
| // CHECK-LABEL: } // end sil function 'f070_mixedResult1' |
| sil @f070_mixedResult1 : $@convention(thin) <T> (@in T, @owned C) -> (@out T, @owned C) { |
| bb0(%0 : $T, %1 : $C): |
| %4 = tuple (%0 : $T, %1 : $C) |
| return %4 : $(T, C) |
| } |
| |
| // CHECK-LABEL: sil @f071_mixedResult2 : $@convention(thin) <T> (@in T, @owned C) -> (@out T, @out T, @owned C, @owned C) { |
| // CHECK: bb0(%0 : $*T, %1 : $*T, %2 : $*T, %3 : $C): |
| // CHECK: copy_addr %2 to [initialization] %0 : $*T |
| // CHECK: strong_retain %3 : $C |
| // CHECK: copy_addr [take] %2 to [initialization] %1 : $*T |
| // CHECK: %[[T:.*]] = tuple (%3 : $C, %3 : $C) |
| // CHECK: return %[[T]] : $(C, C) |
| // CHECK-LABEL: } // end sil function 'f071_mixedResult2' |
| sil @f071_mixedResult2 : $@convention(thin) <T> (@in T, @owned C) -> (@out T, @out T, @owned C, @owned C) { |
| bb0(%0 : $T, %1 : $C): |
| %4 = copy_value %0 : $T |
| strong_retain %1 : $C |
| %6 = tuple (%4 : $T, %0 : $T, %1 : $C, %1 : $C) |
| return %6 : $(T, T, C, C) |
| } |
| |
| // CHECK-LABEL: sil @f072_callMixedResult1 : $@convention(thin) <T> (@in T, @owned C) -> (@out T, @owned C) { |
| // CHECK: bb0(%0 : $*T, %1 : $*T, %2 : $C): |
| // CHECK: %[[LIN:.*]] = alloc_stack $T |
| // CHECK: %[[OUT:.*]] = alloc_stack $T |
| // CHECK: // function_ref f070_mixedResult1 |
| // CHECK: %[[F:.*]] = function_ref @f070_mixedResult1 : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned C) -> (@out τ_0_0, @owned C) |
| // CHECK: copy_addr %1 to [initialization] %[[LIN]] : $*T |
| // CHECK: strong_retain %2 : $C |
| // CHECK: %[[R:.*]] = apply %[[F]]<T>(%[[OUT]], %[[LIN]], %2) : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned C) -> (@out τ_0_0, @owned C) |
| // CHECK: copy_addr %[[OUT]] to [initialization] %0 : $*T |
| // CHECK: strong_retain %[[R]] : $C |
| // CHECK: destroy_addr %[[OUT]] : $*T |
| // CHECK: strong_release %[[R]] : $C |
| // CHECK: strong_release %2 : $C |
| // CHECK: destroy_addr %1 : $*T |
| // CHECK: dealloc_stack %[[OUT]] : $*T |
| // CHECK: dealloc_stack %[[LIN]] : $*T |
| // CHECK: return %[[R]] : $C |
| // CHECK-LABEL: } // end sil function 'f072_callMixedResult1' |
| sil @f072_callMixedResult1 : $@convention(thin) <T> (@in T, @owned C) -> (@out T, @owned C) { |
| bb0(%0 : $T, %1 : $C): |
| %4 = function_ref @f070_mixedResult1 : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned C) -> (@out τ_0_0, @owned C) |
| %5 = copy_value %0 : $T |
| strong_retain %1 : $C |
| %7 = apply %4<T>(%5, %1) : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned C) -> (@out τ_0_0, @owned C) |
| %8 = tuple_extract %7 : $(T, C), 0 |
| %9 = copy_value %8 : $T |
| %10 = tuple_extract %7 : $(T, C), 1 |
| strong_retain %10 : $C |
| destroy_value %7 : $(T, C) |
| strong_release %1 : $C |
| destroy_value %0 : $T |
| %15 = tuple (%9 : $T, %10 : $C) |
| return %15 : $(T, C) |
| } |
| |
| // CHECK-LABEL: sil @f073_callMixedResult2 : $@convention(thin) <T> (@in T, @owned C) -> (@out T, @out T, @owned C, @owned C) { |
| // CHECK: bb0(%0 : $*T, %1 : $*T, %2 : $*T, %3 : $C): |
| // CHECK: %[[LOC0:.*]] = alloc_stack $T |
| // CHECK: %[[OUT1:.*]] = alloc_stack $T |
| // CHECK: %[[OUT2:.*]] = alloc_stack $T |
| // CHECK: %[[F:.*]] = function_ref @f071_mixedResult2 : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned C) -> (@out τ_0_0, @out τ_0_0, @owned C, @owned C) |
| // CHECK: copy_addr %2 to [initialization] %[[LOC0]] : $*T |
| // CHECK: strong_retain %3 : $C |
| // CHECK: %[[R:.*]] = apply %[[F]]<T>(%[[OUT1]], %[[OUT2]], %[[LOC0]], %3) : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned C) -> (@out τ_0_0, @out τ_0_0, @owned C, @owned C) |
| // CHECK: %[[T2:.*]] = tuple_extract %[[R]] : $(C, C), 1 |
| // CHECK: %[[T1:.*]] = tuple_extract %[[R]] : $(C, C), 0 |
| // CHECK: copy_addr %[[OUT1]] to [initialization] %0 : $*T |
| // CHECK: copy_addr %[[OUT2]] to [initialization] %1 : $*T |
| // CHECK: strong_retain %[[T1]] : $C |
| // CHECK: strong_retain %[[T2]] : $C |
| // CHECK: destroy_addr %[[OUT1]] : $*T |
| // CHECK: destroy_addr %[[OUT2]] : $*T |
| // CHECK: strong_release %[[T1]] : $C |
| // CHECK: strong_release %[[T2]] : $C |
| // CHECK: strong_release %3 : $C |
| // CHECK: destroy_addr %2 : $*T |
| // CHECK: %[[T:.*]] = tuple (%[[T1]] : $C, %[[T2]] : $C) |
| // CHECK: dealloc_stack %[[OUT2]] : $*T |
| // CHECK: dealloc_stack %[[OUT1]] : $*T |
| // CHECK: dealloc_stack %[[LOC0]] : $*T |
| // CHECK: return %[[T]] : $(C, C) |
| // CHECK-LABEL: } // end sil function 'f073_callMixedResult2' |
| sil @f073_callMixedResult2 : $@convention(thin) <T> (@in T, @owned C) -> (@out T, @out T, @owned C, @owned C) { |
| bb0(%0 : $T, %1 : $C): |
| %4 = function_ref @f071_mixedResult2 : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned C) -> (@out τ_0_0, @out τ_0_0, @owned C, @owned C) |
| %5 = copy_value %0 : $T |
| strong_retain %1 : $C |
| %7 = apply %4<T>(%5, %1) : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned C) -> (@out τ_0_0, @out τ_0_0, @owned C, @owned C) |
| %8 = tuple_extract %7 : $(T, T, C, C), 0 |
| %9 = copy_value %8 : $T |
| %10 = tuple_extract %7 : $(T, T, C, C), 1 |
| %11 = copy_value %10 : $T |
| %12 = tuple_extract %7 : $(T, T, C, C), 2 |
| strong_retain %12 : $C |
| %14 = tuple_extract %7 : $(T, T, C, C), 3 |
| strong_retain %14 : $C |
| destroy_value %7 : $(T, T, C, C) |
| strong_release %1 : $C |
| destroy_value %0 : $T |
| %19 = tuple (%9 : $T, %11 : $T, %12 : $C, %14 : $C) |
| return %19 : $(T, T, C, C) |
| } |
| |
| sil_default_witness_table C {} |
| |
| enum Optional<T> { |
| case none |
| case some(T) |
| } |
| |
| // CHECK-LABEL: sil @f080_optional : $@convention(thin) <T> (@in T) -> @out Optional<T> { |
| // CHECK: bb0(%0 : $*Optional<T>, %1 : $*T): |
| // CHECK: %[[DATA:.*]] = init_enum_data_addr %0 : $*Optional<T>, #Optional.some!enumelt.1 |
| // CHECK: copy_addr %1 to [initialization] %[[DATA]] : $*T |
| // CHECK: inject_enum_addr %0 : $*Optional<T>, #Optional.some!enumelt.1 |
| // CHECK: destroy_addr %1 : $*T |
| // CHECK: %[[T:.*]] = tuple () |
| // CHECK: return %[[T]] : $() |
| // CHECK-LABEL: } // end sil function 'f080_optional' |
| sil @f080_optional : $@convention(thin) <T> (@in T) -> @out Optional<T> { |
| bb0(%0 : $T): |
| %cpy = copy_value %0 : $T |
| %opt = enum $Optional<T>, #Optional.some!enumelt.1, %cpy : $T |
| destroy_value %0 : $T |
| return %opt : $Optional<T> |
| } |
| |
| // CHECK-LABEL: sil @f090_tupletuple : $@convention(thin) ((Builtin.Int64, Builtin.Int64), Builtin.Int64) -> (@out (Builtin.Int64, Builtin.Int64), @out (Builtin.Int64, Builtin.Int64), Builtin.Int64, Builtin.Int64) { |
| // CHECK: bb0(%0 : $*(Builtin.Int64, Builtin.Int64), %1 : $*(Builtin.Int64, Builtin.Int64), %2 : $(Builtin.Int64, Builtin.Int64), %3 : $Builtin.Int64): |
| // CHECK: store %2 to %0 : $*(Builtin.Int64, Builtin.Int64) |
| // CHECK: store %2 to %1 : $*(Builtin.Int64, Builtin.Int64) |
| // CHECK: %[[T:.*]] = tuple (%3 : $Builtin.Int64, %3 : $Builtin.Int64) |
| // CHECK: return %[[T]] : $(Builtin.Int64, Builtin.Int64) |
| // CHECK-LABEL: } // end sil function 'f090_tupletuple' |
| sil @f090_tupletuple : $@convention(thin) ((Int, Int), Int) -> (@out (Int, Int), @out (Int, Int), Int, Int) { |
| bb0(%0 : $(Int, Int), %1 : $Int): |
| %2 = tuple (%0 : $(Int, Int), %0 : $(Int, Int), %1 : $Int, %1 : $Int) |
| return %2 : $((Int, Int), (Int, Int), Int, Int) |
| } |
| |
| // CHECK-LABEL: sil @f091_callTuple : $@convention(thin) (Builtin.Int64) -> (Builtin.Int64, Builtin.Int64, Builtin.Int64, Builtin.Int64, Builtin.Int64, Builtin.Int64) { |
| // CHECK: bb0(%0 : $Builtin.Int64): |
| // CHECK: %[[T1:.*]] = tuple (%0 : $Builtin.Int64, %0 : $Builtin.Int64) |
| // CHECK: %[[F:.*]] = function_ref @f090_tupletuple : $@convention(thin) ((Builtin.Int64, Builtin.Int64), Builtin.Int64) -> (@out (Builtin.Int64, Builtin.Int64), @out (Builtin.Int64, Builtin.Int64), Builtin.Int64, Builtin.Int64) |
| // CHECK: %[[O1:.*]] = alloc_stack $(Builtin.Int64, Builtin.Int64) |
| // CHECK: %[[O2:.*]] = alloc_stack $(Builtin.Int64, Builtin.Int64) |
| // CHECK: %[[RT:.*]] = apply %[[F]](%[[O1]], %4, %1, %0) : $@convention(thin) ((Builtin.Int64, Builtin.Int64), Builtin.Int64) -> (@out (Builtin.Int64, Builtin.Int64), @out (Builtin.Int64, Builtin.Int64), Builtin.Int64, Builtin.Int64) |
| // CHECK: %[[R1:.*]] = tuple_extract %[[RT]] : $(Builtin.Int64, Builtin.Int64), 1 |
| // CHECK: %[[R0:.*]] = tuple_extract %[[RT]] : $(Builtin.Int64, Builtin.Int64), 0 |
| // CHECK: %[[L2:.*]] = load %[[O2]] : $*(Builtin.Int64, Builtin.Int64) |
| // CHECK: dealloc_stack %[[O2]] : $*(Builtin.Int64, Builtin.Int64) |
| // CHECK: %[[L1:.*]] = load %[[O1]] : $*(Builtin.Int64, Builtin.Int64) |
| // CHECK: dealloc_stack %[[O1]] : $*(Builtin.Int64, Builtin.Int64) |
| // CHECK: %[[E10:.*]] = tuple_extract %[[L1]] : $(Builtin.Int64, Builtin.Int64), 0 |
| // CHECK: %[[E11:.*]] = tuple_extract %[[L1]] : $(Builtin.Int64, Builtin.Int64), 1 |
| // CHECK: %[[E20:.*]] = tuple_extract %[[L2]] : $(Builtin.Int64, Builtin.Int64), 0 |
| // CHECK: %[[E21:.*]] = tuple_extract %[[L2]] : $(Builtin.Int64, Builtin.Int64), 1 |
| // CHECK: %[[RET:.*]] = tuple (%[[E10]] : $Builtin.Int64, %[[E11]] : $Builtin.Int64, %[[E20]] : $Builtin.Int64, %[[E21]] : $Builtin.Int64, %[[R0]] : $Builtin.Int64, %[[R1]] : $Builtin.Int64) |
| // CHECK: return %[[RET]] : $(Builtin.Int64, Builtin.Int64, Builtin.Int64, Builtin.Int64, Builtin.Int64, Builtin.Int64) |
| // CHECK-LABEL: } // end sil function 'f091_callTuple' |
| sil @f091_callTuple : $@convention(thin) (Int) -> (Int, Int, Int, Int, Int, Int) { |
| bb0(%0: $Int): |
| %1 = tuple (%0 : $Int, %0 : $Int) |
| %2 = function_ref @f090_tupletuple : $@convention(thin) ((Int, Int), Int) -> (@out (Int, Int), @out (Int, Int), Int, Int) |
| %3 = apply %2(%1, %0) : $@convention(thin) ((Int, Int), Int) -> (@out (Int, Int), @out (Int, Int), Int, Int) |
| %9 = tuple_extract %3 : $((Int, Int), (Int, Int), Int, Int), 0 |
| %10 = tuple_extract %3 : $((Int, Int), (Int, Int), Int, Int), 1 |
| %11 = tuple_extract %3 : $((Int, Int), (Int, Int), Int, Int), 2 |
| %12 = tuple_extract %3 : $((Int, Int), (Int, Int), Int, Int), 3 |
| %13 = tuple_extract %9 : $(Int, Int), 0 |
| %14 = tuple_extract %9 : $(Int, Int), 1 |
| %15 = tuple_extract %10 : $(Int, Int), 0 |
| %16 = tuple_extract %10 : $(Int, Int), 1 |
| %17 = tuple (%13 : $Int, %14 : $Int, %15 : $Int, %16 : $Int, %11 : $Int, %12 : $Int) |
| return %17 : $(Int, Int, Int, Int, Int, Int) |
| } |
| |
| // CHECK-LABEL: sil hidden @f100_any : $@convention(thin) (@in Any) -> () { |
| // CHECK: bb0(%0 : $*Any): |
| // CHECK: destroy_addr %0 : $*Any |
| // CHECK: %[[T:.*]] = tuple () |
| // CHECK: return %[[T]] : $() |
| // CHECK-LABEL: } // end sil function 'f100_any' |
| sil hidden @f100_any : $@convention(thin) (@in Any) -> () { |
| bb0(%0 : $Any): |
| debug_value %0 : $Any, let, name "any", argno 1 |
| destroy_value %0 : $Any |
| %3 = tuple () |
| return %3 : $() |
| } |
| |
| // CHECK-LABEL: sil @f101_passAny : $@convention(thin) <T> (@in T) -> () { |
| // CHECK: bb0(%0 : $*T): |
| // CHECK: %[[A:.*]] = alloc_stack $Any |
| // CHECK: %[[F:.*]] = function_ref @f100_any : $@convention(thin) (@in Any) -> () |
| // CHECK: %[[T:.*]] = init_existential_addr %[[A]] : $*Any, $T |
| // CHECK: copy_addr %0 to [initialization] %[[T]] : $*T |
| // CHECK: %{{.*}} = apply %[[F]](%[[A]]) : $@convention(thin) (@in Any) -> () |
| // CHECK: destroy_addr %0 : $*T |
| // CHECK: %[[R:.*]] = tuple () |
| // CHECK: dealloc_stack %[[A]] : $*Any |
| // CHECK: return %[[R]] : $() |
| // CHECK-LABEL: } // end sil function 'f101_passAny' |
| sil @f101_passAny : $@convention(thin) <T> (@in T) -> () { |
| bb0(%0 : $T): |
| %2 = function_ref @f100_any : $@convention(thin) (@in Any) -> () |
| %3 = copy_value %0 : $T |
| %4 = init_existential_value %3 : $T, $T, $Any |
| %5 = apply %2(%4) : $@convention(thin) (@in Any) -> () |
| destroy_value %0 : $T |
| %7 = tuple () |
| return %7 : $() |
| } |