Skip to content

Commit 6f5b4f0

Browse files
committed
[IRGen] Use at least Int8 for extra tag bits
rdar://149985633 Using at least Int8 here allows LLVM to apply more optimizations, reducing code size, avoiding stack allocations and as a result often eliminating complete stack frames.
1 parent 1bff8cd commit 6f5b4f0

17 files changed

+140
-96
lines changed

lib/IRGen/GenEnum.cpp

+5-7
Original file line numberDiff line numberDiff line change
@@ -1430,10 +1430,7 @@ namespace {
14301430
// types other than i1 or power-of-two-byte sizes like i8, i16, etc. inhibit
14311431
// FastISel and expose backend bugs.
14321432
static unsigned getIntegerBitSizeForTag(unsigned tagBits) {
1433-
// i1 is used to represent bool in C so is fairly well supported.
1434-
if (tagBits == 1)
1435-
return 1;
1436-
// Otherwise, round the physical size in bytes up to the next power of two.
1433+
// Round the physical size in bytes up to the next power of two.
14371434
unsigned tagBytes = (tagBits + 7U)/8U;
14381435
if (!llvm::isPowerOf2_32(tagBytes))
14391436
tagBytes = llvm::NextPowerOf2(tagBytes);
@@ -2223,7 +2220,7 @@ namespace {
22232220
if (tagBits) {
22242221
if (ExtraTagBitCount == 1) {
22252222
if (extraTag == 1)
2226-
tagResult = tagBits;
2223+
tagResult = IGF.Builder.CreateTrunc(tagBits, IGF.IGM.Int1Ty);
22272224
else
22282225
tagResult = IGF.Builder.CreateNot(tagBits);
22292226
} else {
@@ -2311,7 +2308,8 @@ namespace {
23112308
oneDest = llvm::BasicBlock::Create(C);
23122309
tagBitBlocks.push_back(oneDest);
23132310
}
2314-
IGF.Builder.CreateCondBr(tagBits, oneDest, zeroDest);
2311+
auto isOne = IGF.Builder.CreateTrunc(tagBits, IGF.IGM.Int1Ty);
2312+
IGF.Builder.CreateCondBr(isOne, oneDest, zeroDest);
23152313
} else {
23162314
auto swi = SwitchBuilder::create(IGF, tagBits,
23172315
SwitchDefaultDest(unreachableBB, IsUnreachable),
@@ -2589,7 +2587,7 @@ namespace {
25892587
assert(extraBits);
25902588
llvm::Value *isNonzero;
25912589
if (ExtraTagBitCount == 1) {
2592-
isNonzero = extraBits;
2590+
isNonzero = IGF.Builder.CreateTrunc(extraBits, IGF.IGM.Int1Ty);
25932591
} else {
25942592
llvm::Value *zero = llvm::ConstantInt::get(extraBits->getType(), 0);
25952593
isNonzero = IGF.Builder.CreateICmp(llvm::CmpInst::ICMP_NE,

test/IRGen/alignment.sil

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ entry:
5757
store %w to %d : $*NoPayload
5858

5959
// CHECK: load i32{{.*}}, align 16
60-
// CHECK: load i1{{.*}}, align 4
60+
// CHECK: load i8{{.*}}, align 4
6161
%v = load %e : $*SinglePayload
6262
// CHECK: store i32{{.*}}, align 16
63-
// CHECK: store i1{{.*}}, align 4
63+
// CHECK: store i8{{.*}}, align 4
6464
store %v to %e : $*SinglePayload
6565

6666
// CHECK: load i32{{.*}}, align 16

test/IRGen/bitcast.sil

+3-5
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,9 @@ entry(%c : $C):
4040

4141
// CHECK-x86_64-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { i64, i8 } @bitcast_trivial_optional(i64 %0, i8 %1) {{.*}} {
4242
// CHECK-x86_64-NEXT: entry:
43-
// CHECK-x86_64-NEXT: %2 = trunc i8 %1 to i1
44-
// CHECK-x86_64-NEXT: %3 = zext i1 %2 to i8
45-
// CHECK-x86_64-NEXT: %4 = insertvalue { i64, i8 } undef, i64 %0, 0
46-
// CHECK-x86_64-NEXT: %5 = insertvalue { i64, i8 } %4, i8 %3, 1
47-
// CHECK-x86_64-NEXT: ret { i64, i8 } %5
43+
// CHECK-x86_64-NEXT: %2 = insertvalue { i64, i8 } undef, i64 %0, 0
44+
// CHECK-x86_64-NEXT: %3 = insertvalue { i64, i8 } %2, i8 %1, 1
45+
// CHECK-x86_64-NEXT: ret { i64, i8 } %3
4846

4947
sil @bitcast_trivial_optional: $@convention(thin) (Optional<Int>) -> Optional<Int> {
5048
entry(%c : $Optional<Int>):

test/IRGen/enum.sil

+16-15
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,8 @@ enum SinglePayloadNoXI2 {
470470
// CHECK-32: define{{( dllexport)?}}{{( protected)?}} swiftcc i1 @select_enum([[WORD:i32]] %0, i8 %1)
471471
// CHECK-64: define{{( dllexport)?}}{{( protected)?}} swiftcc i1 @select_enum([[WORD:i64]] %0, i8 %1)
472472
// CHECK: entry:
473-
// CHECK: [[TAG:%.*]] = trunc i8 %1 to i1
474473
// CHECK: [[PAYLOAD:%.*]] = icmp eq [[WORD]] %0, 1
474+
// CHECK: [[TAG:%.*]] = trunc i8 %1 to i1
475475
// CHECK: [[MATCHES:%.*]] = and i1 [[TAG]], [[PAYLOAD]]
476476
// CHECK: [[RES:%.*]] = select i1 [[MATCHES]], i1 false, i1 true
477477
// CHECK: ret i1 [[RES]]
@@ -633,7 +633,7 @@ entry(%0 : $Builtin.Word):
633633
// CHECK: entry:
634634
// CHECK: store [[WORD]] %0, ptr %1
635635
// CHECK: [[T0:%.*]] = getelementptr inbounds %T4enum18SinglePayloadNoXI2O, ptr %1, i32 0, i32 1
636-
// CHECK: store i1 false, ptr [[T0]]
636+
// CHECK: store i8 0, ptr [[T0]]
637637
// CHECK: ret void
638638
// CHECK: }
639639
sil @single_payload_no_xi_inject_x_indirect : $(Builtin.Word, @inout SinglePayloadNoXI2) -> () {
@@ -659,7 +659,7 @@ entry:
659659
// CHECK: entry:
660660
// CHECK: store [[WORD]] 0, ptr %0
661661
// CHECK: [[T0:%.*]] = getelementptr inbounds %T4enum18SinglePayloadNoXI2O, ptr %0, i32 0, i32 1
662-
// CHECK: store i1 true, ptr [[T0]]
662+
// CHECK: store i8 1, ptr [[T0]]
663663
// CHECK: ret void
664664
// CHECK: }
665665
sil @single_payload_no_xi_inject_y_indirect : $(@inout SinglePayloadNoXI2) -> () {
@@ -1593,12 +1593,10 @@ enum MultiPayloadOneSpareBit {
15931593
// CHECK-64: define{{( dllexport)?}}{{( protected)?}} swiftcc void @multi_payload_one_spare_bit_switch(i64 %0, i8 %1) {{.*}} {
15941594
sil @multi_payload_one_spare_bit_switch : $(MultiPayloadOneSpareBit) -> () {
15951595
entry(%u : $MultiPayloadOneSpareBit):
1596-
// CHECK-64: [[NATIVECC_TRUNC:%.*]] = trunc i8 %1 to i1
15971596
// CHECK-64: [[SPARE_TAG_LSHR:%.*]] = lshr i64 %0, 63
15981597
// CHECK-64: [[SPARE_TAG_TRUNC:%.*]] = trunc i64 [[SPARE_TAG_LSHR]] to i8
15991598
// CHECK-64: [[SPARE_TAG:%.*]] = and i8 [[SPARE_TAG_TRUNC]], 1
1600-
// CHECK-64: [[EXTRA_TAG_ZEXT:%.*]] = zext i1 [[NATIVECC_TRUNC]] to i8
1601-
// CHECK-64: [[EXTRA_TAG:%.*]] = shl i8 [[EXTRA_TAG_ZEXT]], 1
1599+
// CHECK-64: [[EXTRA_TAG:%.*]] = shl i8 %1, 1
16021600
// CHECK-64: [[TAG:%.*]] = or i8 [[SPARE_TAG]], [[EXTRA_TAG]]
16031601
// CHECK-64: switch i8 [[TAG]], label %[[UNREACHABLE:[0-9]+]] [
16041602
// CHECK-64: i8 0, label %[[X_PREDEST:[0-9]+]]
@@ -1681,7 +1679,7 @@ sil @multi_payload_one_spare_bit_switch_indirect : $(@inout MultiPayloadOneSpare
16811679
entry(%u : $*MultiPayloadOneSpareBit):
16821680
// CHECK-64: [[PAYLOAD:%.*]] = load i64, ptr %0
16831681
// CHECK-64: [[T0:%.*]] = getelementptr inbounds %T4enum23MultiPayloadOneSpareBitO, ptr %0, i32 0, i32 1
1684-
// CHECK-64: [[TAG:%.*]] = load i1, ptr [[T0]]
1682+
// CHECK-64: [[TAG:%.*]] = load i8, ptr [[T0]]
16851683
// CHECK-64: switch i8 {{%.*}}
16861684
// CHECK-64: switch i64 [[PAYLOAD]]
16871685
// CHECK-64: {{[0-9]+}}:
@@ -1748,7 +1746,7 @@ entry(%0 : $Builtin.Int62):
17481746
// CHECK-64: [[PAYLOAD_MASKED:%.*]] = and i64 [[PAYLOAD]], 9223372036854775807
17491747
// CHECK-64: store i64 [[PAYLOAD_MASKED]], ptr %1
17501748
// CHECK-64: [[T0:%.*]] = getelementptr inbounds %T4enum23MultiPayloadOneSpareBitO, ptr %1, i32 0, i32 1
1751-
// CHECK-64: store i1 false, ptr [[T0]]
1749+
// CHECK-64: store i8 0, ptr [[T0]]
17521750
// CHECK-64: ret void
17531751
// CHECK-64: }
17541752
sil @multi_payload_one_spare_bit_inject_x_indirect : $(Builtin.Int62, @inout MultiPayloadOneSpareBit) -> () {
@@ -1788,7 +1786,7 @@ entry(%0 : $Builtin.Int63):
17881786
// CHECK-64: [[PAYLOAD_TAGGED:%.*]] = or i64 [[PAYLOAD_MASKED]], -9223372036854775808
17891787
// CHECK-64: store i64 [[PAYLOAD_TAGGED]], ptr %1
17901788
// CHECK-64: [[T0:%.*]] = getelementptr inbounds %T4enum23MultiPayloadOneSpareBitO, ptr %1, i32 0, i32 1
1791-
// CHECK-64: store i1 false, ptr [[T0]]
1789+
// CHECK-64: store i8 0, ptr [[T0]]
17921790
// CHECK-64: ret void
17931791
// CHECK-64: }
17941792

@@ -1831,7 +1829,7 @@ entry:
18311829
// -- 0x8000_0000_0000_0000
18321830
// CHECK-64: store i64 -9223372036854775808, ptr %0
18331831
// CHECK-64: [[T0:%.*]] = getelementptr inbounds %T4enum23MultiPayloadOneSpareBitO, ptr %0, i32 0, i32 1
1834-
// CHECK-64: store i1 true, ptr [[T0]]
1832+
// CHECK-64: store i8 1, ptr [[T0]]
18351833
// CHECK-64: ret void
18361834
// CHECK-64: }
18371835
sil @multi_payload_one_spare_bit_inject_a_indirect : $(@inout MultiPayloadOneSpareBit) -> () {
@@ -2227,8 +2225,9 @@ enum MultiPayloadNested {
22272225
// CHECK: %3 = getelementptr
22282226
// CHECK: %4 = load i8, ptr %3
22292227
// CHECK: %5 = lshr i8 %4, 7
2230-
// CHECK: %6 = trunc i8 %5 to i1
2231-
// CHECK: br i1 %6
2228+
// CHECK: %6 = and i8 %5, 1
2229+
// CHECK: %7 = icmp ne i8 %6, 1
2230+
// CHECK: br i1 %7
22322231
sil @multi_payload_nested_switch : $(@in MultiPayloadNested) -> () {
22332232
entry(%c : $*MultiPayloadNested):
22342233
switch_enum_addr %c : $*MultiPayloadNested, case #MultiPayloadNested.A!enumelt: a_dest, case #MultiPayloadNested.B!enumelt: b_dest
@@ -2259,8 +2258,10 @@ enum MultiPayloadNestedSpareBits {
22592258
// CHECK-64: entry:
22602259
// CHECK-64: %1 = load [[WORD]], ptr %0
22612260
// CHECK-64: %2 = lshr [[WORD]] %1, 61
2262-
// CHECK-64: %3 = trunc [[WORD]] %2 to i1
2263-
// CHECK-64: br i1 %3
2261+
// CHECK-64: %3 = trunc [[WORD]] %2 to i8
2262+
// CHECK-64: %4 = and i8 %3, 1
2263+
// CHECK-64: %5 = icmp ne i8 %4, 1
2264+
// CHECK-64: br i1 %5
22642265
sil @multi_payload_nested_spare_bits_switch : $(@in MultiPayloadNestedSpareBits) -> () {
22652266
entry(%c : $*MultiPayloadNestedSpareBits):
22662267
switch_enum_addr %c : $*MultiPayloadNestedSpareBits, case #MultiPayloadNestedSpareBits.A!enumelt: a_dest, case #MultiPayloadNestedSpareBits.B!enumelt: b_dest
@@ -2459,7 +2460,7 @@ entry(%x : $Int32):
24592460
// CHECK-64: [[INT_ZEXT:%.*]] = zext i32 %0 to i64
24602461
// CHECK-64: [[INT_SHL:%.*]] = shl i64 [[INT_ZEXT]], 32
24612462
%d = enum $Optional<(Optional<()>, Int32)>, #Optional.some!enumelt, %c : $(Optional<()>, Int32)
2462-
// CHECK-64: [[BIT:%.*]] = trunc i64 [[INT_SHL]] to i1
2463+
// CHECK-64: [[BIT:%.*]] = trunc i64 [[INT_SHL]] to i8
24632464
// CHECK-64: [[INT_SHR:%.*]] = lshr i64 [[INT_SHL]], 32
24642465
// CHECK-64: [[INT:%.*]] = trunc i64 [[INT_SHR]] to i32
24652466
%e = unchecked_enum_data %d : $Optional<(Optional<()>, Int32)>, #Optional.some!enumelt

test/IRGen/enum_copy_init_with_take_memcpy.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ struct HasAnEnum {
3030
// CHECK: define {{.*}} swiftcc range(i64 -1, 5) i64 @"$s31enum_copy_init_with_take_memcpy9HasAnEnumV9readValueSiyF"(ptr {{.*}} %0)
3131
// CHECK: [[T0:%.*]] = getelementptr inbounds i8, ptr %0, i64 160
3232
// CHECK: [[T1:%.*]] = load i8, ptr [[T0]]
33-
// CHECK: [[T2:%.*]] = icmp eq i8 [[T1]], 2
34-
// CHECK: br i1 [[T2]], label
35-
// CHECK: [[R:%.*]] = phi i64 [ -1, {{.*}} ], [ 4, {{.*}} ]
33+
// CHECK: [[T2:%.*]] = and i8 [[T1]], -3
34+
// CHECK: [[T3:%.*]] = icmp eq i8 [[T2]], 0
35+
// CHECK: [[R:%.*]] = select i1 [[T3]], i64 -1, i64 4
3636
// CHECK: ret i64 [[R]]
3737

3838
}

test/IRGen/enum_dynamic_multi_payload.sil

+4-4
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,21 @@ entry(%e : $Either<(), ()>):
4040
fix_lifetime %e : $Either<(), ()>
4141

4242
// CHECK-NEXT: alloca
43-
// CHECK-NEXT: trunc i8 {{.*}} to i1
4443
// CHECK-NEXT: llvm.lifetime.start
4544
%s = alloc_stack $Either<(), ()>
4645

4746
%l = enum $Either<(), ()>, #Either.Left!enumelt, undef : $()
48-
// CHECK-NEXT: store i1 false
47+
// CHECK-NEXT: store i8 0
4948
store %l to %s : $*Either<(), ()>
5049
%r = enum $Either<(), ()>, #Either.Right!enumelt, undef : $()
51-
// CHECK-NEXT: store i1 true
50+
// CHECK-NEXT: store i8 1
51+
// CHECK-NEXT: [[COND:%.*]] = icmp ne i8 {{%.*}}, 1
5252
store %r to %s : $*Either<(), ()>
5353

5454
%a = unchecked_enum_data %l : $Either<(), ()>, #Either.Left!enumelt
5555
%b = unchecked_enum_data %r : $Either<(), ()>, #Either.Right!enumelt
5656

57-
// CHECK-NEXT: br i1 {{%.*}}, label %[[RIGHT_PRE:[0-9]+]], label %[[LEFT_PRE:[0-9]+]]
57+
// CHECK-NEXT: br i1 [[COND]], label %[[LEFT_PRE:[0-9]+]], label %[[RIGHT_PRE:[0-9]+]]
5858
// CHECK: [[LEFT_PRE]]:
5959
// CHECK: br label [[LEFT:%[0-9]+]]
6060
// CHECK: [[RIGHT_PRE]]:

test/IRGen/enum_future.sil

+16-15
Original file line numberDiff line numberDiff line change
@@ -474,8 +474,8 @@ enum SinglePayloadNoXI2 {
474474
// CHECK-32: define{{( dllexport)?}}{{( protected)?}} swiftcc i1 @select_enum([[WORD:i32]] %0, i8 %1)
475475
// CHECK-64: define{{( dllexport)?}}{{( protected)?}} swiftcc i1 @select_enum([[WORD:i64]] %0, i8 %1)
476476
// CHECK: entry:
477-
// CHECK: [[TAG:%.*]] = trunc i8 %1 to i1
478477
// CHECK: [[PAYLOAD:%.*]] = icmp eq [[WORD]] %0, 1
478+
// CHECK: [[TAG:%.*]] = trunc i8 %1 to i1
479479
// CHECK: [[MATCHES:%.*]] = and i1 [[TAG]], [[PAYLOAD]]
480480
// CHECK: [[RES:%.*]] = select i1 [[MATCHES]], i1 false, i1 true
481481
// CHECK: ret i1 [[RES]]
@@ -637,7 +637,7 @@ entry(%0 : $Builtin.Word):
637637
// CHECK: entry:
638638
// CHECK: store [[WORD]] %0, ptr %1
639639
// CHECK: [[T0:%.*]] = getelementptr inbounds %T11enum_future18SinglePayloadNoXI2O, ptr %1, i32 0, i32 1
640-
// CHECK: store i1 false, ptr [[T0]]
640+
// CHECK: store i8 0, ptr [[T0]]
641641
// CHECK: ret void
642642
// CHECK: }
643643
sil @single_payload_no_xi_inject_x_indirect : $(Builtin.Word, @inout SinglePayloadNoXI2) -> () {
@@ -663,7 +663,7 @@ entry:
663663
// CHECK: entry:
664664
// CHECK: store [[WORD]] 0, ptr %0
665665
// CHECK: [[T0:%.*]] = getelementptr inbounds %T11enum_future18SinglePayloadNoXI2O, ptr %0, i32 0, i32 1
666-
// CHECK: store i1 true, ptr [[T0]]
666+
// CHECK: store i8 1, ptr [[T0]]
667667
// CHECK: ret void
668668
// CHECK: }
669669
sil @single_payload_no_xi_inject_y_indirect : $(@inout SinglePayloadNoXI2) -> () {
@@ -1597,12 +1597,10 @@ enum MultiPayloadOneSpareBit {
15971597
// CHECK-64: define{{( dllexport)?}}{{( protected)?}} swiftcc void @multi_payload_one_spare_bit_switch(i64 %0, i8 %1) {{.*}} {
15981598
sil @multi_payload_one_spare_bit_switch : $(MultiPayloadOneSpareBit) -> () {
15991599
entry(%u : $MultiPayloadOneSpareBit):
1600-
// CHECK-64: [[NATIVECC_TRUNC:%.*]] = trunc i8 %1 to i1
16011600
// CHECK-64: [[SPARE_TAG_LSHR:%.*]] = lshr i64 %0, 63
16021601
// CHECK-64: [[SPARE_TAG_TRUNC:%.*]] = trunc i64 [[SPARE_TAG_LSHR]] to i8
16031602
// CHECK-64: [[SPARE_TAG:%.*]] = and i8 [[SPARE_TAG_TRUNC]], 1
1604-
// CHECK-64: [[EXTRA_TAG_ZEXT:%.*]] = zext i1 [[NATIVECC_TRUNC]] to i8
1605-
// CHECK-64: [[EXTRA_TAG:%.*]] = shl i8 [[EXTRA_TAG_ZEXT]], 1
1603+
// CHECK-64: [[EXTRA_TAG:%.*]] = shl i8 %1, 1
16061604
// CHECK-64: [[TAG:%.*]] = or i8 [[SPARE_TAG]], [[EXTRA_TAG]]
16071605
// CHECK-64: switch i8 [[TAG]], label %[[UNREACHABLE:[0-9]+]] [
16081606
// CHECK-64: i8 0, label %[[X_PREDEST:[0-9]+]]
@@ -1685,7 +1683,7 @@ sil @multi_payload_one_spare_bit_switch_indirect : $(@inout MultiPayloadOneSpare
16851683
entry(%u : $*MultiPayloadOneSpareBit):
16861684
// CHECK-64: [[PAYLOAD:%.*]] = load i64, ptr %0
16871685
// CHECK-64: [[T0:%.*]] = getelementptr inbounds %T11enum_future23MultiPayloadOneSpareBitO, ptr %0, i32 0, i32 1
1688-
// CHECK-64: [[TAG:%.*]] = load i1, ptr [[T0]]
1686+
// CHECK-64: [[TAG:%.*]] = load i8, ptr [[T0]]
16891687
// CHECK-64: switch i8 {{%.*}}
16901688
// CHECK-64: switch i64 [[PAYLOAD]]
16911689
// CHECK-64: {{[0-9]+}}:
@@ -1752,7 +1750,7 @@ entry(%0 : $Builtin.Int62):
17521750
// CHECK-64: [[PAYLOAD_MASKED:%.*]] = and i64 [[PAYLOAD]], 9223372036854775807
17531751
// CHECK-64: store i64 [[PAYLOAD_MASKED]], ptr %1
17541752
// CHECK-64: [[T0:%.*]] = getelementptr inbounds %T11enum_future23MultiPayloadOneSpareBitO, ptr %1, i32 0, i32 1
1755-
// CHECK-64: store i1 false, ptr [[T0]]
1753+
// CHECK-64: store i8 0, ptr [[T0]]
17561754
// CHECK-64: ret void
17571755
// CHECK-64: }
17581756
sil @multi_payload_one_spare_bit_inject_x_indirect : $(Builtin.Int62, @inout MultiPayloadOneSpareBit) -> () {
@@ -1792,7 +1790,7 @@ entry(%0 : $Builtin.Int63):
17921790
// CHECK-64: [[PAYLOAD_TAGGED:%.*]] = or i64 [[PAYLOAD_MASKED]], -9223372036854775808
17931791
// CHECK-64: store i64 [[PAYLOAD_TAGGED]], ptr %1
17941792
// CHECK-64: [[T0:%.*]] = getelementptr inbounds %T11enum_future23MultiPayloadOneSpareBitO, ptr %1, i32 0, i32 1
1795-
// CHECK-64: store i1 false, ptr [[T0]]
1793+
// CHECK-64: store i8 0, ptr [[T0]]
17961794
// CHECK-64: ret void
17971795
// CHECK-64: }
17981796

@@ -1835,7 +1833,7 @@ entry:
18351833
// -- 0x8000_0000_0000_0000
18361834
// CHECK-64: store i64 -9223372036854775808, ptr %0
18371835
// CHECK-64: [[T0:%.*]] = getelementptr inbounds %T11enum_future23MultiPayloadOneSpareBitO, ptr %0, i32 0, i32 1
1838-
// CHECK-64: store i1 true, ptr [[T0]]
1836+
// CHECK-64: store i8 1, ptr [[T0]]
18391837
// CHECK-64: ret void
18401838
// CHECK-64: }
18411839
sil @multi_payload_one_spare_bit_inject_a_indirect : $(@inout MultiPayloadOneSpareBit) -> () {
@@ -2231,8 +2229,9 @@ enum MultiPayloadNested {
22312229
// CHECK: %3 = getelementptr
22322230
// CHECK: %4 = load i8, ptr %3
22332231
// CHECK: %5 = lshr i8 %4, 7
2234-
// CHECK: %6 = trunc i8 %5 to i1
2235-
// CHECK: br i1 %6
2232+
// CHECK: %6 = and i8 %5, 1
2233+
// CHECK: %7 = icmp ne i8 %6, 1
2234+
// CHECK: br i1 %7
22362235
sil @multi_payload_nested_switch : $(@in MultiPayloadNested) -> () {
22372236
entry(%c : $*MultiPayloadNested):
22382237
switch_enum_addr %c : $*MultiPayloadNested, case #MultiPayloadNested.A!enumelt: a_dest, case #MultiPayloadNested.B!enumelt: b_dest
@@ -2263,8 +2262,10 @@ enum MultiPayloadNestedSpareBits {
22632262
// CHECK-64: entry:
22642263
// CHECK-64: %1 = load [[WORD]], ptr %0
22652264
// CHECK-64: %2 = lshr [[WORD]] %1, 61
2266-
// CHECK-64: %3 = trunc [[WORD]] %2 to i1
2267-
// CHECK-64: br i1 %3
2265+
// CHECK-64: %3 = trunc [[WORD]] %2 to i8
2266+
// CHECK-64: %4 = and i8 %3, 1
2267+
// CHECK-64: %5 = icmp ne i8 %4, 1
2268+
// CHECK-64: br i1 %5
22682269
sil @multi_payload_nested_spare_bits_switch : $(@in MultiPayloadNestedSpareBits) -> () {
22692270
entry(%c : $*MultiPayloadNestedSpareBits):
22702271
switch_enum_addr %c : $*MultiPayloadNestedSpareBits, case #MultiPayloadNestedSpareBits.A!enumelt: a_dest, case #MultiPayloadNestedSpareBits.B!enumelt: b_dest
@@ -2463,7 +2464,7 @@ entry(%x : $Int32):
24632464
// CHECK-64: [[INT_ZEXT:%.*]] = zext i32 %0 to i64
24642465
// CHECK-64: [[INT_SHL:%.*]] = shl i64 [[INT_ZEXT]], 32
24652466
%d = enum $Optional<(Optional<()>, Int32)>, #Optional.some!enumelt, %c : $(Optional<()>, Int32)
2466-
// CHECK-64: [[BIT:%.*]] = trunc i64 [[INT_SHL]] to i1
2467+
// CHECK-64: [[BIT:%.*]] = trunc i64 [[INT_SHL]] to i8
24672468
// CHECK-64: [[INT_SHR:%.*]] = lshr i64 [[INT_SHL]], 32
24682469
// CHECK-64: [[INT:%.*]] = trunc i64 [[INT_SHR]] to i32
24692470
%e = unchecked_enum_data %d : $Optional<(Optional<()>, Int32)>, #Optional.some!enumelt

test/IRGen/enum_value_semantics.sil

+7-8
Original file line numberDiff line numberDiff line change
@@ -357,8 +357,8 @@ bb0(%0 : $SinglePayloadNontrivial):
357357
// -- The payload has no spare bits and there are no empty cases, so the tag
358358
// is entirely contained in the extra tag area
359359
// CHECK-NEXT: [[EXTRA_TAG_ADDR_TMP:%.*]] = getelementptr inbounds %T20enum_value_semantics24MultiPayloadNoEmptyCasesO, ptr %value, i32 0, i32 1
360-
// CHECK-NEXT: [[EXTRA_TAG_TMP:%.*]] = load i1, ptr [[EXTRA_TAG_ADDR_TMP]], align 8
361-
// CHECK-NEXT: [[EXTRA_TAG:%.*]] = zext i1 [[EXTRA_TAG_TMP]] to i32
360+
// CHECK-NEXT: [[EXTRA_TAG_TMP:%.*]] = load i8, ptr [[EXTRA_TAG_ADDR_TMP]], align 8
361+
// CHECK-NEXT: [[EXTRA_TAG:%.*]] = zext i8 [[EXTRA_TAG_TMP]] to i32
362362
// CHECK-NEXT: ret i32 [[EXTRA_TAG]]
363363

364364
// -- MultiPayloadNoEmptyCases destructiveProjectEnumData
@@ -368,11 +368,11 @@ bb0(%0 : $SinglePayloadNontrivial):
368368

369369
// -- MultiPayloadNoEmptyCases destructiveInjectEnumTag
370370
// CHECK-LABEL: define internal void @"$s20enum_value_semantics24MultiPayloadNoEmptyCasesOwui"
371-
// CHECK: [[TAG:%.*]] = trunc i32 %tag to i1
371+
// CHECK: [[TAG:%.*]] = trunc i32 %tag to i8
372372

373373
// -- Store the tag in the extra tag area
374374
// CHECK-NEXT: [[EXTRA_TAG_ADDR_TMP:%.*]] = getelementptr inbounds %T20enum_value_semantics24MultiPayloadNoEmptyCasesO, ptr %value, i32 0, i32 1
375-
// CHECK-NEXT: store i1 [[TAG]], ptr [[EXTRA_TAG_ADDR_TMP]], align 8
375+
// CHECK-NEXT: store i8 [[TAG]], ptr [[EXTRA_TAG_ADDR_TMP]], align 8
376376
// CHECK-NEXT: ret void
377377

378378

@@ -564,13 +564,12 @@ bb0(%0 : $SinglePayloadNontrivial):
564564

565565
// -- Load the load bits of the tag from the extra tag area
566566
// CHECK-NEXT: [[EXTRA_TAG_ADDR_TMP:%.*]] = getelementptr inbounds %T20enum_value_semantics029MultiPayloadSpareBitsAndExtraG0O, ptr %value, i32 0, i32 1
567-
// CHECK-NEXT: [[EXTRA_TAG_TMP:%.*]] = load i1, ptr [[EXTRA_TAG_ADDR_TMP]], align 8
567+
// CHECK-NEXT: [[EXTRA_TAG:%.*]] = load i8, ptr [[EXTRA_TAG_ADDR_TMP]], align 8
568568

569569
// -- Load the high bits of the tag from the spare bits area
570570
// CHECK-NEXT: [[SPARE_BITS_TMP2:%.*]] = lshr i64 [[PAYLOAD]], 63
571571
// CHECK-NEXT: [[SPARE_BITS_TMP:%.*]] = trunc i64 [[SPARE_BITS_TMP2]] to i8
572572
// CHECK-NEXT: [[SPARE_BITS:%.*]] = and i8 [[SPARE_BITS_TMP]], 1
573-
// CHECK-NEXT: [[EXTRA_TAG:%.*]] = zext i1 [[EXTRA_TAG_TMP]] to i8
574573

575574
// -- Combine high bits and low bits to form tag
576575
// CHECK-NEXT: [[TAG_TMP:%.*]] = shl i8 [[EXTRA_TAG]], 1
@@ -609,7 +608,7 @@ bb0(%0 : $SinglePayloadNontrivial):
609608

610609
// -- Store high bits of tag in extra tag area
611610
// CHECK-NEXT: [[EXTRA_TAG_TMP:%.*]] = lshr i32 %tag, 1
612-
// CHECK-NEXT: [[EXTRA_TAG:%.*]] = trunc i32 [[EXTRA_TAG_TMP]] to i1
611+
// CHECK-NEXT: [[EXTRA_TAG:%.*]] = trunc i32 [[EXTRA_TAG_TMP]] to i8
613612
// CHECK-NEXT: [[EXTRA_TAG_ADDR_TMP:%.*]] = getelementptr inbounds %T20enum_value_semantics029MultiPayloadSpareBitsAndExtraG0O, ptr %value, i32 0, i32 1
614-
// CHECK-NEXT: store i1 [[EXTRA_TAG]], ptr [[EXTRA_TAG_ADDR_TMP]], align 8
613+
// CHECK-NEXT: store i8 [[EXTRA_TAG]], ptr [[EXTRA_TAG_ADDR_TMP]], align 8
615614
// CHECK-NEXT: ret void

0 commit comments

Comments
 (0)