mirror of
https://github.com/apple/swift.git
synced 2026-10-10 13:50:43 +02: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.
358 lines
12 KiB
Plaintext
358 lines
12 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 [ossa] @expand_destroy_addr_trivial
|
|
// CHECK: bb0
|
|
// CHECK: tuple ()
|
|
// CHECK: return
|
|
sil [ossa] @expand_destroy_addr_trivial : $@convention(thin) (@in Builtin.Int64) -> () {
|
|
bb0(%0 : $*Builtin.Int64):
|
|
destroy_addr %0 : $*Builtin.Int64
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @expand_destroy_addr_aggstructnontrivial :
|
|
// CHECK: bb0([[INPTR:%[0-9]+]] : $*S):
|
|
// CHECK: [[IN:%[0-9]+]] = load [take] [[INPTR]] : $*S
|
|
// CHECK: ({{%.*}}, [[cls:%.*]], [[innerstruct:%.*]]) = destructure_struct [[IN]]
|
|
// CHECK: destroy_value [[cls]] : $C3
|
|
// CHECK: ([[innerstruct_cls1:%.*]], [[innerstruct_cls2:%.*]], {{%.*}}) = destructure_struct [[innerstruct]]
|
|
// CHECK: destroy_value [[innerstruct_cls1]] : $C1
|
|
// CHECK: destroy_value [[innerstruct_cls2]] : $C2
|
|
// CHECK: } // end sil function 'expand_destroy_addr_aggstructnontrivial'
|
|
sil [ossa] @expand_destroy_addr_aggstructnontrivial : $@convention(thin) (@in S) -> () {
|
|
bb0(%0 : $*S):
|
|
destroy_addr %0 : $*S
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @expand_destroy_addr_aggtuplenontrivial :
|
|
// CHECK: bb0([[INPTR:%[0-9]+]] : $*(S, S2, C1)):
|
|
// CHECK: [[IN:%[0-9]+]] = load [take] [[INPTR]] : $*(S, S2, C1)
|
|
// CHECK: ([[ELT0:%.*]], [[ELT1:%.*]], [[ELT2:%.*]]) = destructure_tuple [[IN]]
|
|
// CHECK: ({{%[0-9]+}}, [[ELT0cls:%[0-9]+]], [[ELT0innerstruct:%[0-9]+]]) = destructure_struct [[ELT0]]
|
|
// CHECK: destroy_value [[ELT0cls]]
|
|
// CHECK: ([[ELT0innerstructcls1:%[0-9]+]], [[ELT0innerstructcls2:%[0-9]+]], {{%[0-9]+}}) = destructure_struct [[ELT0innerstruct]]
|
|
// CHECK: destroy_value [[ELT0innerstructcls1]]
|
|
// CHECK: destroy_value [[ELT0innerstructcls2]]
|
|
// CHECK: ([[ELT1cls1:%[0-9]+]], [[ELT1cls2:%[0-9]+]], {{%.*}}) = destructure_struct [[ELT1]]
|
|
// CHECK: destroy_value [[ELT1cls1]] : $C1
|
|
// CHECK: destroy_value [[ELT1cls2]] : $C2
|
|
// CHECK: destroy_value [[ELT2]]
|
|
// CHECK: } // end sil function 'expand_destroy_addr_aggtuplenontrivial'
|
|
sil [ossa] @expand_destroy_addr_aggtuplenontrivial : $@convention(thin) (@in (S, S2, C1)) -> () {
|
|
bb0(%0 : $*(S, S2, C1)):
|
|
destroy_addr %0 : $*(S, S2, C1)
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// Do not do anything.
|
|
sil [ossa] @expand_destroy_addr_addressonly : $@convention(thin) <T> (@in T) -> () {
|
|
bb0(%0 : $*T):
|
|
destroy_addr %0 : $*T
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @expand_destroy_addr_reference :
|
|
// CHECK: bb0
|
|
// CHECK: load
|
|
// CHECK: destroy_value
|
|
// CHECK: tuple
|
|
// CHECK: } // end sil function 'expand_destroy_addr_reference'
|
|
sil [ossa] @expand_destroy_addr_reference : $@convention(thin) (@in C1) -> () {
|
|
bb0(%0 : $*C1):
|
|
destroy_addr %0 : $*C1
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @expand_destroy_addr_enum :
|
|
// CHECK: bb0
|
|
// CHECK: load
|
|
// CHECK: destroy_value
|
|
// CHECK: } // end sil function 'expand_destroy_addr_enum'
|
|
sil [ossa] @expand_destroy_addr_enum : $@convention(thin) (@in E) -> () {
|
|
bb0(%0 : $*E):
|
|
destroy_addr %0 : $*E
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
///////////////
|
|
// Copy Addr //
|
|
///////////////
|
|
|
|
// CHECK-LABEL: sil [ossa] @expand_copy_addr_takeinit :
|
|
// CHECK: bb0([[OUT:%[0-9]+]] : $*S, [[IN:%[0-9]+]] : $*S):
|
|
// CHECK: [[LOAD:%[0-9]+]] = load [take] [[IN]]
|
|
// CHECK: store [[LOAD]] to [init] [[OUT]]
|
|
// CHECK: } // end sil function 'expand_copy_addr_takeinit'
|
|
sil [ossa] @expand_copy_addr_takeinit : $@convention(thin) (@in S) -> @out S {
|
|
bb0(%0 : $*S, %1 : $*S):
|
|
copy_addr [take] %1 to [init] %0 : $*S
|
|
%2 = tuple()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @expand_copy_addr_init :
|
|
// CHECK: bb0([[OUT:%[0-9]+]] : $*S, [[IN:%[0-9]+]] : $*S):
|
|
// CHECK: [[LOADED_IN:%[0-9]+]] = load [copy] [[IN]] : $*S
|
|
// CHECK: store [[LOADED_IN]] to [init] [[OUT]]
|
|
// CHECK: } // end sil function 'expand_copy_addr_init'
|
|
sil [ossa] @expand_copy_addr_init : $@convention(thin) (@in_guaranteed S) -> @out S {
|
|
bb0(%0 : $*S, %1 : $*S):
|
|
copy_addr %1 to [init] %0 : $*S
|
|
%2 = tuple()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @expand_copy_addr_take :
|
|
// CHECK: bb0([[IN_ARG:%[0-9]+]] : $*S, [[INOUT_ARG:%[0-9]+]] : $*S):
|
|
// CHECK: [[LOADED_IN_ARG:%[0-9]+]] = load [take] [[IN_ARG]]
|
|
// CHECK: store [[LOADED_IN_ARG]] to [assign] [[INOUT_ARG]]
|
|
// CHECK: } // end sil function 'expand_copy_addr_take'
|
|
sil [ossa] @expand_copy_addr_take : $@convention(thin) (@in 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 [ossa] @expand_copy_addr_trivial :
|
|
// CHECK: bb0
|
|
// CHECK: load [trivial]
|
|
// CHECK: store
|
|
// CHECK: } // end sil function 'expand_copy_addr_trivial'
|
|
sil [ossa] @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 [ossa] @expand_copy_addr_aggstructnontrivial :
|
|
// CHECK: bb0([[INOUT_ARG1:%[0-9]+]] : $*S, [[INOUT_ARG2:%[0-9]+]] : $*S):
|
|
// CHECK: [[INOUT_ARG1_LOADED:%[0-9]+]] = load [copy] [[INOUT_ARG1]]
|
|
// CHECK: store [[INOUT_ARG1_LOADED]] to [assign] [[INOUT_ARG2]]
|
|
// CHECK: } // end sil function 'expand_copy_addr_aggstructnontrivial'
|
|
sil [ossa] @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 [ossa] @expand_copy_addr_aggtuplenontrivial :
|
|
// CHECK: bb0([[INOUT_1:%[0-9]+]] : $*(S, S2, C1, E), [[INOUT_2:%[0-9]+]] : $*(S, S2, C1, E)):
|
|
// CHECK: [[INOUT_1_LOADED:%[0-9]+]] = load [copy] [[INOUT_1]] : $*(S, S2, C1, E)
|
|
// CHECK: store [[INOUT_1_LOADED]] to [assign] [[INOUT_2]] : $*(S, S2, C1, E)
|
|
// CHECK: tuple ()
|
|
// CHECK: return
|
|
|
|
|
|
sil [ossa] @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 [ossa] @expand_copy_addr_addressonly : $@convention(thin) <T> (@in T, @inout T) -> () {
|
|
// CHECK: copy_addr
|
|
// CHECK: } // end sil function 'expand_copy_addr_addressonly'
|
|
sil [ossa] @expand_copy_addr_addressonly : $@convention(thin) <T> (@in T, @inout T) -> () {
|
|
bb0(%0 : $*T, %1 : $*T):
|
|
copy_addr [take] %0 to %1 : $*T
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// Just turn into a load + destroy_value.
|
|
// CHECK-LABEL: sil [ossa] @expand_copy_addr_reference :
|
|
// CHECK: bb0([[INOUT_1:%[0-9]+]] : $*C1, [[INOUT_2:%[0-9]+]] : $*C1):
|
|
// CHECK: [[LOAD1:%[0-9]+]] = load [copy] [[INOUT_1]] : $*C1
|
|
// CHECK: store [[LOAD1]] to [assign] [[INOUT_2]]
|
|
// CHECK: } // end sil function 'expand_copy_addr_reference'
|
|
sil [ossa] @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 [ossa] @expand_copy_addr_enum :
|
|
// CHECK: bb0([[IN1:%[0-9]+]] : $*E, [[IN2:%[0-9]+]] : $*E):
|
|
// CHECK: [[LOAD1:%[0-9]+]] = load [copy] [[IN1]] : $*E
|
|
// CHECK: store [[LOAD1]] to [assign] [[IN2]]
|
|
// CHECK: } // end sil function 'expand_copy_addr_enum'
|
|
sil [ossa] @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 //
|
|
///////////////////
|
|
|
|
// CHECK-LABEL: sil [ossa] @expand_destroy_value_aggstructnontrivial :
|
|
// CHECK: bb0([[IN:%[0-9]+]] : @owned $S):
|
|
// CHECK: destroy_value [[IN]]
|
|
// CHECK: } // end sil function 'expand_destroy_value_aggstructnontrivial'
|
|
sil [ossa] @expand_destroy_value_aggstructnontrivial : $@convention(thin) (@owned S) -> () {
|
|
bb0(%0 : @owned $S):
|
|
destroy_value %0 : $S
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @expand_destroy_value_aggtuplenontrivial :
|
|
// CHECK: bb0([[IN:%[0-9]+]] : @owned $(S, S2, C1, E)):
|
|
// CHECK: destroy_value [[IN]]
|
|
// CHECK: } // end sil function 'expand_destroy_value_aggtuplenontrivial'
|
|
sil [ossa] @expand_destroy_value_aggtuplenontrivial : $@convention(thin) (@owned (S, S2, C1, E)) -> () {
|
|
bb0(%0 : @owned $(S, S2, C1, E)):
|
|
destroy_value %0 : $(S, S2, C1, E)
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @expand_destroy_value_reference :
|
|
// CHECK: bb0([[IN:%[0-9]+]] : @owned $C1):
|
|
// CHECK: destroy_value [[IN]]
|
|
// CHECK: } // end sil function 'expand_destroy_value_reference'
|
|
sil [ossa] @expand_destroy_value_reference : $@convention(thin) (@owned C1) -> () {
|
|
bb0(%0 : @owned $C1):
|
|
destroy_value %0 : $C1
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @expand_destroy_value_enum :
|
|
// CHECK: bb0([[IN1:%[0-9]+]] : @owned $E):
|
|
// CHECK: destroy_value
|
|
// CHECK: } // end sil function 'expand_destroy_value_enum'
|
|
sil [ossa] @expand_destroy_value_enum : $@convention(thin) (@owned E) -> () {
|
|
bb0(%0 : @owned $E):
|
|
destroy_value %0 : $E
|
|
%1 = tuple()
|
|
return %1 : $()
|
|
}
|
|
|
|
|
|
////////////////
|
|
// Copy Value //
|
|
////////////////
|
|
|
|
// CHECK-LABEL: sil [ossa] @expand_copy_value_aggstructnontrivial :
|
|
// CHECK: bb0([[IN:%[0-9]+]] : @guaranteed $S3):
|
|
// CHECK: [[COPY:%.*]] = copy_value [[IN]]
|
|
// CHECK: return [[COPY]] : $S3
|
|
// CHECK: } // end sil function 'expand_copy_value_aggstructnontrivial'
|
|
sil [ossa] @expand_copy_value_aggstructnontrivial : $@convention(thin) (@guaranteed S3) -> @owned S3 {
|
|
bb0(%0 : @guaranteed $S3):
|
|
%1 = copy_value %0 : $S3
|
|
return %1 : $S3
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @expand_copy_value_aggtuplenontrivial :
|
|
// CHECK: bb0([[IN:%[0-9]+]] : @guaranteed $(S, Builtin.Int64, S2, C1, Builtin.Int64, E)):
|
|
// CHECK: [[OUT:%.*]] = copy_value [[IN]]
|
|
// CHECK: return [[OUT]]
|
|
// CHECK: } // end sil function 'expand_copy_value_aggtuplenontrivial'
|
|
|
|
sil [ossa] @expand_copy_value_aggtuplenontrivial : $@convention(thin) (@guaranteed (S, Builtin.Int64, S2, C1, Builtin.Int64, E)) -> @owned (S, Builtin.Int64, S2, C1, Builtin.Int64, E) {
|
|
bb0(%0 : @guaranteed $(S, Builtin.Int64, S2, C1, Builtin.Int64, E)):
|
|
%1 = copy_value %0 : $(S, Builtin.Int64, S2, C1, Builtin.Int64, E)
|
|
return %1 : $(S, Builtin.Int64, S2, C1, Builtin.Int64, E)
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @expand_copy_value_reference :
|
|
// CHECK: bb0([[IN:%[0-9]+]] : @guaranteed $C1):
|
|
// CHECK: [[OUT:%.*]] = copy_value [[IN]]
|
|
// CHECK: return [[OUT]]
|
|
// CHECK: } // end sil function 'expand_copy_value_reference'
|
|
sil [ossa] @expand_copy_value_reference : $@convention(thin) (@guaranteed C1) -> @owned C1 {
|
|
bb0(%0 : @guaranteed $C1):
|
|
%1 = copy_value %0 : $C1
|
|
return %1 : $C1
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @expand_copy_value_enum :
|
|
// CHECK: bb0([[IN:%[0-9]+]] : @guaranteed $E):
|
|
// CHECK: [[OUT:%.*]] = copy_value [[IN]]
|
|
// CHECk: return [[OUT]]
|
|
// CHECK: } // end sil function 'expand_copy_value_enum'
|
|
sil [ossa] @expand_copy_value_enum : $@convention(thin) (@guaranteed E) -> @owned E {
|
|
bb0(%0 : @guaranteed $E):
|
|
%1 = copy_value %0 : $E
|
|
return %1 : $E
|
|
}
|
|
|