diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index 51b88492e4199..9f91c7250a648 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -1110,11 +1110,23 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF, // ORR is sufficient, it is assumed a Swift kernel would initialize the TBI // bits so that is still true. if (HasFP && AFI->hasSwiftAsyncContext()) { - // ORR x29, x29, #0x1000_0000_0000_0000 - BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXri), AArch64::FP) - .addUse(AArch64::FP) - .addImm(0x1100) - .setMIFlag(MachineInstr::FrameSetup); + if (Subtarget.swiftAsyncContextIsDynamicallySet()) { + // The special symbol below is absolute and has a *value* that can be + // combined with the frame pointer to signal an extended frame. + BuildMI(MBB, MBBI, DL, TII->get(AArch64::LOADgot), AArch64::X16) + .addExternalSymbol("swift_async_extendedFramePointerFlags", + AArch64II::MO_GOT); + BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::FP) + .addUse(AArch64::FP) + .addUse(AArch64::X16) + .addImm(Subtarget.isTargetILP32() ? 32 : 0); + } else { + // ORR x29, x29, #0x1000_0000_0000_0000 + BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXri), AArch64::FP) + .addUse(AArch64::FP) + .addImm(0x1100) + .setMIFlag(MachineInstr::FrameSetup); + } } // All calls are tail calls in GHC calling conv, and functions have no diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h index ab44d0767dec8..2fe572b036510 100644 --- a/llvm/lib/Target/AArch64/AArch64Subtarget.h +++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h @@ -566,6 +566,31 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo { } } + /// Return whether FrameLowering should always set the "extended frame + /// present" bit in FP, or set it based on a symbol in the runtime. + bool swiftAsyncContextIsDynamicallySet() const { + // Older OS versions (particularly system unwinders) are confused by the + // Swift extended frame, so when building code that might be run on them we + // must dynamically query the concurrency library to determine whether + // extended frames should be flagged as present. + const Triple &TT = getTargetTriple(); + + unsigned Major, Minor, Micro; + TT.getOSVersion(Major, Minor, Micro); + switch(TT.getOS()) { + default: + return false; + case Triple::IOS: + case Triple::TvOS: + return Major < 15; + case Triple::WatchOS: + return Major < 8; + case Triple::MacOSX: + case Triple::Darwin: + return Major < 12; + } + } + void mirFileLoaded(MachineFunction &MF) const override; // Return the known range for the bit length of SVE data registers. A value diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index 7850e061bee41..8ba19bcccec67 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -1342,11 +1342,23 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF, unsigned StackProbeSize = STI.getTargetLowering()->getStackProbeSize(MF); if (HasFP && X86FI->hasSwiftAsyncContext()) { - BuildMI(MBB, MBBI, DL, TII.get(X86::BTS64ri8), - MachineFramePtr) - .addUse(MachineFramePtr) - .addImm(60) - .setMIFlag(MachineInstr::FrameSetup); + if (STI.swiftAsyncContextIsDynamicallySet()) { + // The special symbol below is absolute and has a *value* suitable to be + // combined with the frame pointer directly. + BuildMI(MBB, MBBI, DL, TII.get(X86::OR64rm), MachineFramePtr) + .addUse(MachineFramePtr) + .addUse(X86::RIP) + .addImm(1) + .addUse(X86::NoRegister) + .addExternalSymbol("swift_async_extendedFramePointerFlags", + X86II::MO_GOTPCREL) + .addUse(X86::NoRegister); + } else { + BuildMI(MBB, MBBI, DL, TII.get(X86::BTS64ri8), MachineFramePtr) + .addUse(MachineFramePtr) + .addImm(60) + .setMIFlag(MachineInstr::FrameSetup); + } } // Re-align the stack on 64-bit if the x86-interrupt calling convention is diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index 9cda5b56e00b2..9cfeef095d6e6 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -924,6 +924,31 @@ class X86Subtarget final : public X86GenSubtargetInfo { /// Return true if the subtarget allows calls to immediate address. bool isLegalToCallImmediateAddr() const; + /// Return whether FrameLowering should always set the "extended frame + /// present" bit in FP, or set it based on a symbol in the runtime. + bool swiftAsyncContextIsDynamicallySet() const { + // Older OS versions (particularly system unwinders) are confused by the + // Swift extended frame, so when building code that might be run on them we + // must dynamically query the concurrency library to determine whether + // extended frames should be flagged as present. + const Triple &TT = getTargetTriple(); + + unsigned Major, Minor, Micro; + TT.getOSVersion(Major, Minor, Micro); + switch(TT.getOS()) { + default: + return false; + case Triple::IOS: + case Triple::TvOS: + return Major < 15; + case Triple::WatchOS: + return Major < 8; + case Triple::MacOSX: + case Triple::Darwin: + return Major < 12; + } + } + /// If we are using indirect thunks, we need to expand indirectbr to avoid it /// lowering to an actual indirect jump. bool enableIndirectBrExpand() const override { diff --git a/llvm/test/CodeGen/AArch64/swift-async.ll b/llvm/test/CodeGen/AArch64/swift-async.ll index bbf4670e76e84..dba5dacef49c2 100644 --- a/llvm/test/CodeGen/AArch64/swift-async.ll +++ b/llvm/test/CodeGen/AArch64/swift-async.ll @@ -1,6 +1,6 @@ -; RUN: llc -mtriple=arm64-apple-ios %s -o - | FileCheck %s --check-prefixes=CHECK-NOAUTH,CHECK -; RUN: llc -mtriple=arm64-apple-ios -mcpu=apple-a13 %s -o - | FileCheck %s --check-prefixes=CHECK-NOAUTH,CHECK -; RUN: llc -mtriple=arm64e-apple-ios %s -o - | FileCheck %s --check-prefixes=CHECK-AUTH,CHECK +; RUN: llc -mtriple=arm64-apple-ios15 %s -o - | FileCheck %s --check-prefixes=CHECK-NOAUTH,CHECK +; RUN: llc -mtriple=arm64-apple-ios15 -mcpu=apple-a13 %s -o - | FileCheck %s --check-prefixes=CHECK-NOAUTH,CHECK +; RUN: llc -mtriple=arm64e-apple-ios15 %s -o - | FileCheck %s --check-prefixes=CHECK-AUTH,CHECK ; Important details in prologue: ; * x22 is stored just below x29 diff --git a/llvm/test/CodeGen/AArch64/swift-dynamic-async-frame.ll b/llvm/test/CodeGen/AArch64/swift-dynamic-async-frame.ll new file mode 100644 index 0000000000000..6b17b49403f2f --- /dev/null +++ b/llvm/test/CodeGen/AArch64/swift-dynamic-async-frame.ll @@ -0,0 +1,25 @@ +; RUN: llc -mtriple arm64-apple-ios15.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC +; RUN: llc -mtriple arm64-apple-ios14.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC +; RUN: llc -mtriple arm64-apple-tvos15.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC +; RUN: llc -mtriple arm64-apple-tvos14.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC +; RUN: llc -mtriple arm64-apple-macosx12.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC +; RUN: llc -mtriple arm64-apple-macosx11.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC +; RUN: llc -mtriple arm64_32-apple-watchos8.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC +; RUN: llc -mtriple arm64_32-apple-watchos7.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC-32 + +; CHECK-STATIC-LABEL: foo: +; CHECK-STATIC: orr x29, x29, #0x1000000000000000 + +; CHECK-DYNAMIC-LABEL: foo: +; CHECK-DYNAMIC: adrp x16, _swift_async_extendedFramePointerFlags@GOTPAGE +; CHECK-DYNAMIC: ldr x16, [x16, _swift_async_extendedFramePointerFlags@GOTPAGEOFF] +; CHECK-DYNAMIC: orr x29, x29, x16 + +; CHECK-DYNAMIC-32-LABEL: foo: +; CHECK-DYNAMIC-32: adrp x16, _swift_async_extendedFramePointerFlags@GOTPAGE +; CHECK-DYNAMIC-32: ldr w16, [x16, _swift_async_extendedFramePointerFlags@GOTPAGEOFF] +; CHECK-DYNAMIC-32: orr x29, x29, x16, lsl #32 + +define void @foo(i8* swiftasync) "frame-pointer"="all" { + ret void +} diff --git a/llvm/test/CodeGen/X86/swift-async.ll b/llvm/test/CodeGen/X86/swift-async.ll index 9716fe7364896..c671917fd0d4f 100644 --- a/llvm/test/CodeGen/X86/swift-async.ll +++ b/llvm/test/CodeGen/X86/swift-async.ll @@ -1,4 +1,4 @@ -; RUN: llc -mtriple=x86_64-apple-darwin %s -o - | FileCheck %s +; RUN: llc -mtriple=x86_64-apple-macosx12.0 %s -o - | FileCheck %s ; RUN: llc -mtriple=i686-apple-darwin %s -o - | FileCheck %s --check-prefix=CHECK-32 diff --git a/llvm/test/CodeGen/X86/swift-dynamic-async-frame.ll b/llvm/test/CodeGen/X86/swift-dynamic-async-frame.ll new file mode 100644 index 0000000000000..8719aee17d53b --- /dev/null +++ b/llvm/test/CodeGen/X86/swift-dynamic-async-frame.ll @@ -0,0 +1,12 @@ +; RUN: llc -mtriple x86_64-apple-macosx12.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC +; RUN: llc -mtriple x86_64-apple-macosx11.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC + +; CHECK-STATIC-LABEL: foo: +; CHECK-STATIC: btsq $60, %rbp + +; CHECK-DYNAMIC-LABEL: foo: +; CHECK-DYNAMIC: orq _swift_async_extendedFramePointerFlags@GOTPCREL(%rip), %rbp + +define void @foo(i8* swiftasync) "frame-pointer"="all" { + ret void +} diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py index 9f119dd520bd4..14e4a9a005d8d 100644 --- a/llvm/test/lit.cfg.py +++ b/llvm/test/lit.cfg.py @@ -118,6 +118,8 @@ def get_asan_rtlib(): asan_rtlib = get_asan_rtlib() if asan_rtlib: ld64_cmd = 'DYLD_INSERT_LIBRARIES={} {}'.format(asan_rtlib, ld64_cmd) +if config.osx_sysroot: + ld64_cmd = '{} -syslibroot {}'.format(ld64_cmd, config.osx_sysroot) ocamlc_command = '%s ocamlc -cclib -L%s %s' % ( config.ocamlfind_executable, config.llvm_lib_dir, config.ocaml_flags) diff --git a/llvm/test/lit.site.cfg.py.in b/llvm/test/lit.site.cfg.py.in index 9765d498b50d6..c60ea943a8319 100644 --- a/llvm/test/lit.site.cfg.py.in +++ b/llvm/test/lit.site.cfg.py.in @@ -15,6 +15,7 @@ config.lit_tools_dir = path(r"@LLVM_LIT_TOOLS_DIR@") config.python_executable = "@Python3_EXECUTABLE@" config.gold_executable = "@GOLD_EXECUTABLE@" config.ld64_executable = "@LD64_EXECUTABLE@" +config.osx_sysroot = "@CMAKE_OSX_SYSROOT@" config.ocamlfind_executable = "@OCAMLFIND@" config.have_ocamlopt = @HAVE_OCAMLOPT@ config.have_ocaml_ounit = @HAVE_OCAML_OUNIT@ diff --git a/llvm/test/tools/lto/hide-linkonce-odr.ll b/llvm/test/tools/lto/hide-linkonce-odr.ll index ad7cf1b3f8baa..df4b338d2fed3 100644 --- a/llvm/test/tools/lto/hide-linkonce-odr.ll +++ b/llvm/test/tools/lto/hide-linkonce-odr.ll @@ -1,5 +1,5 @@ ; RUN: llvm-as %s -o %t.o -; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -dylib -arch x86_64 -macosx_version_min 10.10.0 -o %t.dylib %t.o -save-temps -undefined dynamic_lookup -exported_symbol _c -exported_symbol _b -exported_symbol _GlobLinkonce +; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -dylib -arch x86_64 -macosx_version_min 10.10.0 -o %t.dylib %t.o -save-temps -undefined dynamic_lookup -exported_symbol _c -exported_symbol _b -exported_symbol _GlobLinkonce -lSystem ; RUN: llvm-dis %t.dylib.lto.opt.bc -o - | FileCheck --check-prefix=IR %s ; check that @a is no longer a linkonce_odr definition diff --git a/llvm/test/tools/lto/no-bitcode.s b/llvm/test/tools/lto/no-bitcode.s index 8fb8e3b645851..74a8a51311bb7 100644 --- a/llvm/test/tools/lto/no-bitcode.s +++ b/llvm/test/tools/lto/no-bitcode.s @@ -2,4 +2,4 @@ ; libLTO.dylib shouldn't assert on invalid inputs. ; RUN: llvm-mc -triple=arm64-apple-ios7.0.0 -filetype=obj -o %t.o ; RUN: llvm-ar r %t.a %t.o -; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -O0 -o %t.dylib %t.a +; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -O0 -o %t.dylib %t.a -lSystem diff --git a/llvm/test/tools/lto/opt-level.ll b/llvm/test/tools/lto/opt-level.ll index b282679936a44..5113353e3b55f 100644 --- a/llvm/test/tools/lto/opt-level.ll +++ b/llvm/test/tools/lto/opt-level.ll @@ -1,7 +1,7 @@ ; RUN: llvm-as %s -o %t.o -; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -O0 -o %t.dylib %t.o +; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -O0 -o %t.dylib %t.o -lSystem ; RUN: llvm-nm --no-llvm-bc %t.dylib | FileCheck --check-prefix=CHECK-O0 %s -; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -O2 -o %t.dylib %t.o +; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -O2 -o %t.dylib %t.o -lSystem ; RUN: llvm-nm --no-llvm-bc %t.dylib | FileCheck --check-prefix=CHECK-O2 %s target triple = "x86_64-apple-macosx10.8.0" diff --git a/llvm/test/tools/lto/print-stats.ll b/llvm/test/tools/lto/print-stats.ll index 125d7d0514990..bfa47e403bfd7 100644 --- a/llvm/test/tools/lto/print-stats.ll +++ b/llvm/test/tools/lto/print-stats.ll @@ -1,6 +1,6 @@ ; RUN: llvm-as %s -o %t.o -; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -stats -o %t.dylib %t.o 2>&1 | FileCheck --check-prefix=STATS %s -; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -o %t.dylib %t.o 2>&1 | FileCheck --check-prefix=NO_STATS %s +; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -stats -o %t.dylib %t.o -lSystem 2>&1 | FileCheck --check-prefix=STATS %s +; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -o %t.dylib %t.o -lSystem 2>&1 | FileCheck --check-prefix=NO_STATS %s ; REQUIRES: asserts target triple = "x86_64-apple-macosx10.8.0"