Skip to content

Commit 61d0a82

Browse files
authored
Merge pull request #7496 from hjyamauchi/backport-arm64
Backport several commits for windows arm64 from upstream
2 parents e814fdb + b70277c commit 61d0a82

File tree

9 files changed

+191
-20
lines changed

9 files changed

+191
-20
lines changed

llvm/lib/MC/WinCOFFObjectWriter.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,9 @@ void WinCOFFWriter::executePostLayoutBinding(MCAssembler &Asm,
847847

848848
if (Mode != DwoOnly)
849849
for (const MCSymbol &Symbol : Asm.symbols())
850-
if (!Symbol.isTemporary())
850+
// Define non-temporary or temporary static (private-linkage) symbols
851+
if (!Symbol.isTemporary() ||
852+
cast<MCSymbolCOFF>(Symbol).getClass() == COFF::IMAGE_SYM_CLASS_STATIC)
851853
DefineSymbol(Symbol, Asm, Layout);
852854
}
853855

@@ -909,7 +911,7 @@ void WinCOFFWriter::recordRelocation(MCAssembler &Asm,
909911
Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment);
910912

911913
// Turn relocations for temporary symbols into section relocations.
912-
if (A.isTemporary()) {
914+
if (A.isTemporary() && !SymbolMap[&A]) {
913915
MCSection *TargetSection = &A.getSection();
914916
assert(
915917
SectionMap.contains(TargetSection) &&

llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,9 @@ class AArch64AsmPrinter : public AsmPrinter {
156156
SetupMachineFunction(MF);
157157

158158
if (STI->isTargetCOFF()) {
159-
bool Internal = MF.getFunction().hasInternalLinkage();
160-
COFF::SymbolStorageClass Scl = Internal ? COFF::IMAGE_SYM_CLASS_STATIC
161-
: COFF::IMAGE_SYM_CLASS_EXTERNAL;
159+
bool Local = MF.getFunction().hasLocalLinkage();
160+
COFF::SymbolStorageClass Scl =
161+
Local ? COFF::IMAGE_SYM_CLASS_STATIC : COFF::IMAGE_SYM_CLASS_EXTERNAL;
162162
int Type =
163163
COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT;
164164

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1993,23 +1993,32 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
19931993
MF.getInfo<AArch64FunctionInfo>()->needsAsyncDwarfUnwindInfo(MF);
19941994
bool HasWinCFI = false;
19951995
bool IsFunclet = false;
1996-
auto WinCFI = make_scope_exit([&]() { assert(HasWinCFI == MF.hasWinCFI()); });
19971996

19981997
if (MBB.end() != MBBI) {
19991998
DL = MBBI->getDebugLoc();
20001999
IsFunclet = isFuncletReturnInstr(*MBBI);
20012000
}
20022001

2002+
MachineBasicBlock::iterator EpilogStartI = MBB.end();
2003+
20032004
auto FinishingTouches = make_scope_exit([&]() {
20042005
InsertReturnAddressAuth(MF, MBB, NeedsWinCFI, &HasWinCFI);
20052006
if (needsShadowCallStackPrologueEpilogue(MF))
20062007
emitShadowCallStackEpilogue(*TII, MF, MBB, MBB.getFirstTerminator(), DL);
20072008
if (EmitCFI)
20082009
emitCalleeSavedGPRRestores(MBB, MBB.getFirstTerminator());
2009-
if (HasWinCFI)
2010+
if (HasWinCFI) {
20102011
BuildMI(MBB, MBB.getFirstTerminator(), DL,
20112012
TII->get(AArch64::SEH_EpilogEnd))
20122013
.setMIFlag(MachineInstr::FrameDestroy);
2014+
if (!MF.hasWinCFI())
2015+
MF.setHasWinCFI(true);
2016+
}
2017+
if (NeedsWinCFI) {
2018+
assert(EpilogStartI != MBB.end());
2019+
if (!HasWinCFI)
2020+
MBB.erase(EpilogStartI);
2021+
}
20132022
});
20142023

20152024
int64_t NumBytes = IsFunclet ? getWinEHFuncletFrameSize(MF)
@@ -2074,7 +2083,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
20742083
// Adjust local stack
20752084
emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::SP,
20762085
StackOffset::getFixed(AFI->getLocalStackSize()), TII,
2077-
MachineInstr::FrameDestroy, false, NeedsWinCFI);
2086+
MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI);
20782087

20792088
// SP has been already adjusted while restoring callee save regs.
20802089
// We've bailed-out the case with adjusting SP for arguments.
@@ -2126,16 +2135,17 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
21262135
NeedsWinCFI, &HasWinCFI);
21272136
}
21282137

2129-
if (MF.hasWinCFI()) {
2130-
// If the prologue didn't contain any SEH opcodes and didn't set the
2131-
// MF.hasWinCFI() flag, assume the epilogue won't either, and skip the
2132-
// EpilogStart - to avoid generating CFI for functions that don't need it.
2133-
// (And as we didn't generate any prologue at all, it would be asymmetrical
2134-
// to the epilogue.) By the end of the function, we assert that
2135-
// HasWinCFI is equal to MF.hasWinCFI(), to verify this assumption.
2136-
HasWinCFI = true;
2138+
if (NeedsWinCFI) {
2139+
// Note that there are cases where we insert SEH opcodes in the
2140+
// epilogue when we had no SEH opcodes in the prologue. For
2141+
// example, when there is no stack frame but there are stack
2142+
// arguments. Insert the SEH_EpilogStart and remove it later if it
2143+
// we didn't emit any SEH opcodes to avoid generating WinCFI for
2144+
// functions that don't need it.
21372145
BuildMI(MBB, LastPopI, DL, TII->get(AArch64::SEH_EpilogStart))
21382146
.setMIFlag(MachineInstr::FrameDestroy);
2147+
EpilogStartI = LastPopI;
2148+
--EpilogStartI;
21392149
}
21402150

21412151
if (hasFP(MF) && AFI->hasSwiftAsyncContext()) {
@@ -2289,11 +2299,11 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
22892299
emitFrameOffset(
22902300
MBB, LastPopI, DL, AArch64::SP, AArch64::FP,
22912301
StackOffset::getFixed(-AFI->getCalleeSaveBaseToFrameRecordOffset()),
2292-
TII, MachineInstr::FrameDestroy, false, NeedsWinCFI);
2302+
TII, MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI);
22932303
} else if (NumBytes)
22942304
emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::SP,
22952305
StackOffset::getFixed(NumBytes), TII,
2296-
MachineInstr::FrameDestroy, false, NeedsWinCFI);
2306+
MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI);
22972307

22982308
// When we are about to restore the CSRs, the CFA register is SP again.
22992309
if (EmitCFI && hasFP(MF)) {
@@ -2750,7 +2760,8 @@ static void computeCalleeSaveRegisterPairs(
27502760
// Swift's async context is directly before FP, so allocate an extra
27512761
// 8 bytes for it.
27522762
if (NeedsFrameRecord && AFI->hasSwiftAsyncContext() &&
2753-
RPI.Reg2 == AArch64::FP)
2763+
((!IsWindows && RPI.Reg2 == AArch64::FP) ||
2764+
(IsWindows && RPI.Reg2 == AArch64::LR)))
27542765
ByteOffset += StackFillDir * 8;
27552766

27562767
assert(!(RPI.isScalable() && RPI.isPaired()) &&
@@ -2779,7 +2790,8 @@ static void computeCalleeSaveRegisterPairs(
27792790
// The FP, LR pair goes 8 bytes into our expanded 24-byte slot so that the
27802791
// Swift context can directly precede FP.
27812792
if (NeedsFrameRecord && AFI->hasSwiftAsyncContext() &&
2782-
RPI.Reg2 == AArch64::FP)
2793+
((!IsWindows && RPI.Reg2 == AArch64::FP) ||
2794+
(IsWindows && RPI.Reg2 == AArch64::LR)))
27832795
Offset += 8;
27842796
RPI.Offset = Offset / Scale;
27852797

llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,13 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
314314
return (Value >> 2) & 0x3fff;
315315
case AArch64::fixup_aarch64_pcrel_branch26:
316316
case AArch64::fixup_aarch64_pcrel_call26:
317+
if (TheTriple.isOSBinFormatCOFF() && !IsResolved && SignedValue != 0) {
318+
// MSVC link.exe and lld do not support this relocation type
319+
// with a non-zero offset
320+
Ctx.reportError(Fixup.getLoc(),
321+
"cannot perform a PC-relative fixup with a non-zero "
322+
"symbol offset");
323+
}
317324
// Signed 28-bit immediate
318325
if (SignedValue > 134217727 || SignedValue < -134217728)
319326
Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
; RUN: llc -mtriple aarch64-unknown-windows-msvc %s -o - | FileCheck %s
2+
3+
define internal void @internal() {
4+
ret void
5+
}
6+
7+
define private void @private() {
8+
ret void
9+
}
10+
11+
; Check that the internal and private linkage symbols have IMAGE_SYM_CLASS_STATIC (3).
12+
; CHECK: .def internal;
13+
; CHECK: .scl 3;
14+
; CHECK: .def .Lprivate;
15+
; CHECK: .scl 3;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
; RUN: llc -mtriple aarch64-unknown-windows-msvc -filetype asm %s -o - | FileCheck %s
2+
3+
; Check that the slot offset of the async context (x22) doesn't
4+
; conflict with that of another callee-saved register (x21 here) and
5+
; saving it won't overwrite the saved value of the callee-saved
6+
; register.
7+
;
8+
; CHECK: sub sp, sp, #64
9+
; CHECK: str x19, [sp, #16]
10+
; CHECK: str x21, [sp, #24]
11+
; CHECK-NOT: stp x29, x30, [sp, #32]
12+
; CHECK: stp x29, x30, [sp, #40]
13+
; CHECK-NOT: str x22, [sp, #24]
14+
; CHECK: str x22, [sp, #32]
15+
16+
declare ptr @llvm.swift.async.context.addr()
17+
declare swiftcc i64 @foo(i64 %0, i64 %1)
18+
declare swifttailcc void @tail(ptr swiftasync %0, ptr swiftself dereferenceable(8) %1, i64 %2)
19+
define internal swifttailcc void @test(ptr swiftasync %0, ptr swiftself %1, i64 %2) {
20+
entry:
21+
%3 = load ptr, ptr %0, align 8
22+
%4 = call ptr @llvm.swift.async.context.addr()
23+
store ptr %3, ptr %4, align 8
24+
%5 = call swiftcc i64 @foo(i64 %2, i64 %2)
25+
%6 = call swiftcc i64 @foo(i64 %2, i64 %5)
26+
%7 = call swiftcc i64 @foo(i64 %5, i64 %2)
27+
%8 = call swiftcc i64 @foo(i64 %7, i64 %6)
28+
%9 = call swiftcc i64 @foo(i64 %2, i64 %8)
29+
%10 = call ptr @llvm.swift.async.context.addr()
30+
musttail call swifttailcc void @tail(ptr swiftasync %10, ptr swiftself %1, i64 %2)
31+
ret void
32+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
; RUN: llc -mtriple=aarch64-windows %s -o - | FileCheck %s
2+
3+
define hidden swifttailcc void @test(ptr noalias nocapture %0, ptr swiftasync %1, ptr %2, ptr noalias nocapture %3, ptr nocapture dereferenceable(8) %4, ptr %5, ptr %6, ptr %Act, ptr %Err, ptr %Res, ptr %Act.DistributedActor, ptr %Err.Error, ptr %Res.Decodable, ptr %Res.Encodable, ptr swiftself %7) #0 {
4+
entry:
5+
ret void
6+
}
7+
8+
; Check that there is no .seh_endprologue but there is seh_startepilogue/seh_endepilogue.
9+
; CHECK-NOT: .seh_endprologue
10+
; CHECK: .seh_startepilogue
11+
; CHECK: add sp, sp, #48
12+
; CHECK: .seh_stackalloc 48
13+
; CHECK: .seh_endepilogue
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
; RUN: llc -mtriple x86_64-unknown-windows-msvc %s -o - | FileCheck %s
2+
3+
define internal void @internal() {
4+
ret void
5+
}
6+
7+
define private void @private() {
8+
ret void
9+
}
10+
11+
; Check that the internal and private linkage symbols have IMAGE_SYM_CLASS_STATIC (3).
12+
; CHECK: .def internal;
13+
; CHECK: .scl 3;
14+
; CHECK: .def .Lprivate;
15+
; CHECK: .scl 3;
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// RUN: llvm-mc -triple aarch64-unknown-windows-msvc -filetype obj %s -o - | llvm-objdump -D -r - | FileCheck %s
2+
// RUN: not llvm-mc -triple aarch64-unknown-windows-msvc -filetype obj --defsym ERR=1 %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR
3+
4+
.text
5+
main:
6+
nop
7+
b .Ltarget
8+
b .Lother_target
9+
10+
// A privte label target in the same section
11+
.def .Ltarget
12+
.scl 3
13+
.type 32
14+
.endef
15+
.p2align 2
16+
.Ltarget:
17+
ret
18+
19+
// A privte label target in another section
20+
.section "other"
21+
nop
22+
nop
23+
nop
24+
nop
25+
nop
26+
nop
27+
nop
28+
nop
29+
.def .Lother_target
30+
.scl 3
31+
.type 32
32+
.endef
33+
.p2align 2
34+
.Lother_target:
35+
ret
36+
37+
// Check that both branches have a relocation with a zero offset.
38+
//
39+
// CHECK: 0000000000000000 <main>:
40+
// CHECK: 0: d503201f nop
41+
// CHECK: 4: 14000000 b 0x4 <main+0x4>
42+
// CHECK: 0000000000000004: IMAGE_REL_ARM64_BRANCH26 .Ltarget
43+
// CHECK: 8: 14000000 b 0x8 <main+0x8>
44+
// CHECK: 0000000000000008: IMAGE_REL_ARM64_BRANCH26 .Lother_target
45+
// CHECK: 000000000000000c <.Ltarget>:
46+
// CHECK: c: d65f03c0 ret
47+
// CHECK: 0000000000000000 <other>:
48+
// CHECK: 0: d503201f nop
49+
// CHECK: 4: d503201f nop
50+
// CHECK: 8: d503201f nop
51+
// CHECK: c: d503201f nop
52+
// CHECK: 10: d503201f nop
53+
// CHECK: 14: d503201f nop
54+
// CHECK: 18: d503201f nop
55+
// CHECK: 1c: d503201f nop
56+
// CHECK: 0000000000000020 <.Lother_target>:
57+
// CHECK: 20: d65f03c0 ret
58+
59+
.ifdef ERR
60+
.section "err"
61+
err:
62+
nop
63+
b .Lerr_target+4
64+
// ERR: [[#@LINE-1]]:5: error: cannot perform a PC-relative fixup with a non-zero symbol offset
65+
66+
.def .Lerr_target
67+
.scl 3
68+
.type 32
69+
.p2align 2
70+
.endef
71+
.Lerr_target:
72+
nop
73+
nop
74+
ret
75+
.endif

0 commit comments

Comments
 (0)