Skip to content

Commit e8c3927

Browse files
authored
Merge pull request #31231 from eeckstein/fix-global_addr-5.3
[5.3] SIL: fix memory behavior of global_addr for globals with non-fixed layout.
2 parents 6921723 + 2cbbc36 commit e8c3927

File tree

4 files changed

+64
-0
lines changed

4 files changed

+64
-0
lines changed

lib/SIL/IR/SILInstruction.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,22 @@ SILInstruction::MemoryBehavior SILInstruction::getMemoryBehavior() const {
10021002
}
10031003
}
10041004

1005+
if (auto *ga = dyn_cast<GlobalAddrInst>(this)) {
1006+
// Global variables with resilient types might be allocated into a buffer
1007+
// and not statically in the data segment.
1008+
// In this case, the global_addr depends on alloc_global being executed
1009+
// first. We model this by letting global_addr have a side effect.
1010+
// It prevents e.g. LICM to move a global_addr out of a loop while keeping
1011+
// the alloc_global inside the loop.
1012+
SILModule &M = ga->getFunction()->getModule();
1013+
auto expansion = TypeExpansionContext::maximal(M.getAssociatedContext(),
1014+
M.isWholeModule());
1015+
const TypeLowering &tl =
1016+
M.Types.getTypeLowering(ga->getType().getObjectType(), expansion);
1017+
return tl.isFixedABI() ? MemoryBehavior::None :
1018+
MemoryBehavior::MayHaveSideEffects;
1019+
}
1020+
10051021
switch (getKind()) {
10061022
#define FULL_INST(CLASS, TEXTUALNAME, PARENT, MEMBEHAVIOR, RELEASINGBEHAVIOR) \
10071023
case SILInstructionKind::CLASS: \
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
testit(3)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
public struct Abc {
3+
public var a = 1
4+
public var b = 2
5+
public var c = 3
6+
public var d = 4
7+
8+
public init() { }
9+
10+
public mutating func printit() {
11+
print(a)
12+
}
13+
}
14+
15+
public func unknown() {
16+
}
17+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift %S/Inputs/licm_and_global_addr/test.swift -parse-as-library -wmo -enable-library-evolution -module-name=Test -emit-module -emit-module-path=%t/Test.swiftmodule -c -o %t/test.o
3+
// RUN: %target-build-swift -O %S/Inputs/licm_and_global_addr/main.swift %s -I%t %t/test.o -o %t/a.out
4+
// RUN: %target-run %t/a.out | %FileCheck %s
5+
6+
// REQUIRES: executable_test
7+
8+
import Test
9+
10+
// Check that LICM does not move a global_addr above an alloc_global in case
11+
// the global might be dynamically allocated.
12+
13+
// The type Abc is resilient and > 3 words. So it is allocated dynamically in a buffer.
14+
var a = Abc()
15+
16+
@inline(never)
17+
func testit(_ n: Int) {
18+
for _ in 0..<n {
19+
// Prevent hoisting the initialization of 'a',
20+
// which would defeat the purpose of the test.
21+
unknown()
22+
23+
// CHECK: 1
24+
// CHECK: 1
25+
// CHECK: 1
26+
a.printit()
27+
}
28+
}
29+

0 commit comments

Comments
 (0)