Skip to content

Commit 759a05e

Browse files
committed
Prevent FunctionSignatureOpts to explode arguments if its type only has a single field.
This could happen in case the argument type is an enum and if one of the enum payloads has multiple non-trivial fields and only one of the values is released before the return.
1 parent 361ab62 commit 759a05e

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

include/swift/SILOptimizer/Utils/FunctionSignatureOptUtils.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ struct ArgumentDescriptor {
104104
if (!canOptimizeLiveArg())
105105
return false;
106106

107+
// See if the projection tree consists of potentially multiple levels of
108+
// structs containing one field. In such a case, there is no point in
109+
// exploding the argument.
110+
if (ProjTree.isSingleton())
111+
return false;
112+
107113
// If this argument is @owned and we can not find all the releases for it
108114
// try to explode it, maybe we can find some of the releases and O2G some
109115
// of its components.
@@ -114,12 +120,6 @@ struct ArgumentDescriptor {
114120
ERM.hasSomeReleasesForArgument(Arg))
115121
return true;
116122

117-
// See if the projection tree consists of potentially multiple levels of
118-
// structs containing one field. In such a case, there is no point in
119-
// exploding the argument.
120-
if (ProjTree.isSingleton())
121-
return false;
122-
123123
size_t explosionSize = ProjTree.liveLeafCount();
124124
return explosionSize >= 1 && explosionSize <= 3;
125125
}

test/SILOptimizer/functionsigopts.sil

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,6 +1300,32 @@ bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject):
13001300
return %9999 : $()
13011301
}
13021302

1303+
1304+
// CHECK-NEGATIVE-NOT: sil {{.*}}_dont_explode_single_enum
1305+
1306+
sil [noinline] @dont_explode_single_enum : $@convention(thin) (@owned Optional<(foo, foo)>) -> @owned foo {
1307+
bb0(%0 : $Optional<(foo, foo)>):
1308+
%281 = unchecked_enum_data %0 : $Optional<(foo, foo)>, #Optional.some!enumelt.1
1309+
%282 = tuple_extract %281 : $(foo, foo), 0
1310+
%283 = tuple_extract %281 : $(foo, foo), 1
1311+
strong_release %283 : $foo
1312+
return %282 : $foo
1313+
}
1314+
1315+
1316+
1317+
// CHECK-LABEL: sil @call_with_single_enum
1318+
// CHECK: [[F:%[0-9]+]] = function_ref @dont_explode_single_enum : $@convention(thin) (@owned Optional<(foo, foo)>) -> @owned foo
1319+
// CHECK: apply [[F]](%0)
1320+
// CHECK: return
1321+
sil @call_with_single_enum : $@convention(thin) (@owned Optional<(foo, foo)>) -> @owned foo {
1322+
bb0(%0 : $Optional<(foo, foo)>):
1323+
%f = function_ref @dont_explode_single_enum : $@convention(thin) (@owned Optional<(foo, foo)>) -> @owned foo
1324+
%a = apply %f(%0) : $@convention(thin) (@owned Optional<(foo, foo)>) -> @owned foo
1325+
return %a : $foo
1326+
}
1327+
1328+
13031329
// We should remove the array semantic from specialized calls.
13041330

13051331
// CHECK-LABEL: sil [fragile] [thunk] [always_inline] [_semantics "array.foobar"] @array_semantic : $@convention(method) (@owned Builtin.NativeObject) -> () {

0 commit comments

Comments
 (0)