blob: 50ed3424a8b6375bfd20fd444ce7ba834e8d202e [file] [log] [blame]
// RUN: %target-swift-frontend %s -gnone -emit-ir -I %S/Inputs | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize -DINT=i%target-ptrsize
import Builtin
sil_stage canonical
enum Either<T, U> {
case Left(T)
case Right(U)
}
enum EitherOr<T, U> {
case Left(T)
case Middle
case Center
case Right(U)
}
class C {}
sil_vtable C {}
// -- The runtime doesn't track spare bits, so fixed instances of the dynamic
// type can't use them.
// CHECK-64-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { i64, i8 } @fixed_instances_dont_use_spare_bits(i64, i8)
// CHECK-32-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { i32, i8 } @fixed_instances_dont_use_spare_bits(i32, i8)
sil @fixed_instances_dont_use_spare_bits : $@convention(thin) (@owned Either<C, C>) -> @owned Either<C, C> {
entry(%e : $Either<C, C>):
return %e : $Either<C, C>
}
// -- Handle case where all of the payloads become empty.
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @empty_instance(i8) {{.*}} {
sil @empty_instance : $@convention(thin) (Either<(), ()>) -> () {
// CHECK-NEXT: entry:
entry(%e : $Either<(), ()>):
retain_value %e : $Either<(), ()>
release_value %e : $Either<(), ()>
fix_lifetime %e : $Either<(), ()>
// CHECK-NEXT: alloca
// CHECK-NEXT: trunc i8 {{.*}} to i1
// CHECK-NEXT: bitcast
// CHECK-NEXT: llvm.lifetime.start
%s = alloc_stack $Either<(), ()>
%l = enum $Either<(), ()>, #Either.Left!enumelt.1, undef : $()
// CHECK-NEXT: bitcast {{.*}} to i1*
// CHECK-NEXT: store i1 false
store %l to %s : $*Either<(), ()>
%r = enum $Either<(), ()>, #Either.Right!enumelt.1, undef : $()
// CHECK-NEXT: bitcast {{.*}} to i1*
// CHECK-NEXT: store i1 true
store %r to %s : $*Either<(), ()>
%a = unchecked_enum_data %l : $Either<(), ()>, #Either.Left!enumelt.1
%b = unchecked_enum_data %r : $Either<(), ()>, #Either.Right!enumelt.1
// CHECK-NEXT: br i1 {{%.*}}, label %7, label %6
// CHECK: <label>:6
// CHECK: br label %8
// CHECK: <label>:7
// CHECK: br label %9
switch_enum %e : $Either<(), ()>,
case #Either.Left!enumelt.1: left,
case #Either.Right!enumelt.1: right
left(%x : $()):
%0 = integer_literal $Builtin.Int8, 0
br next(%0 : $Builtin.Int8)
right(%y : $()):
%1 = integer_literal $Builtin.Int8, 1
br next(%1 : $Builtin.Int8)
// CHECK: phi i8 [ 1, %9 ], [ 0, %8 ]
next(%z : $Builtin.Int8):
dealloc_stack %s : $*Either<(), ()>
return undef : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @empty_instance2(i8) {{.*}} {
sil @empty_instance2 : $@convention(thin) (EitherOr<(), ()>) -> () {
// CHECK-NEXT: entry:
entry(%e : $EitherOr<(), ()>):
retain_value %e : $EitherOr<(), ()>
release_value %e : $EitherOr<(), ()>
fix_lifetime %e : $EitherOr<(), ()>
// CHECK-NEXT: alloca
// CHECK-NEXT: bitcast
// CHECK-NEXT: llvm.lifetime.start
%s = alloc_stack $EitherOr<(), ()>
// CHECK-NEXT: bitcast {{.*}} to i8*
// CHECK-NEXT: store i8 0
%l = enum $EitherOr<(), ()>, #EitherOr.Left!enumelt.1, undef : $()
store %l to %s : $*EitherOr<(), ()>
// CHECK-NEXT: bitcast {{.*}} to i8*
// CHECK-NEXT: store i8 1
%r = enum $EitherOr<(), ()>, #EitherOr.Right!enumelt.1, undef : $()
store %r to %s : $*EitherOr<(), ()>
// CHECK-NEXT: bitcast {{.*}} to i8*
// CHECK-NEXT: store i8 2
%m = enum $EitherOr<(), ()>, #EitherOr.Middle!enumelt
store %m to %s : $*EitherOr<(), ()>
// CHECK-NEXT: bitcast {{.*}} to i8*
// CHECK-NEXT: store i8 3
%k = enum $EitherOr<(), ()>, #EitherOr.Center!enumelt
store %k to %s : $*EitherOr<(), ()>
%a = unchecked_enum_data %l : $EitherOr<(), ()>, #EitherOr.Left!enumelt.1
%b = unchecked_enum_data %r : $EitherOr<(), ()>, #EitherOr.Right!enumelt.1
// CHECK-NEXT: switch
// CHECK-NEXT: i8 0, label %[[LEFT_PRE:[0-9]+]]
// CHECK-NEXT: i8 1, label %[[RIGHT_PRE:[0-9]+]]
// CHECK-NEXT: i8 2, label [[MIDDLE:%[0-9]+]]
// CHECK-NEXT: i8 3, label [[CENTER:%[0-9]+]]
switch_enum %e : $EitherOr<(), ()>,
case #EitherOr.Left!enumelt.1: left,
case #EitherOr.Middle!enumelt: middle,
case #EitherOr.Center!enumelt: center,
case #EitherOr.Right!enumelt.1: right
// CHECK: <label>:[[LEFT_PRE]]
// CHECK: br label [[LEFT:%[0-9]+]]
// CHECK: <label>:[[RIGHT_PRE]]
// CHECK: br label [[RIGHT:%[0-9]+]]
left(%x : $()):
%0 = integer_literal $Builtin.Int8, 0
br next(%0 : $Builtin.Int8)
middle:
%1 = integer_literal $Builtin.Int8, 1
br next(%1 : $Builtin.Int8)
center:
%2 = integer_literal $Builtin.Int8, 2
br next(%2 : $Builtin.Int8)
right(%y : $()):
%3 = integer_literal $Builtin.Int8, 3
br next(%3 : $Builtin.Int8)
next(%z : $Builtin.Int8):
// CHECK: phi i8 [ 3, [[RIGHT]] ], [ 2, [[CENTER]] ], [ 1, [[MIDDLE]] ], [ 0, [[LEFT]] ]
dealloc_stack %s : $*EitherOr<(), ()>
return undef : $()
}
sil hidden_external @consume_case_test_result : $@convention(thin) (Builtin.Int1, Builtin.Int1, Builtin.Int1, Builtin.Int1) -> ()
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @static_multi_payload_case_test
// CHECK: call swiftcc void @consume_case_test_result(i1 true, i1 true, i1 true, i1 true)
sil @static_multi_payload_case_test : $@convention(thin) () -> () {
entry:
%0 = integer_literal $Builtin.Int64, 0
%t = integer_literal $Builtin.Int1, 1
%f = integer_literal $Builtin.Int1, 0
%a = enum $EitherOr<Builtin.Int64, Builtin.Int64>,
#EitherOr.Left!enumelt.1, %0 : $Builtin.Int64
%x = select_enum %a : $EitherOr<Builtin.Int64, Builtin.Int64>,
case #EitherOr.Left!enumelt.1: %t,
default %f : $Builtin.Int1
%b = enum $EitherOr<Builtin.Int64, Builtin.Int64>,
#EitherOr.Right!enumelt.1, %0 : $Builtin.Int64
%y = select_enum %b : $EitherOr<Builtin.Int64, Builtin.Int64>,
case #EitherOr.Right!enumelt.1: %t,
default %f : $Builtin.Int1
%c = enum $EitherOr<Builtin.Int64, Builtin.Int64>,
#EitherOr.Middle!enumelt
%z = select_enum %c : $EitherOr<Builtin.Int64, Builtin.Int64>,
case #EitherOr.Middle!enumelt: %t,
default %f : $Builtin.Int1
%d = enum $EitherOr<Builtin.Int64, Builtin.Int64>,
#EitherOr.Center!enumelt
%w = select_enum %d : $EitherOr<Builtin.Int64, Builtin.Int64>,
case #EitherOr.Center!enumelt: %t,
default %f : $Builtin.Int1
%g = function_ref @consume_case_test_result : $@convention(thin) (Builtin.Int1, Builtin.Int1, Builtin.Int1, Builtin.Int1) -> ()
%r = apply %g(%x, %y, %z, %w) : $@convention(thin) (Builtin.Int1, Builtin.Int1, Builtin.Int1, Builtin.Int1) -> ()
return %r : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @static_multi_payload_case_test_empty
// CHECK: call swiftcc void @consume_case_test_result(i1 true, i1 true, i1 true, i1 true)
sil @static_multi_payload_case_test_empty : $@convention(thin) () -> () {
entry:
%t = integer_literal $Builtin.Int1, 1
%f = integer_literal $Builtin.Int1, 0
%a = enum $EitherOr<(), ()>,
#EitherOr.Left!enumelt.1, undef : $()
%x = select_enum %a : $EitherOr<(), ()>,
case #EitherOr.Left!enumelt.1: %t,
default %f : $Builtin.Int1
%b = enum $EitherOr<(), ()>,
#EitherOr.Right!enumelt.1, undef : $()
%y = select_enum %b : $EitherOr<(), ()>,
case #EitherOr.Right!enumelt.1: %t,
default %f : $Builtin.Int1
%c = enum $EitherOr<(), ()>,
#EitherOr.Middle!enumelt
%z = select_enum %c : $EitherOr<(), ()>,
case #EitherOr.Middle!enumelt: %t,
default %f : $Builtin.Int1
%d = enum $EitherOr<(), ()>,
#EitherOr.Center!enumelt
%w = select_enum %d : $EitherOr<(), ()>,
case #EitherOr.Center!enumelt: %t,
default %f : $Builtin.Int1
%g = function_ref @consume_case_test_result : $@convention(thin) (Builtin.Int1, Builtin.Int1, Builtin.Int1, Builtin.Int1) -> ()
%r = apply %g(%x, %y, %z, %w) : $@convention(thin) (Builtin.Int1, Builtin.Int1, Builtin.Int1, Builtin.Int1) -> ()
return %r : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @dynamic_multi_payload_case_test
sil @dynamic_multi_payload_case_test : $@convention(thin) <T, U> () -> () {
entry:
%t = integer_literal $Builtin.Int1, 1
%f = integer_literal $Builtin.Int1, 0
%a = alloc_stack $EitherOr<T, U>
// CHECK: [[LEFT:%.*]] = icmp eq i32 {{%.*}}, 0
%x = select_enum_addr %a : $*EitherOr<T, U>,
case #EitherOr.Left!enumelt.1: %t,
default %f : $Builtin.Int1
// CHECK: [[RIGHT:%.*]] = icmp eq i32 {{%.*}}, 1
%y = select_enum_addr %a : $*EitherOr<T, U>,
case #EitherOr.Right!enumelt.1: %t,
default %f : $Builtin.Int1
// CHECK: [[MIDDLE:%.*]] = icmp eq i32 {{%.*}}, 2
%z = select_enum_addr %a : $*EitherOr<T, U>,
case #EitherOr.Middle!enumelt: %t,
default %f : $Builtin.Int1
// CHECK: [[CENTER:%.*]] = icmp eq i32 {{%.*}}, 3
%w = select_enum_addr %a : $*EitherOr<T, U>,
case #EitherOr.Center!enumelt: %t,
default %f : $Builtin.Int1
// CHECK: call swiftcc void @consume_case_test_result(i1 [[LEFT]], i1 [[RIGHT]], i1 [[MIDDLE]], i1 [[CENTER]])
%g = function_ref @consume_case_test_result : $@convention(thin) (Builtin.Int1, Builtin.Int1, Builtin.Int1, Builtin.Int1) -> ()
%r = apply %g(%x, %y, %z, %w) : $@convention(thin) (Builtin.Int1, Builtin.Int1, Builtin.Int1, Builtin.Int1) -> ()
dealloc_stack %a : $*EitherOr<T, U>
return %r : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @dynamic_inject
// CHECK: ([[EITHER_OR:%T26enum_dynamic_multi_payload8EitherOrO.*]]* noalias nocapture sret, %swift.type* %T)
sil @dynamic_inject : $@convention(thin) <T> () -> @out EitherOr<T, Builtin.Int64> {
entry(%e : $*EitherOr<T, Builtin.Int64>):
// CHECK: call void @swift_storeEnumTagMultiPayload(%swift.opaque* {{%.*}}, %swift.type* [[TYPE:%.*]], i32 0)
inject_enum_addr %e : $*EitherOr<T, Builtin.Int64>, #EitherOr.Left!enumelt.1
// CHECK: call void @swift_storeEnumTagMultiPayload(%swift.opaque* {{%.*}}, %swift.type* [[TYPE]], i32 2)
inject_enum_addr %e : $*EitherOr<T, Builtin.Int64>, #EitherOr.Middle!enumelt
// CHECK: call void @swift_storeEnumTagMultiPayload(%swift.opaque* {{%.*}}, %swift.type* [[TYPE]], i32 3)
inject_enum_addr %e : $*EitherOr<T, Builtin.Int64>, #EitherOr.Center!enumelt
// CHECK: call void @swift_storeEnumTagMultiPayload(%swift.opaque* {{%.*}}, %swift.type* [[TYPE]], i32 1)
inject_enum_addr %e : $*EitherOr<T, Builtin.Int64>, #EitherOr.Right!enumelt.1
return undef : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @dynamic_project
// CHECK: ([[EITHER_OR]]* noalias nocapture sret, %swift.type* %T)
sil @dynamic_project : $@convention(thin) <T> () -> @out EitherOr<T, Builtin.Int64> {
entry(%e : $*EitherOr<T, Builtin.Int64>):
// CHECK: bitcast [[EITHER_OR]]* %0 to %swift.opaque*
%l = unchecked_take_enum_data_addr %e : $*EitherOr<T, Builtin.Int64>, #EitherOr.Left!enumelt.1
// CHECK: bitcast [[EITHER_OR]]* %0 to i64*
%r = unchecked_take_enum_data_addr %e : $*EitherOr<T, Builtin.Int64>, #EitherOr.Right!enumelt.1
return undef : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @dynamic_switch
// CHECK: ([[EITHER_OR]]* noalias nocapture sret, %swift.type* %T)
sil @dynamic_switch : $@convention(thin) <T> () -> @out EitherOr<T, Builtin.Int64> {
entry(%e : $*EitherOr<T, Builtin.Int64>):
// CHECK: [[TAG:%.*]] = call i32 @swift_getEnumCaseMultiPayload
// CHECK: switch i32 [[TAG]]
// CHECK-NEXT: i32 0, label %[[LEFT:[0-9]+]]
// CHECK-NEXT: i32 1, label %[[RIGHT:[0-9]+]]
// CHECK-NEXT: i32 2, label %[[MIDDLE:[0-9]+]]
// CHECK-NEXT: i32 3, label %[[CENTER:[0-9]+]]
switch_enum_addr %e : $*EitherOr<T, Builtin.Int64>,
case #EitherOr.Left!enumelt.1: left,
case #EitherOr.Middle!enumelt: middle,
case #EitherOr.Center!enumelt: center,
case #EitherOr.Right!enumelt.1: right
// CHECK: <label>:[[LEFT]]
left:
%0 = integer_literal $Builtin.Int8, 0
br next(%0 : $Builtin.Int8)
// CHECK: <label>:[[MIDDLE]]
middle:
%1 = integer_literal $Builtin.Int8, 1
br next(%1 : $Builtin.Int8)
// CHECK: <label>:[[CENTER]]
center:
%2 = integer_literal $Builtin.Int8, 2
br next(%2 : $Builtin.Int8)
// CHECK: <label>:[[RIGHT]]
right:
%3 = integer_literal $Builtin.Int8, 3
br next(%3 : $Builtin.Int8)
// CHECK: phi i8 [ 3, %[[RIGHT]] ], [ 2, %[[CENTER]] ], [ 1, %[[MIDDLE]] ], [ 0, %[[LEFT]] ]
next(%x : $Builtin.Int8):
return undef : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @dynamic_value_semantics
// CHECK: ([[EITHER_OR]]* noalias nocapture sret, [[EITHER_OR]]* noalias nocapture, %swift.type* %T)
sil @dynamic_value_semantics : $@convention(thin) <T> (@in EitherOr<T, Builtin.Int64>) -> @out EitherOr<T, Builtin.Int64> {
entry(%a : $*EitherOr<T, Builtin.Int64>, %b : $*EitherOr<T, Builtin.Int64>):
// CHECK: [[TAG:%.*]] = call i32 @swift_getEnumCaseMultiPayload
// -- only the Left branch of this instance needs cleanup
// CHECK: [[COND:%.*]] = icmp ne i32 [[TAG]], 0
// CHECK-NEXT: br i1 [[COND]], label %[[NOOP:[0-9]+]], label %[[LEFT:[0-9]+]]
// CHECK: <label>:[[LEFT]]
// CHECK: call void %destroy(%swift.opaque* noalias {{%.*}}, %swift.type* %T)
// CHECK: br label %[[NOOP]]
// CHECK: <label>:[[NOOP]]
destroy_addr %a : $*EitherOr<T, Builtin.Int64>
// CHECK: [[TAG:%.*]] = call i32 @swift_getEnumCaseMultiPayload
// -- only the Left branch of this instance needs nontrivial take
// CHECK: [[COND:%.*]] = icmp ne i32 [[TAG]], 0
// CHECK-NEXT: br i1 [[COND]], label %[[TRIVIAL:[0-9]+]], label %[[LEFT:[0-9]+]]
// CHECK: <label>:[[LEFT]]
// CHECK: call %swift.opaque* %initializeWithTake(%swift.opaque* noalias {{%.*}}, %swift.type* %T)
// CHECK: br label %[[DONE:[0-9]+]]
// CHECK: <label>:[[TRIVIAL]]
// CHECK: call void @llvm.memcpy
// CHECK: br label %[[DONE]]
// CHECK: <label>:[[DONE]]
copy_addr [take] %a to [initialization] %b : $*EitherOr<T, Builtin.Int64>
copy_addr [take] %a to %b : $*EitherOr<T, Builtin.Int64>
copy_addr %a to [initialization] %b : $*EitherOr<T, Builtin.Int64>
copy_addr %a to %b : $*EitherOr<T, Builtin.Int64>
return undef : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @dynamic_value_semantics2
// CHECK: ([[EITHER_OR:%T26enum_dynamic_multi_payload8EitherOrO.*]]* noalias nocapture sret, [[EITHER_OR]]* noalias nocapture, %swift.type* %T)
sil @dynamic_value_semantics2 : $@convention(thin) <T> (@in EitherOr<T, C>) -> @out EitherOr<T, C> {
entry(%a : $*EitherOr<T, C>, %b : $*EitherOr<T, C>):
// CHECK: [[TAG:%.*]] = call i32 @swift_getEnumCaseMultiPayload
// CHECK: switch i32 [[TAG]], label %[[NOOP:[0-9]+]] [
// CHECK-NEXT: i32 0, label %[[LEFT:[0-9]+]]
// CHECK-NEXT: i32 1, label %[[RIGHT:[0-9]+]]
// CHECK-NEXT: ]
// CHECK: <label>:[[LEFT]]
// CHECK: call void %destroy(%swift.opaque* noalias {{%.*}}, %swift.type* %T)
// CHECK: br label %[[NOOP]]
// CHECK: <label>:[[RIGHT]]
// CHECK: call void {{.*}} @swift_release
// CHECK: <label>:[[NOOP]]
destroy_addr %a : $*EitherOr<T, C>
// CHECK: [[TAG:%.*]] = call i32 @swift_getEnumCaseMultiPayload
// -- only the Left branch of this instance needs cleanup
// CHECK: [[COND:%.*]] = icmp ne i32 [[TAG]], 0
// CHECK-NEXT: br i1 [[COND]], label %[[TRIVIAL:[0-9]+]], label %[[LEFT:[0-9]+]]
// CHECK: <label>:[[LEFT]]
// CHECK: call %swift.opaque* %initializeWithTake(%swift.opaque* noalias {{%.*}}, %swift.type* %T)
// CHECK: br label %[[DONE:[0-9]+]]
// CHECK: <label>:[[TRIVIAL]]
// CHECK: call void @llvm.memcpy
// CHECK: br label %[[DONE]]
// CHECK: <label>:[[DONE]]
copy_addr [take] %a to [initialization] %b : $*EitherOr<T, C>
// CHECK: [[TAG:%.*]] = call i32 @swift_getEnumCaseMultiPayload
// CHECK: switch i32 [[TAG]], label %[[TRIVIAL:[0-9]+]] [
// -- both branches have nontrivial copy
// CHECK-NEXT: i32 0, label %[[LEFT:[0-9]+]]
// CHECK-NEXT: i32 1, label %[[RIGHT:[0-9]+]]
// CHECK-NEXT: ]
// CHECK: <label>:[[LEFT]]
// CHECK: call %swift.opaque* %initializeWithCopy(%swift.opaque* noalias {{%.*}}, %swift.type* %T)
// CHECK: br label %[[DONE:[0-9]+]]
// CHECK: <label>:[[RIGHT]]
// CHECK: call %swift.refcounted* @swift_retain
// CHECK: br label %[[DONE:[0-9]+]]
// CHECK: <label>:[[TRIVIAL]]
// CHECK: call void @llvm.memcpy
// CHECK: br label %[[DONE]]
// CHECK: <label>:[[DONE]]
copy_addr %a to [initialization] %b : $*EitherOr<T, C>
return undef : $()
}
// CHECK: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$s26enum_dynamic_multi_payload8EitherOrOMi"(%swift.type_descriptor*, i8**, i8*) {{.*}} {
// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata
// CHECK: define{{( protected)?}} internal swiftcc %swift.metadata_response @"$s26enum_dynamic_multi_payload8EitherOrOMr"
// CHECK-SAME: (%swift.type* [[METADATA:%.*]], i8*, i8**) {{.*}} {
// CHECK: [[BUF:%.*]] = alloca [2 x i8**]
// CHECK: [[BUF0:%.*]] = getelementptr {{.*}} [[BUF]], i32 0, i32 0
// CHECK: [[T0:%.*]] = call{{( tail)?}} swiftcc %swift.metadata_response @swift_checkMetadataState([[INT]] 319, %swift.type* %T)
// CHECK-NEXT: [[T_CHECKED:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
// CHECK-NEXT: [[T_STATUS:%.*]] = extractvalue %swift.metadata_response [[T0]], 1
// CHECK-NEXT: [[T_OK:%.*]] = icmp ule [[INT]] [[T_STATUS]], 63
// CHECK-NEXT: br i1 [[T_OK]],
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]]
// CHECK-NEXT: [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
// CHECK-NEXT: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 8
// CHECK-NEXT: store i8** [[LAYOUT]], {{.*}} [[BUF0]]
// CHECK: [[BUF1:%.*]] = getelementptr {{.*}} [[BUF]], i32 0, i32 1
// CHECK: [[T0:%.*]] = call{{( tail)?}} swiftcc %swift.metadata_response @swift_checkMetadataState([[INT]] 319, %swift.type* %U)
// CHECK-NEXT: [[U_CHECKED:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
// CHECK-NEXT: [[U_STATUS:%.*]] = extractvalue %swift.metadata_response [[T0]], 1
// CHECK-NEXT: [[U_OK:%.*]] = icmp ule [[INT]] [[U_STATUS]], 63
// CHECK-NEXT: br i1 [[U_OK]],
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[U_CHECKED]] to i8***
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]]
// CHECK-NEXT: [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
// CHECK-NEXT: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 8
// CHECK-NEXT: store i8** [[LAYOUT]], {{.*}} [[BUF1]]
// CHECK: call void @swift_initEnumMetadataMultiPayload(%swift.type* [[METADATA]], {{i(32|64)}} 0, {{i(32|64)}} 2, i8*** [[BUF0]])