Skip to content

Commit 8280527

Browse files
authored
Merge pull request swiftlang#28072 from slavapestov/global-opt-resilience-fix
SILOptimizer: Don't optimize initializers for dynamically-sized globals
2 parents 4d4ee03 + a86f174 commit 8280527

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

lib/IRGen/IRGenSIL.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5640,6 +5640,15 @@ void IRGenModule::emitSILStaticInitializers() {
56405640
if (!InitValue)
56415641
continue;
56425642

5643+
#ifndef NDEBUG
5644+
SILType loweredTy = Global.getLoweredType();
5645+
auto &ti = getTypeInfo(loweredTy);
5646+
5647+
auto expansion = getResilienceExpansionForLayout(&Global);
5648+
assert(ti.isFixedSize(expansion) &&
5649+
"cannot emit a static initializer for dynamically-sized global");
5650+
#endif
5651+
56435652
auto *IRGlobal =
56445653
Module.getGlobalVariable(Global.getName(), true /* = AllowLocal */);
56455654

lib/SILOptimizer/IPO/GlobalOpt.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,14 @@ void SILGlobalOpt::optimizeInitializer(SILFunction *AddrF,
743743
if (!SILG)
744744
return;
745745

746+
auto expansion = ResilienceExpansion::Maximal;
747+
if (hasPublicVisibility(SILG->getLinkage()))
748+
expansion = ResilienceExpansion::Minimal;
749+
750+
auto &tl = Module->Types.getTypeLowering(SILG->getLoweredType(), expansion);
751+
if (!tl.isLoadable())
752+
return;
753+
746754
LLVM_DEBUG(llvm::dbgs() << "GlobalOpt: use static initializer for "
747755
<< SILG->getName() << '\n');
748756

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %target-swift-frontend -emit-sil -O -enable-library-evolution -primary-file %s | %FileCheck %s
2+
// RUN: %target-swift-frontend -emit-sil -O -enable-library-evolution -enable-testing -primary-file %s | %FileCheck %s --check-prefix=CHECK-TESTING
3+
4+
// If a global variable with a resilient type has public linkage, we have to
5+
// allocate a buffer for it even if the type has a fixed size in its
6+
// defining module.
7+
//
8+
// There are two cases where this can occur:
9+
//
10+
// - An internal property is defined in a resilient module built with
11+
// -enable-testing
12+
//
13+
// - A public property is defined to have the @_fixed_layout attribute
14+
15+
public struct Wrapper {
16+
var x: Int32
17+
18+
static let usefulConstant = Wrapper(x: 321)
19+
}
20+
21+
// CHECK-LABEL: sil_global hidden [let] @$s28globalopt_resilience_testing7WrapperV14usefulConstantACvpZ : $Wrapper = {
22+
// CHECK-NEXT: %0 = integer_literal $Builtin.Int32, 321
23+
// CHECK-NEXT: %1 = struct $Int32 (%0 : $Builtin.Int32)
24+
// CHECK-NEXT: %initval = struct $Wrapper (%1 : $Int32)
25+
// CHECK-NEXT: }
26+
27+
// CHECK-TESTING-LABEL: sil_global [let] @$s28globalopt_resilience_testing7WrapperV14usefulConstantACvpZ : $Wrapper{{$}}

0 commit comments

Comments
 (0)