Files
swift-mirror/test/IRGen/enum_value_semantics.sil
T
John McCall 0ffb7278bc Only use metadata patterns for generic types; perform other
initialization in-place on demand.  Initialize parent metadata
references correctly on struct and enum metadata.

Also includes several minor improvements related to relative
pointers that I was using before deciding to simply switch the
parent reference to an absolute reference to get better access
patterns.

Includes a fix since the earlier commit to make enum metadata
writable if they have an unfilled payload size.  This didn't show
up on Darwin because "constant" is currently unenforced there in
global data containing relocations.

This patch requires an associated LLDB change which is being
submitted in parallel.
2016-03-24 15:10:31 -07:00

727 lines
36 KiB
Plaintext

// RUN: %target-swift-frontend %s -gnone -emit-ir | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
// REQUIRES: CPU=x86_64
import Builtin
enum NoPayload {
case a
case b
case c
}
enum SingletonPayload {
case S(Builtin.Int64, Builtin.Int64)
}
enum SinglePayloadTrivial {
case payload(Builtin.Int64)
case a
case b
case c
}
enum SinglePayloadNontrivial {
case payload(Builtin.NativeObject)
case a
case b
case c
}
enum MultiPayloadTrivial {
case payload1(Builtin.Int64)
case payload2(Builtin.Int32, Builtin.Int32)
case a
case b
case c
}
enum MultiPayloadNoEmptyCases {
case payload1(Builtin.Int64)
case payload2(Builtin.Int32, Builtin.Int32)
}
enum MultiPayloadEmptyPayload {
case payload1()
case payload2()
case a
case b
case c
}
// No spare bits
enum MultiPayloadNontrivial {
case payload1(Builtin.NativeObject)
case payload2(Builtin.Int64)
case payload3(Builtin.Int64, Builtin.UnknownObject)
case payload4(Builtin.Int64, Builtin.Int64)
case a
case b
case c
}
enum MultiPayloadGeneric<T> {
case payload1(T)
case payload2(T)
case a
case b
case c
}
// Most significant bits of second 64-bit word of payload
// are spare bits
enum MultiPayloadNontrivialSpareBits {
case payload1(Builtin.NativeObject)
case payload2(Builtin.Int64)
case payload3(Builtin.Int64, Builtin.UnknownObject)
case a
case b
case c
}
// We only have 1 spare bit but 3 payload cases
enum MultiPayloadSpareBitsAndExtraBits {
case payload1(Builtin.Int63)
case payload2(Builtin.NativeObject)
case payload3(Builtin.NativeObject)
}
enum GenericFixedLayout<T> {
case foo(Builtin.Int64)
case bar(Builtin.NativeObject)
}
// CHECK-LABEL: @_TWVO20enum_value_semantics20SinglePayloadTrivial = {{(protected )?}}constant [26 x i8*] [
// CHECK: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
// CHECK: i8* bitcast (i8* (i8*, %swift.type*)* @__swift_noop_self_return to i8*),
// CHECK: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*),
// CHECK: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
// CHECK: i8* bitcast (i8* (i8*, %swift.type*)* @__swift_noop_self_return to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
// CHECK: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, i64, %swift.type*)* @__swift_memcpy_array16_8 to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, i64, %swift.type*)* @__swift_memmove_array16_8 to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, i64, %swift.type*)* @__swift_memmove_array16_8 to i8*),
// CHECK: i8* inttoptr (i64 9 to i8*),
// CHECK: i8* inttoptr (i64 2097159 to i8*),
// CHECK: i8* inttoptr (i64 16 to i8*),
// CHECK: i8* null,
// CHECK: i8* null,
// CHECK: i8* null,
// CHECK: i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_TwugO20enum_value_semantics20SinglePayloadTrivial to i8*),
// CHECK: i8* bitcast (void (%swift.opaque*, %swift.type*)* @_TwupO20enum_value_semantics20SinglePayloadTrivial to i8*),
// CHECK: i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_TwuiO20enum_value_semantics20SinglePayloadTrivial to i8*)
// CHECK: ]
// CHECK-LABEL: @_TMfO20enum_value_semantics20SinglePayloadTrivial =
// CHECK-SAME: internal constant {{.*}} <{
// CHECK-SAME: i8** getelementptr inbounds ([26 x i8*], [26 x i8*]* @_TWVO20enum_value_semantics20SinglePayloadTrivial, i32 0, i32 0),
// CHECK-SAME: i64 2,
// CHECK-SAME: {{.*}}* @_TMnO20enum_value_semantics20SinglePayloadTrivial
// CHECK-SAME: %swift.type* null
// CHECK-SAME: }>
// CHECK-LABEL: @_TWVO20enum_value_semantics23SinglePayloadNontrivial = {{(protected )?}}constant [26 x i8*] [
// CHECK: i8* bitcast (void ([24 x i8]*, %swift.type*)* @_TwXXO20enum_value_semantics23SinglePayloadNontrivial to i8*),
// CHECK: i8* bitcast (%swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)* @_TwCPO20enum_value_semantics23SinglePayloadNontrivial to i8*),
// CHECK: i8* bitcast (i8* (i8*, %swift.type*)* @__swift_noop_self_return to i8*),
// CHECK: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*),
// CHECK: i8* bitcast (void (%swift.opaque*, %swift.type*)* @_TwxxO20enum_value_semantics23SinglePayloadNontrivial to i8*),
// CHECK: i8* bitcast (%swift.opaque* ([24 x i8]*, %swift.opaque*, %swift.type*)* @_TwCpO20enum_value_semantics23SinglePayloadNontrivial to i8*),
// CHECK: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @_TwcpO20enum_value_semantics23SinglePayloadNontrivial to i8*),
// CHECK: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @_TwcaO20enum_value_semantics23SinglePayloadNontrivial to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy8_8 to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy8_8 to i8*),
// CHECK: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @_TwtaO20enum_value_semantics23SinglePayloadNontrivial to i8*),
// CHECK: i8* bitcast (i8* (i8*, %swift.type*)* @__swift_noop_self_return to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy8_8 to i8*),
// CHECK: i8* bitcast (void (%swift.opaque*, i64, %swift.type*)* @_TwXxO20enum_value_semantics23SinglePayloadNontrivial to i8*),
// CHECK: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, i64, %swift.type*)* @_TwCcO20enum_value_semantics23SinglePayloadNontrivial to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, i64, %swift.type*)* @__swift_memmove_array8_8 to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, i64, %swift.type*)* @__swift_memmove_array8_8 to i8*),
// CHECK: i8* inttoptr (i64 8 to i8*),
// -- 0x250007
// CHECK: i8* inttoptr (i64 2424839 to i8*),
// CHECK: i8* inttoptr (i64 8 to i8*),
// -- on Darwin, first 4GB are unmapped: 0x7ffffffc
// -- on Linux, only safe to assume first 4KB: 0x7fd
// CHECK: i8* inttoptr (i64 {{2045|2147483644}} to i8*)
// CHECK: i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_TwxsO20enum_value_semantics23SinglePayloadNontrivial to i8*)
// CHECK: i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_TwxgO20enum_value_semantics23SinglePayloadNontrivial to i8*)
// CHECK: i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_TwugO20enum_value_semantics23SinglePayloadNontrivial to i8*),
// CHECK: i8* bitcast (void (%swift.opaque*, %swift.type*)* @_TwupO20enum_value_semantics23SinglePayloadNontrivial to i8*)
// CHECK: i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_TwuiO20enum_value_semantics23SinglePayloadNontrivial to i8*)
// CHECK: ]
// CHECK-LABEL: @_TMfO20enum_value_semantics23SinglePayloadNontrivial =
// CHECK-SAME: internal constant {{.*}} <{
// CHECK-SAME: i8** getelementptr inbounds ([26 x i8*], [26 x i8*]* @_TWVO20enum_value_semantics23SinglePayloadNontrivial, i32 0, i32 0),
// CHECK-SAME: i64 2,
// CHECK-SAME: {{.*}}* @_TMnO20enum_value_semantics23SinglePayloadNontrivial
// CHECK-SAME: %swift.type* null
// CHECK-SAME: }>
// CHECK-LABEL: @_TMPO20enum_value_semantics18GenericFixedLayout = {{(protected )?}}global <{{[{].*\* [}]}}> <{
// CHECK: %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_GenericFixedLayout
// CHECK: i32 48, i16 1, i16 8,
// CHECK: [16 x i8*] zeroinitializer,
// CHECK: i8** getelementptr inbounds ([26 x i8*], [26 x i8*]* @_TWVO20enum_value_semantics18GenericFixedLayout, i32 0, i32 0),
// CHECK: i64 2,
// CHECK: {{.*}}* @_TMnO20enum_value_semantics18GenericFixedLayout
// CHECK: i{{32|64}} 0
// CHECK: %swift.type* null,
// CHECK: %swift.type** null
// CHECK: }>
sil @single_payload_nontrivial_copy_destroy : $(SinglePayloadNontrivial) -> () {
bb0(%0 : $SinglePayloadNontrivial):
retain_value %0 : $SinglePayloadNontrivial
release_value %0 : $SinglePayloadNontrivial
%v = tuple ()
return %v : $()
}
// CHECK-LABEL: define{{( protected)?}} void @single_payload_nontrivial_copy_destroy(i64)
// CHECK: switch i64 %0, label [[PRESENT:%.*]] [
// CHECK-NEXT: i64 0, label [[NOT_PRESENT:%.*]]
// CHECK-NEXT: i64 2, label [[NOT_PRESENT]]
// CHECK-NEXT: i64 4, label [[NOT_PRESENT]]
// CHECK-NEXT: ]
// CHECK: [[T0:%.*]] = inttoptr i64 [[V:%.*]] to %swift.refcounted*
// CHECK-NEXT: call void @rt_swift_retain(%swift.refcounted* [[T0]])
// CHECK-NEXT: br label [[NOT_PRESENT]]
// CHECK: switch i64 %0, label [[PRESENT:%.*]] [
// CHECK-NEXT: i64 0, label [[NOT_PRESENT:%.*]]
// CHECK-NEXT: i64 2, label [[NOT_PRESENT]]
// CHECK-NEXT: i64 4, label [[NOT_PRESENT]]
// CHECK-NEXT: ]
// CHECK: [[T0:%.*]] = inttoptr i64 [[V:%.*]] to %swift.refcounted*
// CHECK-NEXT: call void @rt_swift_release(%swift.refcounted* [[T0]])
// CHECK-NEXT: br label [[NOT_PRESENT]]
// CHECK: ret void
//
// No payload enums
//
// -- NoPayload getExtraInhabitants
// CHECK-LABEL: define linkonce_odr hidden i32 @_TwxgO20enum_value_semantics9NoPayload
// CHECK: [[VALUE:%.*]] = load i8, i8* {{%.*}}, align 1
// CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[VALUE]] to i32
// CHECK-NEXT: [[SUB:%.*]] = sub i32 [[ZEXT]], 3
// CHECK-NEXT: [[EXTRA:%.*]] = icmp slt i32 [[SUB]], 0
// CHECK-NEXT: [[RES:%.*]] = select i1 [[EXTRA]], i32 -1, i32 [[SUB]]
// CHECK-NEXT: ret i32 [[RES]]
// -- NoPayload getEnumTag
// CHECK-LABEL: define linkonce_odr hidden i32 @_TwugO20enum_value_semantics9NoPayload
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics9NoPayload*
// CHECK-NEXT: [[TAG_ADDR:%.*]] = getelementptr inbounds %O20enum_value_semantics9NoPayload, %O20enum_value_semantics9NoPayload* [[SELF]], i32 0, i32 0
// CHECK-NEXT: [[TAG:%.*]] = load i2, i2* [[TAG_ADDR]], align 1
// CHECK-NEXT: [[RESULT:%.*]] = zext i2 %2 to i32
// CHECK-NEXT: ret i32 [[RESULT]]
// -- NoPayload destructiveProjectEnumData
// CHECK-LABEL: define linkonce_odr hidden void @_TwupO20enum_value_semantics9NoPayload
// CHECK: ret void
// -- NoPayload destructiveInjectEnumTag
// CHECK-LABEL: define linkonce_odr hidden void @_TwuiO20enum_value_semantics9NoPayload
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics9NoPayload*
// CHECK-NEXT: [[TAG:%.*]] = trunc i32 %tag to i2
// CHECK-NEXT: [[TAG_ADDR:%.*]] = getelementptr inbounds %O20enum_value_semantics9NoPayload, %O20enum_value_semantics9NoPayload* [[SELF]], i32 0, i32 0
// CHECK-NEXT: store i2 [[TAG]], i2* [[TAG_ADDR]], align 1
// CHECK-NEXT: ret void
//
// Singleton payload enums
//
// -- SingletonPayload getEnumTag
// CHECK-LABEL: define linkonce_odr hidden i32 @_TwugO20enum_value_semantics16SingletonPayload
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics16SingletonPayload*
// CHECK-NEXT: ret i32 -1
// -- SingletonPayload destructiveProjectEnumData
// CHECK-LABEL: define linkonce_odr hidden void @_TwupO20enum_value_semantics16SingletonPayload
// CHECK: ret void
// -- SingletonPayload destructiveInjectEnumTag
// CHECK-LABEL: define linkonce_odr hidden void @_TwuiO20enum_value_semantics16SingletonPayload
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics16SingletonPayload*
// CHECK-NEXT: ret void
// -- SinglePayloadTrivial getEnumTag
// CHECK-LABEL: define linkonce_odr hidden i32 @_TwugO20enum_value_semantics20SinglePayloadTrivial
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics20SinglePayloadTrivial*
// CHECK-NEXT: [[OPAQUE:%.*]] = bitcast %O20enum_value_semantics20SinglePayloadTrivial* [[SELF]] to %swift.opaque*
// CHECK-NEXT: [[TAG:%.*]] = call i32 @rt_swift_getEnumCaseSinglePayload(%swift.opaque* [[OPAQUE]], %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* @_TMBi64_, i32 0, i32 1), i32 3)
// CHECK-NEXT: ret i32 [[TAG]]
// -- SinglePayloadTrivial destructiveProjectEnumData
// CHECK-LABEL: define linkonce_odr hidden void @_TwupO20enum_value_semantics20SinglePayloadTrivial
// CHECK: ret void
//
// Single-payload enums
//
// -- SinglePayloadTrivial destructiveInjectEnumTag
// CHECK-LABEL: define linkonce_odr hidden void @_TwuiO20enum_value_semantics20SinglePayloadTrivial
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics20SinglePayloadTrivial*
// CHECK-NEXT: [[OPAQUE:%.*]] = bitcast %O20enum_value_semantics20SinglePayloadTrivial* [[SELF]] to %swift.opaque*
// CHECK-NEXT: call void @rt_swift_storeEnumTagSinglePayload(%swift.opaque* [[OPAQUE]], %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* @_TMBi64_, i32 0, i32 1), i32 %tag, i32 3)
// CHECK-NEXT: ret void
// -- SinglePayloadNontrivial destroyBuffer
// CHECK: define linkonce_odr hidden void @_TwxxO20enum_value_semantics23SinglePayloadNontrivial(%swift.opaque* [[OBJ:%.*]], %swift.type* %SinglePayloadNontrivial) {{.*}} {
// CHECK: [[ADDR:%.*]] = bitcast %swift.opaque* [[OBJ]] to %O20enum_value_semantics23SinglePayloadNontrivial*
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %O20enum_value_semantics23SinglePayloadNontrivial* [[ADDR]] to i64*
// CHECK-NEXT: [[PAYLOAD:%.*]] = load i64, i64* [[PAYLOAD_ADDR]], align 8
// CHECK-NEXT: switch i64 %2, label %[[RELEASE_PAYLOAD:[0-9]+]] [
// CHECK: i64 0, label %[[DONE:[0-9]+]]
// CHECK: i64 2, label %[[DONE]]
// CHECK: i64 4, label %[[DONE]]
// CHECK: ]
// CHECK: ; <label>:[[RELEASE_PAYLOAD]]
// CHECK-NEXT: [[DATA_ADDR:%.*]] = bitcast %O20enum_value_semantics23SinglePayloadNontrivial* [[ADDR]] to %swift.refcounted**
// CHECK-NEXT: [[DATA:%.*]] = load %swift.refcounted*, %swift.refcounted** [[DATA_ADDR]], align 8
// CHECK-NEXT: call void @rt_swift_release(%swift.refcounted* [[DATA]])
// CHECK-NEXT: br label %[[DONE]]
// CHECK: ; <label>:[[DONE]]
// CHECK-NEXT: ret void
//
// Multi-payload enums
//
// -- MultiPayloadTrivial getEnumTag
// CHECK-LABEL: define linkonce_odr hidden i32 @_TwugO20enum_value_semantics19MultiPayloadTrivial
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics19MultiPayloadTrivial*
// CHECK-NEXT: [[PAYLOAD:%.*]] = bitcast %O20enum_value_semantics19MultiPayloadTrivial* [[SELF]] to i64*
// -- Load the low bits of the tag from the payload area
// CHECK-NEXT: [[NO_PAYLOAD_TAG_TMP:%.*]] = load i64, i64* [[PAYLOAD]], align 8
// -- Load the high bits of the tag from the extra tag area
// CHECK-NEXT: [[EXTRA_TAG_ADDR_TMP:%.*]] = getelementptr inbounds %O20enum_value_semantics19MultiPayloadTrivial, %O20enum_value_semantics19MultiPayloadTrivial* [[SELF]], i32 0, i32 1
// CHECK-NEXT: [[EXTRA_TAG_ADDR:%.*]] = bitcast [1 x i8]* [[EXTRA_TAG_ADDR_TMP]] to i2*
// CHECK-NEXT: [[EXTRA_TAG_TMP:%.*]] = load i2, i2* [[EXTRA_TAG_ADDR]], align 8
// CHECK-NEXT: [[EXTRA_TAG:%.*]] = zext i2 [[EXTRA_TAG_TMP]] to i32
// -- Form tag for the payload case, or the high bits of no-payload case
// CHECK-NEXT: [[PAYLOAD_TAG:%.*]] = sub i32 [[EXTRA_TAG]], 2
// -- Combine them to form the tag for the no-payload case
// CHECK-NEXT: [[NO_PAYLOAD_TAG:%.*]] = trunc i64 [[NO_PAYLOAD_TAG_TMP]] to i32
// -- Check if we have a payload or not
// CHECK-NEXT: [[IS_PAYLOAD:%.*]] = icmp sge i32 [[PAYLOAD_TAG]], 0
// CHECK-NEXT: [[TAG:%.*]] = select i1 [[IS_PAYLOAD]], i32 [[NO_PAYLOAD_TAG]], i32 [[PAYLOAD_TAG]]
// -- Return the tag
// CHECK-NEXT: ret i32 [[TAG]]
// -- MultiPayloadTrivial destructiveProjectEnumData
// CHECK-LABEL: define linkonce_odr hidden void @_TwupO20enum_value_semantics19MultiPayloadTrivial
// CHECK: ret void
// -- MultiPayloadTrivial destructiveInjectEnumTag
// CHECK-LABEL: define linkonce_odr hidden void @_TwuiO20enum_value_semantics19MultiPayloadTrivial
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics19MultiPayloadTrivial*
// CHECK-NEXT: [[IS_PAYLOAD:%.*]] = icmp sge i32 %tag, 0
// CHECK-NEXT: br i1 [[IS_PAYLOAD]], label %[[HAS_NO_PAYLOAD:.*]], label %[[HAS_PAYLOAD:.*]]
// CHECK: ; <label>:[[HAS_NO_PAYLOAD]]
// -- Compute the no-payload tag
// CHECK-NEXT: [[NO_PAYLOAD_TAG:%.*]] = zext i32 %tag to i64
// CHECK-NEXT: [[PAYLOAD:%.*]] = bitcast %O20enum_value_semantics19MultiPayloadTrivial* [[SELF]] to i64*
// -- Store the low bits of the tag in the payload area
// CHECK-NEXT: store i64 [[NO_PAYLOAD_TAG]], i64* [[PAYLOAD]], align 8
// -- Store the high bits of the tag in the extra tag area
// CHECK-NEXT: [[EXTRA_TAG_ADDR_TMP:%.*]] = getelementptr inbounds %O20enum_value_semantics19MultiPayloadTrivial, %O20enum_value_semantics19MultiPayloadTrivial* [[SELF]], i32 0, i32 1
// CHECK-NEXT: [[EXTRA_TAG_ADDR:%.*]] = bitcast [1 x i8]* [[EXTRA_TAG_ADDR_TMP]] to i2*
// CHECK-NEXT: store i2 -2, i2* [[EXTRA_TAG_ADDR]], align 8
// CHECK-NEXT: br label %[[DONE:.*]]
// CHECK: ; <label>:[[HAS_PAYLOAD]]
// -- Store the tag in the extra tag area
// CHECK-NEXT: [[PAYLOAD_TAG:%.*]] = add i32 %tag, 2
// CHECK-NEXT: [[TAG:%.*]] = trunc i32 [[PAYLOAD_TAG]] to i2
// CHECK-NEXT: [[EXTRA_TAG_ADDR_TMP:%.*]] = getelementptr inbounds %O20enum_value_semantics19MultiPayloadTrivial, %O20enum_value_semantics19MultiPayloadTrivial* [[SELF]], i32 0, i32 1
// CHECK-NEXT: [[EXTRA_TAG_ADDR:%.*]] = bitcast [1 x i8]* [[EXTRA_TAG_ADDR_TMP]] to i2*
// CHECK-NEXT: store i2 [[TAG]], i2* [[EXTRA_TAG_ADDR]], align 8
// CHECK-NEXT: br label %[[DONE]]
// CHECK: ; <label>:[[DONE]]
// CHECK-NEXT: ret void
//
// Multi-payload enums with no empty cases
//
// -- MultiPayloadNoEmptyCases getEnumTag
// CHECK-LABEL: define linkonce_odr hidden i32 @_TwugO20enum_value_semantics24MultiPayloadNoEmptyCases
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics24MultiPayloadNoEmptyCases*
// CHECK-NEXT: [[PAYLOAD:%.*]] = bitcast %O20enum_value_semantics24MultiPayloadNoEmptyCases* [[SELF]] to i64*
// CHECK-NEXT: [[NO_PAYLOAD_TAG_TMP:%.*]] = load i64, i64* [[PAYLOAD]], align 8
// -- The payload has no spare bits and there are no empty cases, so the tag
// is entirely contained in the extra tag area
// CHECK-NEXT: [[EXTRA_TAG_ADDR_TMP:%.*]] = getelementptr inbounds %O20enum_value_semantics24MultiPayloadNoEmptyCases, %O20enum_value_semantics24MultiPayloadNoEmptyCases* [[SELF]], i32 0, i32 1
// CHECK-NEXT: [[EXTRA_TAG_ADDR:%.*]] = bitcast [1 x i8]* [[EXTRA_TAG_ADDR_TMP]] to i1*
// CHECK-NEXT: [[EXTRA_TAG_TMP:%.*]] = load i1, i1* [[EXTRA_TAG_ADDR]], align 8
// CHECK-NEXT: [[EXTRA_TAG:%.*]] = zext i1 [[EXTRA_TAG_TMP]] to i32
// CHECK-NEXT: [[PAYLOAD_TAG:%.*]] = sub i32 [[EXTRA_TAG]], 2
// CHECK-NEXT: ret i32 [[PAYLOAD_TAG]]
// -- MultiPayloadNoEmptyCases destructiveProjectEnumData
// CHECK-LABEL: define linkonce_odr hidden void @_TwupO20enum_value_semantics24MultiPayloadNoEmptyCases
// CHECK: ret void
// -- MultiPayloadNoEmptyCases destructiveInjectEnumTag
// CHECK-LABEL: define linkonce_odr hidden void @_TwuiO20enum_value_semantics24MultiPayloadNoEmptyCases
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics24MultiPayloadNoEmptyCases*
// CHECK-NEXT: [[PAYLOAD_TAG:%.*]] = add i32 %tag, 2
// CHECK-NEXT: [[TAG:%.*]] = trunc i32 [[PAYLOAD_TAG]] to i1
// -- Store the tag in the extra tag area
// CHECK-NEXT: [[EXTRA_TAG_ADDR_TMP:%.*]] = getelementptr inbounds %O20enum_value_semantics24MultiPayloadNoEmptyCases, %O20enum_value_semantics24MultiPayloadNoEmptyCases* [[SELF]], i32 0, i32 1
// CHECK-NEXT: [[EXTRA_TAG_ADDR:%.*]] = bitcast [1 x i8]* [[EXTRA_TAG_ADDR_TMP]] to i1*
// CHECK-NEXT: store i1 [[TAG]], i1* [[EXTRA_TAG_ADDR]], align 8
// CHECK-NEXT: ret void
//
// Multi-payload enum with empty payloads -- payload tag is not used
//
// -- MultiPayloadEmptyPayload getEnumTag
// CHECK-LABEL: define linkonce_odr hidden i32 @_TwugO20enum_value_semantics24MultiPayloadEmptyPayload
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics24MultiPayloadEmptyPayload*
// -- Load the tag from the extra tag area
// CHECK-NEXT: [[EXTRA_TAG_ADDR:%.*]] = getelementptr inbounds %O20enum_value_semantics24MultiPayloadEmptyPayload, %O20enum_value_semantics24MultiPayloadEmptyPayload* [[SELF]], i32 0, i32 0
// CHECK-NEXT: [[EXTRA_TAG_TMP:%.*]] = load i3, i3* [[EXTRA_TAG_ADDR]], align 1
// CHECK-NEXT: [[EXTRA_TAG:%.*]] = zext i3 [[EXTRA_TAG_TMP]] to i32
// CHECK-NEXT: ret i32 [[EXTRA_TAG]]
// -- MultiPayloadEmptyPayload destructiveProjectEnumData
// CHECK-LABEL: define linkonce_odr hidden void @_TwupO20enum_value_semantics24MultiPayloadEmptyPayload
// CHECK: ret void
// -- MultiPayloadEmptyPayload destructiveInjectEnumTag
// CHECK-LABEL: define linkonce_odr hidden void @_TwuiO20enum_value_semantics24MultiPayloadEmptyPayload
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics24MultiPayloadEmptyPayload*
// -- Store the tag in the extra tag area
// CHECK-NEXT: [[TAG:%.*]] = trunc i32 %tag to i3
// CHECK-NEXT: [[EXTRA_TAG_ADDR:%.*]] = getelementptr inbounds %O20enum_value_semantics24MultiPayloadEmptyPayload, %O20enum_value_semantics24MultiPayloadEmptyPayload* [[SELF]], i32 0, i32 0
// CHECK-NEXT: store i3 [[TAG]], i3* [[EXTRA_TAG_ADDR]], align 1
// CHECK-NEXT: ret void
//
// Multi-payload enum with non-POD payloads
//
// -- MultiPayloadNontrivial destroyBuffer
// CHECK: define linkonce_odr hidden void @_TwxxO20enum_value_semantics22MultiPayloadNontrivial(%swift.opaque* [[OBJ:%.*]], %swift.type* %MultiPayloadNontrivial)
// CHECK: [[ADDR:%.*]] = bitcast %swift.opaque* [[OBJ]] to %O20enum_value_semantics22MultiPayloadNontrivial*
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %O20enum_value_semantics22MultiPayloadNontrivial* [[ADDR]] to { i64, i64 }*
// CHECK-NEXT: [[PAYLOAD_0_ADDR:%.*]] = getelementptr
// CHECK-NEXT: [[PAYLOAD_0:%.*]] = load i64, i64* [[PAYLOAD_0_ADDR]], align 8
// CHECK-NEXT: [[PAYLOAD_1_ADDR:%.*]] = getelementptr
// CHECK-NEXT: [[PAYLOAD_1:%.*]] = load i64, i64* [[PAYLOAD_1_ADDR]], align 8
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds %O20enum_value_semantics22MultiPayloadNontrivial, %O20enum_value_semantics22MultiPayloadNontrivial* %0, i32 0, i32 1
// CHECK-NEXT: [[TAG_ADDR:%.*]] = bitcast [1 x i8]* [[T0]] to i3*
// CHECK-NEXT: [[TAG:%.*]] = load i3, i3* [[TAG_ADDR]], align 8
// CHECK-NEXT: switch i3 [[TAG]], label %[[END:[0-9]+]] [
// CHECK: i3 0, label %[[PAYLOAD1_DESTROY:[0-9]+]]
// CHECK: i3 2, label %[[PAYLOAD3_DESTROY:[0-9]+]]
// CHECK: ]
// CHECK: ; <label>:[[PAYLOAD1_DESTROY]]
// CHECK-NEXT: [[PAYLOAD1_VAL:%.*]] = inttoptr i64 [[PAYLOAD_0]] to %swift.refcounted*
// CHECK-NEXT: call void @rt_swift_release(%swift.refcounted* [[PAYLOAD1_VAL]])
// CHECK-NEXT: br label %[[END]]
// CHECK: ; <label>:[[PAYLOAD3_DESTROY]]
// CHECK-NEXT: [[PAYLOAD3_1_VAL:%.*]] = inttoptr i64 [[PAYLOAD_1]] to %objc_object*
// CHECK-NEXT: call void @objc_release(%objc_object* [[PAYLOAD3_1_VAL]])
// CHECK-NEXT: br label %[[END]]
// CHECK: ; <label>:[[END]]
// CHECK-NEXT: ret void
//
// Multi-payload enum with generic layout -- spare bits are not used
//
// CHECK-LABEL: define linkonce_odr hidden i32 @_TwugO20enum_value_semantics19MultiPayloadGeneric
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics19MultiPayloadGeneric*
// CHECK-NEXT: [[OPAQUE:%.*]] = bitcast %O20enum_value_semantics19MultiPayloadGeneric* [[SELF]] to %swift.opaque*
// CHECK-NEXT: [[TAG:%.*]] = call i32 @swift_getEnumCaseMultiPayload(%swift.opaque* [[OPAQUE]], %swift.type* %"MultiPayloadGeneric<T>")
// CHECK-NEXT: [[PAYLOAD_TAG:%.*]] = sub i32 [[TAG]], 2
// CHECK-NEXT: ret i32 [[PAYLOAD_TAG]]
// CHECK-LABEL: define linkonce_odr hidden void @_TwupO20enum_value_semantics19MultiPayloadGeneric
// CHECK: ret void
// CHECK-LABEL: define linkonce_odr hidden void @_TwuiO20enum_value_semantics19MultiPayloadGeneric
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics19MultiPayloadGeneric*
// CHECK-NEXT: [[PAYLOAD_TAG:%.*]] = add i32 %tag, 2
// CHECK: [[OPAQUE:%.*]] = bitcast %O20enum_value_semantics19MultiPayloadGeneric* [[SELF]] to %swift.opaque*
// CHECK-NEXT: call void @swift_storeEnumTagMultiPayload(%swift.opaque* [[OPAQUE]], %swift.type* %"MultiPayloadGeneric<T>", i32 [[PAYLOAD_TAG]])
// CHECK-NEXT: ret void
//
// Multi-payload enum with spare bits
//
// -- MultiPayloadNontrivialSpareBits destroyBuffer
// CHECK-LABEL: define linkonce_odr hidden void @_TwxxO20enum_value_semantics31MultiPayloadNontrivialSpareBits
// CHECK-SAME: (%swift.opaque* [[OBJ:%.*]], %swift.type* %MultiPayloadNontrivialSpareBits) {{.*}} {
// CHECK: [[ADDR:%.*]] = bitcast %swift.opaque* [[OBJ]] to %O20enum_value_semantics31MultiPayloadNontrivialSpareBits*
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %O20enum_value_semantics31MultiPayloadNontrivialSpareBits* [[ADDR]] to { i64, i64 }*
// CHECK-NEXT: [[PAYLOAD_0_ADDR:%.*]] = getelementptr
// CHECK-NEXT: [[PAYLOAD_0:%.*]] = load i64, i64* [[PAYLOAD_0_ADDR]], align 8
// CHECK-NEXT: [[PAYLOAD_1_ADDR:%.*]] = getelementptr
// CHECK-NEXT: [[PAYLOAD_1:%.*]] = load i64, i64* [[PAYLOAD_1_ADDR]], align 8
// CHECK: switch i2 [[SPARE_BITS:%.*]], label %[[END:[0-9]+]] [
// CHECK: i2 0, label %[[PAYLOAD1_DESTROY:[0-9]+]]
// CHECK: i2 -2, label %[[PAYLOAD3_DESTROY:[0-9]+]]
// CHECK: ]
// CHECK: ; <label>:[[PAYLOAD1_DESTROY]]
// CHECK-NEXT: [[PAYLOAD1_VAL:%.*]] = inttoptr i64 [[PAYLOAD_0]] to %swift.refcounted*
// CHECK-NEXT: call void @rt_swift_release(%swift.refcounted* [[PAYLOAD1_VAL]])
// CHECK-NEXT: br label %[[END]]
// CHECK: ; <label>:[[PAYLOAD3_DESTROY]]
// CHECK-NEXT: [[MASKED:%.*]] = and i64 [[PAYLOAD_1]]
// CHECK-NEXT: [[PAYLOAD3_1_VAL:%.*]] = inttoptr i64 [[MASKED]] to %objc_object*
// CHECK-NEXT: call void @objc_release(%objc_object* [[PAYLOAD3_1_VAL]])
// CHECK-NEXT: br label %[[END]]
// CHECK: ; <label>:[[END]]
// CHECK-NEXT: ret void
// CHECK-LABEL: define linkonce_odr hidden i32 @_TwugO20enum_value_semantics31MultiPayloadNontrivialSpareBits
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics31MultiPayloadNontrivialSpareBits*
// -- Load the payload
// CHECK-NEXT: [[PAYLOAD:%.*]] = bitcast %O20enum_value_semantics31MultiPayloadNontrivialSpareBits* [[SELF]] to { i64, i64 }*
// CHECK-NEXT: [[FIRST_ADDR:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[PAYLOAD]], i32 0, i32 0
// CHECK-NEXT: [[FIRST:%.*]] = load i64, i64* [[FIRST_ADDR]], align 8
// CHECK-NEXT: [[SECOND_ADDR:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[PAYLOAD]], i32 0, i32 1
// CHECK-NEXT: [[SECOND:%.*]] = load i64, i64* [[SECOND_ADDR]], align 8
// -- Get the high bits of the tag from the spare bits
// CHECK-NEXT: [[SPARE_TAG_TMP2:%.*]] = lshr i64 [[SECOND]], 62
// CHECK-NEXT: [[SPARE_TAG_TMP:%.*]] = trunc i64 [[SPARE_TAG_TMP2]] to i2
// CHECK-NEXT: [[SPARE_TAG:%.*]] = zext i2 [[SPARE_TAG_TMP]] to i32
// CHECK-NEXT: [[PAYLOAD_TAG:%.*]] = sub i32 [[SPARE_TAG]], 3
// -- Get the low bits of the tag from the payload area
// CHECK-NEXT: [[NO_PAYLOAD_TAG:%.*]] = trunc i64 [[FIRST]] to i32
// -- Check if we have a payload or not
// CHECK-NEXT: [[IS_PAYLOAD:%.*]] = icmp sge i32 [[PAYLOAD_TAG]], 0
// -- Return the tag
// CHECK-NEXT: [[TAG:%.*]] = select i1 [[IS_PAYLOAD]], i32 [[NO_PAYLOAD_TAG]], i32 [[PAYLOAD_TAG]]
// CHECK-NEXT: ret i32 [[TAG]]
// CHECK-LABEL: define linkonce_odr hidden void @_TwupO20enum_value_semantics31MultiPayloadNontrivialSpareBits
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to { i64, i64 }*
// -- Load the payload
// CHECK-NEXT: [[FIRST_ADDR:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[SELF]], i32 0, i32 0
// CHECK-NEXT: [[FIRST:%.*]] = load i64, i64* [[FIRST_ADDR]], align 8
// CHECK-NEXT: [[SECOND_ADDR:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[SELF]], i32 0, i32 1
// CHECK-NEXT: [[SECOND:%.*]] = load i64, i64* [[SECOND_ADDR]], align 8
// -- Strip off spare bits
// CHECK-NEXT: [[SECOND_PROJ:%.*]] = and i64 [[SECOND]], 4611686018427387903
// -- Store the payload
// CHECK-NEXT: [[SELF:%.*]] = bitcast %swift.opaque* %value to { i64, i64 }*
// CHECK-NEXT: [[FIRST_ADDR:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[SELF]], i32 0, i32 0
// CHECK-NEXT: store i64 [[FIRST]], i64* [[FIRST_ADDR]], align 8
// CHECK-NEXT: [[SECOND_ADDR:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[SELF]], i32 0, i32 1
// CHECK-NEXT: store i64 [[SECOND_PROJ]], i64* [[SECOND_ADDR]], align 8
// CHECK-NEXT: ret void
// CHECK-LABEL: define linkonce_odr hidden void @_TwuiO20enum_value_semantics31MultiPayloadNontrivialSpareBits
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics31MultiPayloadNontrivialSpareBits*
// CHECK-NEXT: [[IS_PAYLOAD:%.*]] = icmp sge i32 %tag, 0
// CHECK-NEXT: br i1 [[IS_PAYLOAD]], label %[[HAS_NO_PAYLOAD:.*]], label %[[HAS_PAYLOAD:.*]]
// CHECK: ; <label>:[[HAS_NO_PAYLOAD]]
// -- Turn the case index into a no-payload case index
// CHECK-NEXT: [[NO_PAYLOAD_TAG:%.*]] = zext i32 %tag to i64
// -- Store the low bits of the tag into the payload
// CHECK-NEXT: [[PAYLOAD:%.*]] = bitcast %O20enum_value_semantics31MultiPayloadNontrivialSpareBits* [[SELF]] to { i64, i64 }*
// CHECK-NEXT: [[FIRST_ADDR:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[PAYLOAD]], i32 0, i32 0
// CHECK-NEXT: store i64 [[NO_PAYLOAD_TAG]], i64* [[FIRST_ADDR]], align 8
// -- Store the high bits of the tag into the spare bits
// CHECK-NEXT: [[SECOND_ADDR:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[PAYLOAD]], i32 0, i32 1
// -- 0xc000000000000000
// CHECK-NEXT: store i64 -4611686018427387904, i64* [[SECOND_ADDR]], align 8
// CHECK-NEXT: br label %[[END:.*]]
// CHECK: ; <label>:[[HAS_PAYLOAD]]
// CHECK-NEXT: [[TAG_TMP2:%.*]] = add i32 %tag, 3
// -- Not really necessary
// CHECK-NEXT: [[TAG_TMP:%.*]] = and i32 [[TAG_TMP2]], 3
// -- Load the payload
// CHECK-NEXT: [[PAYLOAD:%.*]] = bitcast %O20enum_value_semantics31MultiPayloadNontrivialSpareBits* [[SELF]] to { i64, i64 }*
// CHECK-NEXT: [[FIRST_ADDR:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[PAYLOAD]], i32 0, i32 0
// CHECK-NEXT: [[FIRST:%.*]] = load i64, i64* [[FIRST_ADDR]], align 8
// CHECK-NEXT: [[SECOND_ADDR:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[PAYLOAD]], i32 0, i32 1
// CHECK-NEXT: [[SECOND:%.*]] = load i64, i64* [[SECOND_ADDR]], align 8
// -- Mask off spare bits in the payload -- 0x3fffffffffffffff
// CHECK-NEXT: [[SECOND_PROJ:%.*]] = and i64 [[SECOND]], 4611686018427387903
// -- Store the low bits of the tag in the spare bits of the payload
// CHECK-NEXT: [[TAG:%.*]] = zext i32 [[TAG_TMP]] to i64
// CHECK-NEXT: [[SPARE_TAG_TMP2:%.*]] = shl i64 [[TAG]], 62
// -- Not really necessary -- 0xc000000000000000
// CHECK-NEXT: [[SPARE_TAG_TMP:%.*]] = and i64 [[SPARE_TAG_TMP2]], -4611686018427387904
// -- Apply the new spare bits
// CHECK-NEXT: [[SECOND_NEW:%.*]] = or i64 [[SECOND_PROJ]], [[SPARE_TAG_TMP]]
// -- Store the payload back
// CHECK-NEXT: [[PAYLOAD:%.*]] = bitcast %O20enum_value_semantics31MultiPayloadNontrivialSpareBits* [[SELF]] to { i64, i64 }*
// CHECK-NEXT: [[FIRST_ADDR:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[PAYLOAD]], i32 0, i32 0
// CHECK-NEXT: store i64 [[FIRST]], i64* [[FIRST_ADDR]], align 8
// CHECK-NEXT: [[SECOND_ADDR:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[PAYLOAD]], i32 0, i32 1
// CHECK-NEXT: store i64 [[SECOND_NEW]], i64* [[SECOND_ADDR]], align 8
// CHECK-NEXT: br label %[[END]]
// CHECK: ; <label>:[[END]]
// CHECK-NEXT: ret void
// CHECK-LABEL: define linkonce_odr hidden i32 @_TwugO20enum_value_semantics33MultiPayloadSpareBitsAndExtraBits
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics33MultiPayloadSpareBitsAndExtraBits*
// -- Load the payload
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %O20enum_value_semantics33MultiPayloadSpareBitsAndExtraBits* [[SELF]] to i64*
// CHECK-NEXT: [[PAYLOAD:%.*]] = load i64, i64* [[PAYLOAD_ADDR]], align 8
// -- Load the load bits of the tag from the extra tag area
// CHECK-NEXT: [[EXTRA_TAG_ADDR_TMP:%.*]] = getelementptr inbounds %O20enum_value_semantics33MultiPayloadSpareBitsAndExtraBits, %O20enum_value_semantics33MultiPayloadSpareBitsAndExtraBits* [[SELF]], i32 0, i32 1
// CHECK-NEXT: [[EXTRA_TAG_ADDR:%.*]] = bitcast [1 x i8]* [[EXTRA_TAG_ADDR_TMP]] to i1*
// CHECK-NEXT: [[EXTRA_TAG_TMP:%.*]] = load i1, i1* [[EXTRA_TAG_ADDR]], align 8
// -- Load the high bits of the tag from the spare bits area
// CHECK-NEXT: [[SPARE_BITS_TMP2:%.*]] = lshr i64 [[PAYLOAD]], 63
// CHECK-NEXT: [[SPARE_BITS_TMP:%.*]] = trunc i64 [[SPARE_BITS_TMP2]] to i2
// CHECK-NEXT: [[SPARE_BITS:%.*]] = and i2 [[SPARE_BITS_TMP]], 1
// CHECK-NEXT: [[EXTRA_TAG:%.*]] = zext i1 [[EXTRA_TAG_TMP]] to i2
// -- Combine high bits and low bits to form tag
// CHECK-NEXT: [[TAG_TMP:%.*]] = shl i2 [[EXTRA_TAG]], 1
// CHECK-NEXT: [[TAG:%.*]] = or i2 [[SPARE_BITS]], [[TAG_TMP]]
// CHECK-NEXT: [[RESULT:%.*]] = zext i2 [[TAG]] to i32
// CHECK-NEXT: [[PAYLOAD_TAG:%.*]] = sub i32 [[RESULT]],
// CHECK-NEXT: ret i32 [[PAYLOAD_TAG]]
// CHECK-LABEL: define linkonce_odr hidden void @_TwupO20enum_value_semantics33MultiPayloadSpareBitsAndExtraBits
// CHECK: [[PAYLOAD_ADDR:%.*]] = bitcast %swift.opaque* %value to i64*
// CHECK-NEXT: [[PAYLOAD:%.*]] = load i64, i64* [[PAYLOAD_ADDR]], align 8
// -- 0x7fffffffffffffff
// CHECK-NEXT: [[PAYLOAD_PROJ:%.*]] = and i64 [[PAYLOAD]], 9223372036854775807
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %swift.opaque* %value to i64*
// CHECK-NEXT: store i64 [[PAYLOAD_PROJ]], i64* [[PAYLOAD_ADDR]], align 8
// CHECK-NEXT: ret void
// CHECK-LABEL: define linkonce_odr hidden void @_TwuiO20enum_value_semantics33MultiPayloadSpareBitsAndExtraBits
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics33MultiPayloadSpareBitsAndExtraBits*
// CHECK-NEXT: [[PAYLOAD_TAG:%.*]] = add i32 %tag, 3
// CHECK-NEXT: [[SPARE_TAG_TMP3:%.*]] = and i32 [[PAYLOAD_TAG]], 1
// -- Load the payload
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %O20enum_value_semantics33MultiPayloadSpareBitsAndExtraBits* %0 to i64*
// CHECK-NEXT: [[PAYLOAD:%.*]] = load i64, i64* [[PAYLOAD_ADDR]], align 8
// -- Mask off the spare bits
// -- 0x7fffffffffffffff
// CHECK-NEXT: [[PAYLOAD_PROJ:%.*]] = and i64 [[PAYLOAD]], 9223372036854775807
// -- Store low bits of tag in spare bits area
// CHECK-NEXT: [[SPARE_TAG_TMP2:%.*]] = zext i32 [[SPARE_TAG_TMP3]] to i64
// CHECK-NEXT: [[SPARE_TAG_TMP:%.*]] = shl i64 [[SPARE_TAG_TMP2]], 63
// -- 0x8000000000000000
// CHECK-NEXT: [[SPARE_TAG:%.*]] = and i64 [[SPARE_TAG_TMP:%.*]], -9223372036854775808
// CHECK-NEXT: [[PAYLOAD_NEW:%.*]] = or i64 [[PAYLOAD_PROJ]], [[SPARE_TAG]]
// -- Store the payload
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %O20enum_value_semantics33MultiPayloadSpareBitsAndExtraBits* %0 to i64*
// CHECK-NEXT: store i64 [[PAYLOAD_NEW]], i64* [[PAYLOAD_ADDR]], align 8
// -- Store high bits of tag in extra tag area
// CHECK-NEXT: [[EXTRA_TAG_TMP:%.*]] = lshr i32 [[PAYLOAD_TAG]], 1
// CHECK-NEXT: [[EXTRA_TAG:%.*]] = trunc i32 [[EXTRA_TAG_TMP]] to i1
// CHECK-NEXT: [[EXTRA_TAG_ADDR_TMP:%.*]] = getelementptr inbounds %O20enum_value_semantics33MultiPayloadSpareBitsAndExtraBits, %O20enum_value_semantics33MultiPayloadSpareBitsAndExtraBits* [[SELF]], i32 0, i32 1
// CHECK-NEXT: [[EXTRA_TAG_ADDR:%.*]] = bitcast [1 x i8]* [[EXTRA_TAG_ADDR_TMP]] to i1*
// CHECK-NEXT: store i1 [[EXTRA_TAG]], i1* [[EXTRA_TAG_ADDR]], align 8
// CHECK-NEXT: ret void