mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Type annotations for instruction operands are omitted, e.g. ``` %3 = struct $S(%1, %2) ``` Operand types are redundant anyway and were only used for sanity checking in the SIL parser. But: operand types _are_ printed if the definition of the operand value was not printed yet. This happens: * if the block with the definition appears after the block where the operand's instruction is located * if a block or instruction is printed in isolation, e.g. in a debugger The old behavior can be restored with `-Xllvm -sil-print-types`. This option is added to many existing test files which check for operand types in their check-lines.
550 lines
21 KiB
Plaintext
550 lines
21 KiB
Plaintext
// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all -enable-expand-all -sil-lower-agg-instrs-expand-all -lower-aggregate-instrs %s | %FileCheck %s
|
|
|
|
// This file makes sure that the mechanics of expanding aggregate instructions
|
|
// work. With that in mind, we expand all structs here ignoring code-size
|
|
// trade-offs.
|
|
|
|
sil_stage canonical
|
|
|
|
import Swift
|
|
import Builtin
|
|
|
|
class C1 {
|
|
var data : Builtin.Int64
|
|
init()
|
|
}
|
|
|
|
class C2 {
|
|
var data : Builtin.FPIEEE32
|
|
init()
|
|
}
|
|
|
|
class C3 {
|
|
var data : Builtin.FPIEEE64
|
|
init()
|
|
}
|
|
|
|
struct S2 {
|
|
var cls1 : C1
|
|
var cls2 : C2
|
|
var trivial : Builtin.FPIEEE32
|
|
}
|
|
|
|
struct S {
|
|
var trivial : Builtin.Int64
|
|
var cls : C3
|
|
var inner_struct : S2
|
|
}
|
|
|
|
enum E {
|
|
case NoElement(Void)
|
|
case TrivialElement(Builtin.Int64)
|
|
case ReferenceElement(C1)
|
|
case StructNonTrivialElt(S)
|
|
case TupleNonTrivialElt((Builtin.Int64, S, C3))
|
|
}
|
|
|
|
// A struct for testing that aggregate rebuilding works.
|
|
struct S3 {
|
|
var trivial1 : Builtin.Int64
|
|
var cls : S
|
|
var trivial2 : Builtin.Int64
|
|
var e : E
|
|
var trivial3 : Builtin.Int64
|
|
}
|
|
|
|
//////////////////
|
|
// Destroy Addr //
|
|
//////////////////
|
|
|
|
// CHECK-LABEL: sil @expand_destroy_addr_trivial
|
|
// CHECK: bb0
|
|
// CHECK: tuple ()
|
|
// CHECK: return
|
|
sil @expand_destroy_addr_trivial : $@convention(thin) (@inout Builtin.Int64) -> () {
|
|
bb0(%0 : $*Builtin.Int64):
|
|
destroy_addr %0 : $*Builtin.Int64
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @expand_destroy_addr_aggstructnontrivial
|
|
// CHECK: bb0([[INPTR:%[0-9]+]] : $*S):
|
|
// CHECK: [[IN:%[0-9]+]] = load [[INPTR]] : $*S
|
|
// CHECK: [[cls:%[0-9]+]] = struct_extract [[IN]] : $S, #S.cls
|
|
// CHECK: strong_release [[cls]] : $C3
|
|
// CHECK: [[innerstruct:%[0-9]+]] = struct_extract [[IN]] : $S, #S.inner_struct
|
|
// CHECK: [[innerstruct_cls1:%[0-9]+]] = struct_extract [[innerstruct]] : $S2, #S2.cls1
|
|
// CHECK: strong_release [[innerstruct_cls1]] : $C1
|
|
// CHECK: [[innerstruct_cls2:%[0-9]+]] = struct_extract [[innerstruct]] : $S2, #S2.cls2
|
|
// CHECK: strong_release [[innerstruct_cls2]] : $C2
|
|
// CHECK: tuple
|
|
// CHECK: return
|
|
sil @expand_destroy_addr_aggstructnontrivial : $@convention(thin) (@inout S) -> () {
|
|
bb0(%0 : $*S):
|
|
destroy_addr %0 : $*S
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @expand_destroy_addr_aggtuplenontrivial
|
|
// CHECK: bb0([[INPTR:%[0-9]+]] : $*(S, S2, C1)):
|
|
// CHECK: [[IN:%[0-9]+]] = load [[INPTR]] : $*(S, S2, C1)
|
|
// CHECK: [[ELT0:%[0-9]+]] = tuple_extract [[IN]] : $(S, S2, C1), 0
|
|
// CHECK: [[ELT0cls:%[0-9]+]] = struct_extract [[ELT0]] : $S, #S.cls
|
|
// CHECK: strong_release [[ELT0cls]] : $C3
|
|
// CHECK: [[ELT0innerstruct:%[0-9]+]] = struct_extract [[ELT0]] : $S, #S.inner_struct
|
|
// CHECK: [[ELT0innerstructcls1:%[0-9]+]] = struct_extract [[ELT0innerstruct]] : $S2, #S2.cls1
|
|
// CHECK: strong_release [[ELT0innerstructcls1]] : $C1
|
|
// CHECK: [[ELT0innerstructcls2:%[0-9]+]] = struct_extract [[ELT0innerstruct]] : $S2, #S2.cls2
|
|
// CHECK: strong_release [[ELT0innerstructcls2]]
|
|
// CHECK: [[ELT1:%[0-9]+]] = tuple_extract [[IN]] : $(S, S2, C1), 1
|
|
// CHECK: [[ELT1cls1:%[0-9]+]] = struct_extract [[ELT1]] : $S2, #S2.cls1
|
|
// CHECK: strong_release [[ELT1cls1]] : $C1
|
|
// CHECK: [[ELT1cls2:%[0-9]+]] = struct_extract [[ELT1]] : $S2, #S2.cls2
|
|
// CHECK: strong_release [[ELT1cls2]] : $C2
|
|
// CHECK: [[ELT2:%[0-9]+]] = tuple_extract [[IN]] : $(S, S2, C1), 2
|
|
// CHECK: strong_release [[ELT2]]
|
|
// CHECK: tuple ()
|
|
// CHECK: return
|
|
sil @expand_destroy_addr_aggtuplenontrivial : $@convention(thin) (@inout (S, S2, C1)) -> () {
|
|
bb0(%0 : $*(S, S2, C1)):
|
|
destroy_addr %0 : $*(S, S2, C1)
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// Do not do anything.
|
|
//
|
|
// CHECK-LABEL: sil @expand_destroy_addr_addressonly : $@convention(thin) <T> (@inout T) -> () {
|
|
// CHECK: destroy_addr
|
|
// CHECK: } // end sil function 'expand_destroy_addr_addressonly'
|
|
sil @expand_destroy_addr_addressonly : $@convention(thin) <T> (@inout T) -> () {
|
|
bb0(%0 : $*T):
|
|
destroy_addr %0 : $*T
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @expand_destroy_addr_reference
|
|
// CHECK: bb0
|
|
// CHECK: load
|
|
// CHECK: strong_release
|
|
// CHECK: tuple
|
|
// CHECK: return
|
|
sil @expand_destroy_addr_reference : $@convention(thin) (@inout C1) -> () {
|
|
bb0(%0 : $*C1):
|
|
destroy_addr %0 : $*C1
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @expand_destroy_addr_enum
|
|
// CHECK: bb0
|
|
// CHECK: load
|
|
// CHECK: release_value
|
|
// CHECK: tuple
|
|
// CHECK: return
|
|
sil @expand_destroy_addr_enum : $@convention(thin) (@inout E) -> () {
|
|
bb0(%0 : $*E):
|
|
destroy_addr %0 : $*E
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
///////////////
|
|
// Copy Addr //
|
|
///////////////
|
|
|
|
// CHECK-LABEL: sil @expand_copy_addr_takeinit
|
|
// CHECK: bb0([[IN1:%[0-9]+]] : $*S, [[IN2:%[0-9]+]] : $*S):
|
|
// CHECK: [[LOAD1:%[0-9]+]] = load [[IN1]] : $*S
|
|
// CHECK: store [[LOAD1]] to [[IN2]]
|
|
// CHECK: tuple
|
|
// CHECK: return
|
|
sil @expand_copy_addr_takeinit : $@convention(thin) (@inout S, @inout S) -> () {
|
|
bb0(%0 : $*S, %1 : $*S):
|
|
copy_addr [take] %0 to [init] %1 : $*S
|
|
%2 = tuple()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @expand_copy_addr_init
|
|
// CHECK: bb0([[IN1PTR:%[0-9]+]] : $*S, [[IN2PTR:%[0-9]+]] : $*S):
|
|
// CHECK: [[IN1:%[0-9]+]] = load [[IN1PTR]] : $*S
|
|
// CHECK: [[IN1trivial:%[0-9]+]] = struct_extract [[IN1]] : $S, #S.trivial
|
|
// CHECK: [[IN1cls:%[0-9]+]] = struct_extract [[IN1]] : $S, #S.cls
|
|
// CHECK: strong_retain [[IN1cls]] : $C3
|
|
// CHECK: [[innerstruct:%[0-9]+]] = struct_extract [[IN1]] : $S, #S.inner_struct
|
|
// CHECK: [[innerstructIN11:%[0-9]+]] = struct_extract [[innerstruct]] : $S2, #S2.cls1
|
|
// CHECK: strong_retain [[innerstructIN11]] : $C1
|
|
// CHECK: [[innerstructIN12:%[0-9]+]] = struct_extract [[innerstruct]] : $S2, #S2.cls2
|
|
// CHECK: strong_retain [[innerstructIN12]] : $C2
|
|
// CHECK: [[innerstructtrivial:%[0-9]+]] = struct_extract [[innerstruct]] : $S2, #S2.trivial
|
|
// CHECK: store [[IN1]] to [[IN2PTR]]
|
|
// CHECK: } // end sil function 'expand_copy_addr_init'
|
|
sil @expand_copy_addr_init : $@convention(thin) (@inout S, @inout S) -> () {
|
|
bb0(%0 : $*S, %1 : $*S):
|
|
copy_addr %0 to [init] %1 : $*S
|
|
%2 = tuple()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @expand_copy_addr_take
|
|
// CHECK: bb0([[IN1PTR:%[0-9]+]] : $*S, [[IN2PTR:%[0-9]+]] : $*S):
|
|
// CHECK: [[IN1:%[0-9]+]] = load [[IN1PTR]] : $*S
|
|
// CHECK: [[IN2:%[0-9]+]] = load [[IN2PTR]] : $*S
|
|
// CHECK: [[cls:%[0-9]+]] = struct_extract [[IN2]] : $S, #S.cls
|
|
// CHECK: strong_release [[cls]] : $C3
|
|
// CHECK: [[innerstruct:%[0-9]+]] = struct_extract [[IN2]] : $S, #S.inner_struct
|
|
// CHECK: [[innerstructcls1:%[0-9]+]] = struct_extract [[innerstruct]] : $S2, #S2.cls1
|
|
// CHECK: strong_release [[innerstructcls1]] : $C1
|
|
// CHECK: [[innerstructcls2:%[0-9]+]] = struct_extract [[innerstruct]] : $S2, #S2.cls2
|
|
// CHECK: strong_release [[innerstructcls2]]
|
|
// CHECK: store [[IN1]] to [[IN2PTR]]
|
|
// CHECK: tuple
|
|
// CHECK: return
|
|
sil @expand_copy_addr_take : $@convention(thin) (@inout S, @inout S) -> () {
|
|
bb0(%0 : $*S, %1 : $*S):
|
|
copy_addr [take] %0 to %1 : $*S
|
|
%2 = tuple()
|
|
return %2 : $()
|
|
}
|
|
|
|
// Test expansions for various types (these will become more
|
|
// interesting when I introduce the actual chopping work).
|
|
|
|
// CHECK-LABEL: sil @expand_copy_addr_trivial
|
|
// CHECK: bb0
|
|
// CHECK: load
|
|
// CHECK: store
|
|
// CHECK: tuple
|
|
// CHECK: return
|
|
sil @expand_copy_addr_trivial : $@convention(thin) (@inout Builtin.Int64, @inout Builtin.Int64) -> () {
|
|
bb0(%0 : $*Builtin.Int64, %1 : $*Builtin.Int64):
|
|
copy_addr %0 to %1 : $*Builtin.Int64
|
|
%2 = tuple()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @expand_copy_addr_aggstructnontrivial :
|
|
// CHECK: bb0([[IN1PTR:%[0-9]+]] : $*S, [[IN2PTR:%[0-9]+]] : $*S):
|
|
// CHECK: [[IN1:%[0-9]+]] = load [[IN1PTR]] : $*S
|
|
// CHECK: [[IN1trivial:%[0-9]+]] = struct_extract [[IN1]] : $S, #S.trivial
|
|
// CHECK: [[IN1cls:%[0-9]+]] = struct_extract [[IN1]] : $S, #S.cls
|
|
// CHECK: strong_retain [[IN1cls]] : $C3
|
|
//
|
|
// CHECK: [[IN1innerstruct:%[0-9]+]] = struct_extract [[IN1]] : $S, #S.inner_struct
|
|
// CHECK: [[IN1innerstructcls1:%[0-9]+]] = struct_extract [[IN1innerstruct]] : $S2, #S2.cls1
|
|
// CHECK: strong_retain [[IN1innerstructcls1]] : $C1
|
|
// CHECK: [[IN1innerstructcls2:%[0-9]+]] = struct_extract [[IN1innerstruct]] : $S2, #S2.cls2
|
|
// CHECK: strong_retain [[IN1innerstructcls2]] : $C2
|
|
//
|
|
// CHECK: [[IN1innerstructtrivial:%[0-9]+]] = struct_extract [[IN1innerstruct]] : $S2, #S2.trivial
|
|
// CHECK: [[IN2:%[0-9]+]] = load [[IN2PTR]] : $*S
|
|
// CHECK: [[IN2cls:%[0-9]+]] = struct_extract [[IN2]] : $S, #S.cls
|
|
// CHECK: strong_release [[IN2cls]] : $C3
|
|
// CHECK: [[IN2innerstruct:%[0-9]+]] = struct_extract [[IN2]] : $S, #S.inner_struct
|
|
// CHECK: [[IN2innerstructcls1:%[0-9]+]] = struct_extract [[IN2innerstruct]] : $S2, #S2.cls1
|
|
// CHECK: strong_release [[IN2innerstructcls1]] : $C1
|
|
// CHECK: [[IN2innerstructcls2:%[0-9]+]] = struct_extract [[IN2innerstruct]] : $S2, #S2.cls2
|
|
// CHECK: strong_release [[IN2innerstructcls2]]
|
|
// CHECK: store [[IN1]] to [[IN2PTR]]
|
|
// CHECK: } // end sil function 'expand_copy_addr_aggstructnontrivial'
|
|
sil @expand_copy_addr_aggstructnontrivial : $@convention(thin) (@inout S, @inout S) -> () {
|
|
bb0(%0 : $*S, %1 : $*S):
|
|
copy_addr %0 to %1 : $*S
|
|
%2 = tuple()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @expand_copy_addr_aggtuplenontrivial :
|
|
// CHECK: bb0([[IN1PTR:%[0-9]+]] : $*(S, S2, C1, E), [[IN2PTR:%[0-9]+]] : $*(S, S2, C1, E)):
|
|
//
|
|
// -- Begin IN1ELT
|
|
// CHECK: [[IN1:%[0-9]+]] = load [[IN1PTR]] : $*(S, S2, C1, E)
|
|
//
|
|
// -- IN1ELT0
|
|
// CHECK: [[IN1ELT0:%[0-9]+]] = tuple_extract [[IN1]] : $(S, S2, C1, E), 0
|
|
// CHECK: [[IN1ELT0trivial:%[0-9]+]] = struct_extract [[IN1ELT0]] : $S, #S.trivial
|
|
// CHECK: [[IN1ELT0cls:%[0-9]+]] = struct_extract [[IN1ELT0]] : $S, #S.cls
|
|
// CHECK: strong_retain [[IN1ELT0cls]] : $C3
|
|
// CHECK: [[IN1ELT0innerstruct:%[0-9]+]] = struct_extract [[IN1ELT0]] : $S, #S.inner_struct
|
|
// CHECK: [[IN1ELT0innerstructcls1:%[0-9]+]] = struct_extract [[IN1ELT0innerstruct]] : $S2, #S2.cls1
|
|
// CHECK: strong_retain [[IN1ELT0innerstructcls1]] : $C1
|
|
// CHECK: [[IN1ELT0innerstructcls2:%[0-9]+]] = struct_extract [[IN1ELT0innerstruct]] : $S2, #S2.cls2
|
|
// CHECK: strong_retain [[IN1ELT0innerstructcls2]]
|
|
// CHECK: [[IN1ELT0innerstructtrivial:%[0-9]+]] = struct_extract [[IN1ELT0innerstruct]] : $S2, #S2.trivial
|
|
//
|
|
// -- IN1ELT1
|
|
// CHECK: [[IN1ELT1:%[0-9]+]] = tuple_extract [[IN1]] : $(S, S2, C1, E), 1
|
|
// CHECK: [[IN1ELT1cls1:%[0-9]+]] = struct_extract [[IN1ELT1]] : $S2, #S2.cls1
|
|
// CHECK: strong_retain [[IN1ELT1cls1]] : $C1
|
|
// CHECK: [[IN1ELT1cls2:%[0-9]+]] = struct_extract [[IN1ELT1]] : $S2, #S2.cls2
|
|
// CHECK: strong_retain [[IN1ELT1cls2]] : $C2
|
|
// CHECK: [[IN1ELT1trivial:%[0-9]+]] = struct_extract [[IN1ELT1]] : $S2, #S2.trivial
|
|
//
|
|
// -- IN1ELT2
|
|
// CHECK: [[IN1ELT2:%[0-9]+]] = tuple_extract [[IN1]] : $(S, S2, C1, E), 2
|
|
// CHECK: strong_retain [[IN1ELT2]]
|
|
//
|
|
// -- IN1ELT3
|
|
// CHECK: [[IN1ELT3:%[0-9]+]] = tuple_extract [[IN1]] : $(S, S2, C1, E), 3
|
|
// CHECK: retain_value [[IN1ELT3]] : $E
|
|
//
|
|
// -- Finish IN1ELT
|
|
//
|
|
// -- IN2
|
|
// CHECK: [[IN2:%[0-9]+]] = load [[IN2PTR]] : $*(S, S2, C1, E)
|
|
// CHECK: [[IN2ELT0:%[0-9]+]] = tuple_extract [[IN2]] : $(S, S2, C1, E), 0
|
|
// CHECK: [[IN2ELT0cls:%[0-9]+]] = struct_extract [[IN2ELT0]] : $S, #S.cls
|
|
// CHECK: strong_release [[IN2ELT0cls]] : $C3
|
|
// CHECK: [[IN2ELT0innerstruct:%[0-9]+]] = struct_extract [[IN2ELT0]] : $S, #S.inner_struct
|
|
// CHECK: [[IN2ELT0innerstructcls1:%[0-9]+]] = struct_extract [[IN2ELT0innerstruct]] : $S2, #S2.cls1
|
|
// CHECK: strong_release [[IN2ELT0innerstructcls1]] : $C1
|
|
// CHECK: [[IN2ELT0innerstructcls2:%[0-9]+]] = struct_extract [[IN2ELT0innerstruct]] : $S2, #S2.cls2
|
|
// CHECK: strong_release [[IN2ELT0innerstructcls2]]
|
|
// CHECK: [[IN2ELT1:%[0-9]+]] = tuple_extract [[IN2]] : $(S, S2, C1, E), 1
|
|
// CHECK: [[IN2ELT1cls1:%[0-9]+]] = struct_extract [[IN2ELT1]] : $S2, #S2.cls1
|
|
// CHECK: strong_release [[IN2ELT1cls1]] : $C1
|
|
// CHECK: [[IN2ELT1cls2:%[0-9]+]] = struct_extract [[IN2ELT1]] : $S2, #S2.cls2
|
|
// CHECK: strong_release [[IN2ELT1cls2]] : $C2
|
|
// CHECK: [[IN2ELT2:%[0-9]+]] = tuple_extract [[IN2]] : $(S, S2, C1, E), 2
|
|
// CHECK: strong_release [[IN2ELT2]]
|
|
// CHECK: [[IN2ELT3:%[0-9]+]] = tuple_extract [[IN2]] : $(S, S2, C1, E), 3
|
|
// CHECK: release_value [[IN2ELT3]] : $E
|
|
//
|
|
// CHECK: store [[IN1]] to [[IN2PTR]] : $*(S, S2, C1, E)
|
|
// CHECK: } // end sil function 'expand_copy_addr_aggtuplenontrivial'
|
|
sil @expand_copy_addr_aggtuplenontrivial : $@convention(thin) (@inout (S, S2, C1, E), @inout (S, S2, C1, E)) -> () {
|
|
bb0(%0 : $*(S, S2, C1, E), %1 : $*(S, S2, C1, E)):
|
|
copy_addr %0 to %1 : $*(S, S2, C1, E)
|
|
%2 = tuple()
|
|
return %2 : $()
|
|
}
|
|
|
|
// Do not do anything.
|
|
//
|
|
// CHECK-LABEL: sil @expand_copy_addr_addressonly : $@convention(thin) <T> (@inout T) -> () {
|
|
// CHECK: copy_addr
|
|
// CHECK: } // end sil function 'expand_copy_addr_addressonly'
|
|
sil @expand_copy_addr_addressonly : $@convention(thin) <T> (@inout T) -> () {
|
|
bb0(%0 : $*T):
|
|
copy_addr [take] %0 to [init] %0 : $*T
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// Just turn into a load + strong_release.
|
|
//
|
|
// CHECK-LABEL: sil @expand_copy_addr_reference :
|
|
// CHECK: bb0([[IN1:%[0-9]+]] : $*C1, [[IN2:%[0-9]+]] : $*C1):
|
|
// CHECK: [[LOAD1:%[0-9]+]] = load [[IN1]] : $*C1
|
|
// CHECK: strong_retain [[LOAD1]]
|
|
// CHECK: [[LOAD2:%[0-9]+]] = load [[IN2]] : $*C1
|
|
// CHECK: strong_release [[LOAD2]]
|
|
// CHECK: store [[LOAD1]] to [[IN2]]
|
|
// CHECK: } // end sil function 'expand_copy_addr_reference'
|
|
sil @expand_copy_addr_reference : $@convention(thin) (@inout C1, @inout C1) -> () {
|
|
bb0(%0 : $*C1, %1 : $*C1):
|
|
copy_addr %0 to %1 : $*C1
|
|
%2 = tuple()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @expand_copy_addr_enum :
|
|
// CHECK: bb0([[IN1:%[0-9]+]] : $*E, [[IN2:%[0-9]+]] : $*E):
|
|
// CHECK: [[LOAD1:%[0-9]+]] = load [[IN1]] : $*E
|
|
// CHECK: retain_value [[LOAD1]]
|
|
// CHECK: [[LOAD2:%[0-9]+]] = load [[IN2]] : $*E
|
|
// CHECK: release_value [[LOAD2]]
|
|
// CHECK: store [[LOAD1]] to [[IN2]]
|
|
// CHECK: } // end sil function 'expand_copy_addr_enum'
|
|
sil @expand_copy_addr_enum : $@convention(thin) (@inout E, @inout E) -> () {
|
|
bb0(%0 : $*E, %1 : $*E):
|
|
copy_addr %0 to %1 : $*E
|
|
%2 = tuple()
|
|
return %2 : $()
|
|
}
|
|
|
|
///////////////////
|
|
// Destroy Value //
|
|
///////////////////
|
|
|
|
// Test expansions for various types (these will become more
|
|
// interesting when I introduce the actual chopping work).
|
|
|
|
// CHECK-LABEL: sil @expand_release_value_trivial
|
|
// CHECK: bb0
|
|
// CHECK: tuple
|
|
// CHECK: return
|
|
sil @expand_release_value_trivial : $@convention(thin) (Builtin.Int64) -> () {
|
|
bb0(%0 : $Builtin.Int64):
|
|
release_value %0 : $Builtin.Int64
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @expand_release_value_aggstructnontrivial
|
|
// CHECK: bb0([[IN:%[0-9]+]] : $S):
|
|
// CHECK: [[cls:%[0-9]+]] = struct_extract [[IN]] : $S, #S.cls
|
|
// CHECK: strong_release [[cls]] : $C3
|
|
// CHECK: [[innerstruct:%[0-9]+]] = struct_extract [[IN]] : $S, #S.inner_struct
|
|
// CHECK: [[innerstructcls1:%[0-9]+]] = struct_extract [[innerstruct]] : $S2, #S2.cls1
|
|
// CHECK: strong_release [[innerstructcls1]] : $C1
|
|
// CHECK: [[innerstructcls2:%[0-9]+]] = struct_extract [[innerstruct]] : $S2, #S2.cls2
|
|
// CHECK: strong_release [[innerstructcls2]]
|
|
sil @expand_release_value_aggstructnontrivial : $@convention(thin) (S) -> () {
|
|
bb0(%0 : $S):
|
|
release_value %0 : $S
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @expand_release_value_aggtuplenontrivial
|
|
// CHECK: bb0([[IN:%[0-9]+]] : $(S, S2, C1, E)):
|
|
// CHECK: [[ELT0:%[0-9]+]] = tuple_extract [[IN]] : $(S, S2, C1, E), 0
|
|
// CHECK: [[ELT0cls:%[0-9]+]] = struct_extract [[ELT0]] : $S, #S.cls
|
|
// CHECK: strong_release [[ELT0cls]] : $C3
|
|
// CHECK: [[ELT0innerstruct:%[0-9]+]] = struct_extract [[ELT0]] : $S, #S.inner_struct
|
|
// CHECK: [[ELT0innerstructcls1:%[0-9]+]] = struct_extract [[ELT0innerstruct]] : $S2, #S2.cls1
|
|
// CHECK: strong_release [[ELT0innerstructcls1]] : $C1
|
|
// CHECK: [[ELT0innerstructcls2:%[0-9]+]] = struct_extract [[ELT0innerstruct]] : $S2, #S2.cls2
|
|
// CHECK: strong_release [[ELT0innerstructcls2]]
|
|
// CHECK: [[ELT1:%[0-9]+]] = tuple_extract [[IN]] : $(S, S2, C1, E), 1
|
|
// CHECK: [[ELT1cls1:%[0-9]+]] = struct_extract [[ELT1]] : $S2, #S2.cls1
|
|
// CHECK: strong_release [[ELT1cls1]] : $C1
|
|
// CHECK: [[ELT1cls2:%[0-9]+]] = struct_extract [[ELT1]] : $S2, #S2.cls2
|
|
// CHECK: strong_release [[ELT1cls2]] : $C2
|
|
// CHECK: [[ELT2:%[0-9]+]] = tuple_extract [[IN]] : $(S, S2, C1, E), 2
|
|
// CHECK: strong_release [[ELT2]]
|
|
// CHECK: [[ELT3:%[0-9]+]] = tuple_extract [[IN]] : $(S, S2, C1, E), 3
|
|
// CHECK: release_value [[ELT3]] : $E
|
|
// CHECK: tuple ()
|
|
// CHECK: return
|
|
sil @expand_release_value_aggtuplenontrivial : $@convention(thin) ((S, S2, C1, E)) -> () {
|
|
bb0(%0 : $(S, S2, C1, E)):
|
|
release_value %0 : $(S, S2, C1, E)
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// Just turn into a load + strong_release.
|
|
// CHECK-LABEL: sil @expand_release_value_reference
|
|
// CHECK: bb0([[IN:%[0-9]+]] : $C1):
|
|
// CHECK: strong_release [[IN]]
|
|
// CHECK: tuple
|
|
// CHECK: return
|
|
sil @expand_release_value_reference : $@convention(thin) (C1) -> () {
|
|
bb0(%0 : $C1):
|
|
release_value %0 : $C1
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @expand_release_value_enum
|
|
// CHECK: bb0([[IN1:%[0-9]+]] : $E):
|
|
// CHECK: release_value
|
|
// CHECK: tuple ()
|
|
// CHECK: return
|
|
sil @expand_release_value_enum : $@convention(thin) (E) -> () {
|
|
bb0(%0 : $E):
|
|
release_value %0 : $E
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
|
|
////////////////
|
|
// Copy Value //
|
|
////////////////
|
|
|
|
// Test expansions for various types (these will become more
|
|
// interesting when I introduce the actual chopping work).
|
|
|
|
// CHECK-LABEL: sil @expand_retain_value_trivial
|
|
// CHECK: bb0
|
|
// CHECK: return
|
|
sil @expand_retain_value_trivial : $@convention(thin) (Builtin.Int64) -> (Builtin.Int64) {
|
|
bb0(%0 : $Builtin.Int64):
|
|
retain_value %0 : $Builtin.Int64
|
|
return %0 : $Builtin.Int64
|
|
}
|
|
|
|
// CHECK-LABEL: sil @expand_retain_value_aggstructnontrivial
|
|
// CHECK: bb0([[IN:%[0-9]+]] : $S3):
|
|
// CHECK: [[trivial:%[0-9]+]] = struct_extract [[IN]] : $S3, #S3.trivial1
|
|
// CHECK: [[cls:%[0-9]+]] = struct_extract [[IN]] : $S3, #S3.cls
|
|
// CHECK: [[clstrivial:%[0-9]+]] = struct_extract [[cls]] : $S, #S.trivial
|
|
// CHECK: [[clscls:%[0-9]+]] = struct_extract [[cls]] : $S, #S.cls
|
|
// CHECK: strong_retain [[clscls]] : $C3
|
|
// CHECK: [[innerstruct:%[0-9]+]] = struct_extract [[cls]] : $S, #S.inner_struct
|
|
// CHECK: [[innerstructcls1:%[0-9]+]] = struct_extract [[innerstruct]] : $S2, #S2.cls1
|
|
// CHECK: strong_retain [[innerstructcls1]] : $C1
|
|
// CHECK: [[innerstructcls2:%[0-9]+]] = struct_extract [[innerstruct]] : $S2, #S2.cls2
|
|
// CHECK: strong_retain [[innerstructcls2]] : $C2
|
|
// CHECK: [[innerstructtrivial:%[0-9]+]] = struct_extract [[innerstruct]] : $S2, #S2.trivial
|
|
// CHECK: [[trivial2:%[0-9]+]] = struct_extract [[IN]] : $S3, #S3.trivial2
|
|
// CHECK: [[enum:%[0-9]+]] = struct_extract [[IN]] : $S3, #S3.e
|
|
// CHECK: retain_value [[enum]] : $E
|
|
// CHECK: [[trivial3:%[0-9]+]] = struct_extract [[IN]] : $S3, #S3.trivial3
|
|
// CHECK: return [[IN]] : $S3
|
|
sil @expand_retain_value_aggstructnontrivial : $@convention(thin) (S3) -> (S3) {
|
|
bb0(%0 : $S3):
|
|
retain_value %0 : $S3
|
|
return %0 : $S3
|
|
}
|
|
|
|
// CHECK-LABEL: sil @expand_retain_value_aggtuplenontrivial
|
|
// CHECK: bb0([[IN:%[0-9]+]] : $(S, Builtin.Int64, S2, C1, Builtin.Int64, E)):
|
|
// CHECK: [[ELT0:%[0-9]+]] = tuple_extract [[IN]] : $(S, Builtin.Int64, S2, C1, Builtin.Int64, E), 0
|
|
// CHECK: [[ELT0trivial:%[0-9]+]] = struct_extract [[ELT0]] : $S, #S.trivial
|
|
// CHECK: [[ELT0cls:%[0-9]+]] = struct_extract [[ELT0]] : $S, #S.cls
|
|
// CHECK: strong_retain [[ELT0cls]] : $C3
|
|
// CHECK: [[ELT0innerstruct:%[0-9]+]] = struct_extract [[ELT0]] : $S, #S.inner_struct
|
|
// CHECK: [[ELT0innerstructcls1:%[0-9]+]] = struct_extract [[ELT0innerstruct]] : $S2, #S2.cls1
|
|
// CHECK: strong_retain [[ELT0innerstructcls1]] : $C1
|
|
// CHECK: [[ELT0innerstructcls2:%[0-9]+]] = struct_extract [[ELT0innerstruct]] : $S2, #S2.cls2
|
|
// CHECK: strong_retain [[ELT0innerstructcls2]]
|
|
// CHECK: [[ELT0innerstructtrivial:%[0-9]+]] = struct_extract [[ELT0innerstruct]] : $S2, #S2.trivial
|
|
// CHECK: [[ELT1:%[0-9]+]] = tuple_extract [[IN]] : $(S, Builtin.Int64, S2, C1, Builtin.Int64, E), 1
|
|
// CHECK: [[ELT2:%[0-9]+]] = tuple_extract [[IN]] : $(S, Builtin.Int64, S2, C1, Builtin.Int64, E), 2
|
|
// CHECK: [[ELT2cls1:%[0-9]+]] = struct_extract [[ELT2]] : $S2, #S2.cls1
|
|
// CHECK: strong_retain [[ELT2cls1]] : $C1
|
|
// CHECK: [[ELT2cls2:%[0-9]+]] = struct_extract [[ELT2]] : $S2, #S2.cls2
|
|
// CHECK: strong_retain [[ELT2cls2]] : $C2
|
|
// CHECK: [[ELT2trivial:%[0-9]+]] = struct_extract [[ELT2]] : $S2, #S2.trivial
|
|
// CHECK: [[ELT3:%[0-9]+]] = tuple_extract [[IN]] : $(S, Builtin.Int64, S2, C1, Builtin.Int64, E), 3
|
|
// CHECK: strong_retain [[ELT3]]
|
|
// CHECK: [[ELT4:%[0-9]+]] = tuple_extract [[IN]] : $(S, Builtin.Int64, S2, C1, Builtin.Int64, E), 4
|
|
// CHECK: [[ELT5:%[0-9]+]] = tuple_extract [[IN]] : $(S, Builtin.Int64, S2, C1, Builtin.Int64, E), 5
|
|
// CHECK: retain_value [[ELT5]] : $E
|
|
// CHECK: return [[IN]]
|
|
|
|
sil @expand_retain_value_aggtuplenontrivial : $@convention(thin) ((S, Builtin.Int64, S2, C1, Builtin.Int64, E)) -> ((S, Builtin.Int64, S2, C1, Builtin.Int64, E)) {
|
|
bb0(%0 : $(S, Builtin.Int64, S2, C1, Builtin.Int64, E)):
|
|
retain_value %0 : $(S, Builtin.Int64, S2, C1, Builtin.Int64, E)
|
|
return %0 : $(S, Builtin.Int64, S2, C1, Builtin.Int64, E)
|
|
}
|
|
|
|
// CHECK-LABEL: sil @expand_retain_value_reference
|
|
// CHECK: bb0([[IN:%[0-9]+]] : $C1):
|
|
// CHECK: strong_retain [[IN]]
|
|
// CHECK: return
|
|
sil @expand_retain_value_reference : $@convention(thin) (C1) -> (C1) {
|
|
bb0(%0 : $C1):
|
|
retain_value %0 : $C1
|
|
return %0 : $C1
|
|
}
|
|
|
|
// CHECK-LABEL: sil @expand_retain_value_enum
|
|
// CHECK: bb0([[IN1:%[0-9]+]] : $E):
|
|
// CHECK: retain_value
|
|
// CHECK: return
|
|
sil @expand_retain_value_enum : $@convention(thin) (E) -> (E) {
|
|
bb0(%0 : $E):
|
|
retain_value %0 : $E
|
|
return %0 : $E
|
|
}
|
|
|