Skip to content

Commit 23b721f

Browse files
Merge pull request #76902 from aschwaighofer/payload_enum_prefer_memcpy
IRGen: Prefer memcpy for initWithTake of single/mulipayload enums where possible over an outlined copy function
2 parents c018f3e + 35afefb commit 23b721f

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

lib/IRGen/GenEnum.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3312,6 +3312,14 @@ namespace {
33123312
void initializeWithTake(IRGenFunction &IGF, Address dest, Address src,
33133313
SILType T, bool isOutlined,
33143314
bool zeroizeIfSensitive) const override {
3315+
if (TI->isBitwiseTakable(ResilienceExpansion::Maximal)) {
3316+
IGF.Builder.CreateMemCpy(
3317+
dest.getAddress(), llvm::MaybeAlign(dest.getAlignment().getValue()),
3318+
src.getAddress(), llvm::MaybeAlign(src.getAlignment().getValue()),
3319+
TI->getSize(IGF, T));
3320+
return;
3321+
}
3322+
33153323
if (!ElementsAreABIAccessible) {
33163324
emitInitializeWithTakeCall(IGF, T, dest, src);
33173325
} else if (isOutlined || T.hasParameterizedExistential()) {
@@ -5227,6 +5235,14 @@ namespace {
52275235
void initializeWithTake(IRGenFunction &IGF, Address dest, Address src,
52285236
SILType T, bool isOutlined,
52295237
bool zeroizeIfSensitive) const override {
5238+
if (TI->isBitwiseTakable(ResilienceExpansion::Maximal)) {
5239+
IGF.Builder.CreateMemCpy(
5240+
dest.getAddress(), llvm::MaybeAlign(dest.getAlignment().getValue()),
5241+
src.getAddress(), llvm::MaybeAlign(src.getAlignment().getValue()),
5242+
TI->getSize(IGF, T));
5243+
return;
5244+
}
5245+
52305246
if (!ElementsAreABIAccessible) {
52315247
emitInitializeWithTakeCall(IGF, T, dest, src);
52325248
} else if (isOutlined || T.hasParameterizedExistential()) {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// RUN: %target-swift-frontend -I %t -primary-file %s -O -emit-ir | %FileCheck %s
2+
3+
// REQUIRES: PTRSIZE=64
4+
5+
enum MyEnum {
6+
case one
7+
case four
8+
}
9+
10+
struct HasAnEnum {
11+
var s1: String
12+
var s2: String
13+
var s3: String
14+
var s4: String
15+
var s5: String
16+
var s6: String
17+
var s7: String
18+
var s8: String
19+
var s9: String
20+
var s10: String
21+
var value: MyEnum?
22+
23+
func readValue() -> Int {
24+
let x = value
25+
if case .four = x { return 4 }
26+
return -1
27+
}
28+
29+
30+
// CHECK: define{{.*}} hidden swiftcc i64 @"$s31enum_copy_init_with_take_memcpy9HasAnEnumV9readValueSiyF"(ptr {{.*}} %0)
31+
// CHECK: [[T0:%.*]] = getelementptr inbounds %T31enum_copy_init_with_take_memcpy9HasAnEnumV, ptr %0
32+
// CHECK: [[T1:%.*]] = load i8, ptr [[T0]]
33+
// CHECK: [[T2:%.*]] = and i8 [[T1]], 1
34+
// CHECK: [[T3:%.*]] = icmp eq i8 [[T2]], 0
35+
// CHECK: [[T4:%.*]] = select i1 [[T3]], i64 -1, i64 4
36+
// CHECK: ret i64 [[T4]]
37+
// CHECK: }
38+
39+
}

0 commit comments

Comments
 (0)