Skip to content

Commit 64e174f

Browse files
authored
Merge pull request #22286 from jckarter/multi-payload-mask-bits-for-extra-inhabitants-5.0
[5.0] IRGen: Mask all spare bits in multi-payload enums when injecting the tag.
2 parents d2f60e6 + 649961e commit 64e174f

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

lib/IRGen/GenEnum.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4785,7 +4785,11 @@ namespace {
47854785
Address payloadAddr = projectPayload(IGF, enumAddr);
47864786
auto payload = EnumPayload::load(IGF, payloadAddr, PayloadSchema);
47874787

4788-
auto spareBitMask = ~PayloadTagBits.asAPInt();
4788+
// We need to mask not only the payload tag bits, but all spare bits,
4789+
// because the other spare bits may be used to tag a single-payload
4790+
// enum containing this enum as a payload. Single payload layout
4791+
// unfortunately assumes that tagging the payload case is a no-op.
4792+
auto spareBitMask = ~CommonSpareBits.asAPInt();
47894793
APInt tagBitMask
47904794
= interleaveSpareBits(IGF.IGM, PayloadTagBits, PayloadTagBits.size(),
47914795
spareTagBits, 0);
@@ -4823,7 +4827,11 @@ namespace {
48234827
auto payload = EnumPayload::load(IGF, payloadAddr, PayloadSchema);
48244828

48254829
// Mask off the spare bits.
4826-
auto spareBitMask = ~PayloadTagBits.asAPInt();
4830+
// We need to mask not only the payload tag bits, but all spare bits,
4831+
// because the other spare bits may be used to tag a single-payload
4832+
// enum containing this enum as a payload. Single payload layout
4833+
// unfortunately assumes that tagging the payload case is a no-op.
4834+
auto spareBitMask = ~CommonSpareBits.asAPInt();
48274835
payload.emitApplyAndMask(IGF, spareBitMask);
48284836

48294837
// Store the tag into the spare bits.

test/IRGen/enum_value_semantics.sil

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -570,8 +570,8 @@ bb0(%0 : $SinglePayloadNontrivial):
570570
// CHECK-NEXT: [[SECOND_ADDR:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[PAYLOAD]], i32 0, i32 1
571571
// CHECK-NEXT: [[SECOND:%.*]] = load i64, i64* [[SECOND_ADDR]], align 8
572572

573-
// -- Mask off spare bits in the payload -- 0x3fffffffffffffff
574-
// CHECK-NEXT: [[SECOND_PROJ:%.*]] = and i64 [[SECOND]], 4611686018427387903
573+
// -- Mask off spare bits in the payload -- 0x00fffffffffffff8
574+
// CHECK-NEXT: [[SECOND_PROJ:%.*]] = and i64 [[SECOND]], 72057594037927928
575575

576576
// -- Store the low bits of the tag in the spare bits of the payload
577577
// CHECK-NEXT: [[TAG:%.*]] = zext i32 [[TAG_TMP]] to i64

0 commit comments

Comments
 (0)