Skip to content

Commit cc1ee7e

Browse files
committed
[ARM] [Windows] Use IMAGE_SYM_CLASS_STATIC for private functions
For functions with private linkage, pick IMAGE_SYM_CLASS_STATIC rather than IMAGE_SYM_CLASS_EXTERNAL; GlobalValue::isInternalLinkage() only checks for InternalLinkage, while GlobalValue::isLocalLinkage() checks for both InternalLinkage and PrivateLinkage. This matches what the AArch64 target does. This activates a preexisting fix for the AArch64 target from 1e7f592, for the ARM target as well. When a relocation points at a symbol, one usually can convey an offset to the symbol by encoding it as an immediate in the instruction. However, for the ARM and AArch64 branch instructions, the immediate stored in the instruction is ignored by MS link.exe (and lld-link matches this aspect). (It would be simple to extend lld-link to support it - but such object files would be incompatible with MS link.exe.) This was worked around by 1e7f592 by emitting symbols into the object file symbol table, for temporary symbols that otherwise would have been omitted, if they have the class IMAGE_SYM_CLASS_STATIC, in order to avoid needing an offset in the relocated instruction. This change gives the symbols generated from functions with the IR level "private" linkage the right class, to activate that workaround. This fixes #100101, fixing code generation for coroutines for Windows on ARM. After the change in f786881, coroutines generate a function with private linkage, and calls to this function were previously broken for this target.
1 parent 4121191 commit cc1ee7e

File tree

3 files changed

+77
-3
lines changed

3 files changed

+77
-3
lines changed

llvm/lib/Target/ARM/ARMAsmPrinter.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,9 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
153153
OptimizationGoals = 0;
154154

155155
if (Subtarget->isTargetCOFF()) {
156-
bool Internal = F.hasInternalLinkage();
157-
COFF::SymbolStorageClass Scl = Internal ? COFF::IMAGE_SYM_CLASS_STATIC
158-
: COFF::IMAGE_SYM_CLASS_EXTERNAL;
156+
bool Local = F.hasLocalLinkage();
157+
COFF::SymbolStorageClass Scl =
158+
Local ? COFF::IMAGE_SYM_CLASS_STATIC : COFF::IMAGE_SYM_CLASS_EXTERNAL;
159159
int Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT;
160160

161161
OutStreamer->beginCOFFSymbolDef(CurrentFnSym);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
; RUN: llc -mtriple thumbv7-windows -filetype asm -o - %s | FileCheck %s
2+
3+
define dso_local void @func1() {
4+
entry:
5+
call void @func2()
6+
ret void
7+
}
8+
9+
define private void @func2() {
10+
entry:
11+
ret void
12+
}
13+
14+
; CHECK: .def .Lfunc2;
15+
; CHECK-NEXT: .scl 3;
16+
; CHECK-NEXT: .type 32;
17+
; CHECK-NEXT: .endef
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// RUN: llvm-mc -triple thumbv7-windows-gnu -filetype obj %s -o - | llvm-objdump -D -r - | FileCheck %s
2+
3+
.text
4+
main:
5+
nop
6+
b .Ltarget
7+
b .Lother_target
8+
9+
// A private label target in the same section
10+
.def .Ltarget
11+
.scl 3
12+
.type 32
13+
.endef
14+
.p2align 2
15+
.Ltarget:
16+
bx lr
17+
18+
// A private label target in another section
19+
.section "other", "xr"
20+
nop
21+
nop
22+
nop
23+
nop
24+
nop
25+
nop
26+
nop
27+
nop
28+
.def .Lother_target
29+
.scl 3
30+
.type 32
31+
.endef
32+
.p2align 2
33+
.Lother_target:
34+
bx lr
35+
36+
// Check that both branches have a relocation with a zero offset.
37+
//
38+
// CHECK: 00000000 <main>:
39+
// CHECK: 0: bf00 nop
40+
// CHECK: 2: f000 b800 b.w 0x6 <main+0x6> @ imm = #0x0
41+
// CHECK: 00000002: IMAGE_REL_ARM_BRANCH24T .Ltarget
42+
// CHECK: 6: f000 b800 b.w 0xa <main+0xa> @ imm = #0x0
43+
// CHECK: 00000006: IMAGE_REL_ARM_BRANCH24T .Lother_target
44+
// CHECK: a: bf00 nop
45+
// CHECK: 0000000c <.Ltarget>:
46+
// CHECK: c: 4770 bx lr
47+
// CHECK: 00000000 <other>:
48+
// CHECK: 0: bf00 nop
49+
// CHECK: 2: bf00 nop
50+
// CHECK: 4: bf00 nop
51+
// CHECK: 6: bf00 nop
52+
// CHECK: 8: bf00 nop
53+
// CHECK: a: bf00 nop
54+
// CHECK: c: bf00 nop
55+
// CHECK: e: bf00 nop
56+
// CHECK: 00000010 <.Lother_target>:
57+
// CHECK: 10: 4770 bx lr

0 commit comments

Comments
 (0)