Skip to content

Commit 36f6d30

Browse files
authored
Merge pull request #74014 from Azoy/60-fix-invertible-abi
[6.0] [IRGen] Fix misalignment of conditional invertible requirement counts
2 parents 6348cfd + 5cb1779 commit 36f6d30

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

include/swift/ABI/GenericContext.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/ABI/MetadataRef.h"
2424
#include "swift/ABI/InvertibleProtocols.h"
2525
#include "swift/ABI/TrailingObjects.h"
26+
#include "swift/Basic/MathUtils.h"
2627
#include "swift/Demangling/Demangle.h"
2728

2829
namespace swift {
@@ -696,7 +697,7 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
696697
if (!asSelf()->hasConditionalInvertedProtocols())
697698
return 0;
698699

699-
return countBitsUsed(getConditionalInvertedProtocols().rawBits());
700+
return popcount(getConditionalInvertedProtocols().rawBits());
700701
}
701702

702703
size_t numTrailingObjects(

include/swift/Basic/MathUtils.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,13 @@
1717
#ifndef SWIFT_BASIC_MATH_UTILS_H
1818
#define SWIFT_BASIC_MATH_UTILS_H
1919

20+
#include "Compiler.h"
2021
#include <cstddef>
22+
#include <cstdint>
23+
24+
#if SWIFT_COMPILER_IS_MSVC
25+
#include <intrin.h>
26+
#endif
2127

2228
namespace swift {
2329

@@ -33,6 +39,21 @@ static inline size_t roundUpToAlignMask(size_t size, size_t alignMask) {
3339
return (size + alignMask) & ~alignMask;
3440
}
3541

42+
static inline unsigned popcount(unsigned value) {
43+
#if SWIFT_COMPILER_IS_MSVC && (defined(_M_IX86) || defined(_M_X64))
44+
// The __popcnt intrinsic is only available when targetting x86{_64} with MSVC.
45+
return __popcnt(value);
46+
#elif __has_builtin(__builtin_popcount)
47+
return __builtin_popcount(value);
48+
#else
49+
// From llvm/ADT/bit.h which the runtime doesn't have access to (yet?)
50+
uint32_t v = value;
51+
v = v - ((v >> 1) & 0x55555555);
52+
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
53+
return int(((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24);
54+
#endif
55+
}
56+
3657
} // namespace swift
3758

3859
#endif // #ifndef SWIFT_BASIC_MATH_UTILS_H

lib/IRGen/GenMeta.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,6 +1334,13 @@ namespace {
13341334
B.addPlaceholderWithSize(IGM.Int16Ty));
13351335
}
13361336

1337+
// The conditional invertible protocol set is alone as a 16 bit slot, so
1338+
// an even amount of conditional invertible protocols will cause an uneven
1339+
// alignment.
1340+
if ((numProtocols & 1) == 0) {
1341+
B.addInt16(0);
1342+
}
1343+
13371344
// Emit the generic requirements for the conditional conformance
13381345
// to each invertible protocol.
13391346
auto nominal = cast<NominalTypeDecl>(Type);

0 commit comments

Comments
 (0)