Skip to content

Commit 45d1e95

Browse files
authored
[SILOpt] Fix mutable state in EagerSpecializer (#70083)
* [SILOpt] Fix mutable state in EagerSpecializer rdar://118554892 On the first occurance of a `@_specialize` attribute with `target:` argument, `onlyCreatePrespecializations` would be set to `true`, preventing any subsequent pre-specializations with `exported: false` * Fix test on non-darwin platforms
1 parent d1bb5f6 commit 45d1e95

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

lib/SILOptimizer/Transforms/EagerSpecializer.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,7 @@ SILValue EagerDispatch::emitArgumentConversion(
746746

747747
namespace {
748748
class EagerSpecializerTransform : public SILFunctionTransform {
749-
bool onlyCreatePrespecializations;
749+
const bool onlyCreatePrespecializations;
750750
public:
751751
EagerSpecializerTransform(bool onlyPrespecialize)
752752
: onlyCreatePrespecializations(onlyPrespecialize) {}
@@ -834,6 +834,8 @@ void EagerSpecializerTransform::run() {
834834
// performed.
835835
SmallVector<SILSpecializeAttr *, 8> attrsToRemove;
836836

837+
bool onlyCreatePrespecializations = this->onlyCreatePrespecializations;
838+
837839
for (auto *SA : F.getSpecializeAttrs()) {
838840
if (onlyCreatePrespecializations && !SA->isExported()) {
839841
attrsToRemove.push_back(SA);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -parse-stdlib -O -Xllvm -sil-disable-pass=function-signature-opts -emit-sil %s | %FileCheck %s
3+
4+
// Regression test for rdar://118554892
5+
6+
import Swift
7+
8+
public struct Foo {}
9+
10+
@_specializeExtension
11+
extension Array {
12+
// The `target:` here triggered the bug we are testing for here. So while we don't test this
13+
// specialization itself, it has to remain here for the test to properly function.
14+
@_specialize(exported: true,
15+
target: _endMutation(),
16+
where Element == Foo)
17+
@usableFromInline
18+
mutating func rdar118554892__specialize_class__endMutation(){ Builtin.unreachable() }
19+
}
20+
21+
extension Sequence where Element: StringProtocol {
22+
// CHECK-DAG: sil shared [noinline] @$sST28pre_specialize_rdar118554892Sy7ElementRpzrlE3xxxSSyFSaySSG_Tg5 : $@convention(method) (@guaranteed Array<String>)
23+
// CHECK-DAG: sil shared [noinline] @$sST28pre_specialize_rdar118554892Sy7ElementRpzrlE3xxxSSyFSaySsG_Tg5 : $@convention(method) (@guaranteed Array<Substring>)
24+
@_specialize(where Self == Array<Substring>)
25+
@_specialize(where Self == Array<String>)
26+
@inline(never) // prevent inlining the specialization into the function body
27+
public func xxx() -> String {
28+
return _xxx()
29+
}
30+
31+
@inline(__always)
32+
internal func _xxx() -> String {
33+
var result = ""
34+
for x in self {
35+
result.append(x._ephemeralString)
36+
}
37+
return result
38+
}
39+
}

0 commit comments

Comments
 (0)