diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h index d7d3692877de2e..281ecb8de25156 100644 --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -799,6 +799,11 @@ class AsmPrinter : public MachineFunctionPass { /// This method decides whether the specified basic block requires a label. bool shouldEmitLabelForBasicBlock(const MachineBasicBlock &MBB) const; + +protected: + virtual bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags() const { + return false; + } }; } // end namespace llvm diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 8dbc14dc906568..0b46533490a8b1 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1860,6 +1860,17 @@ bool AsmPrinter::doFinalization(Module &M) { continue; OutStreamer->emitSymbolAttribute(getSymbol(&GO), MCSA_WeakReference); } + if (shouldEmitWeakSwiftAsyncExtendedFramePointerFlags()) { + auto SymbolName = "swift_async_extendedFramePointerFlags"; + auto Global = M.getGlobalVariable(SymbolName); + if (!Global) { + auto Int8PtrTy = Type::getInt8PtrTy(M.getContext()); + Global = new GlobalVariable(M, Int8PtrTy, false, + GlobalValue::ExternalWeakLinkage, nullptr, + SymbolName); + OutStreamer->emitSymbolAttribute(getSymbol(Global), MCSA_WeakReference); + } + } } // Print aliases in topological order, that is, for each alias a = b, diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index aeebb49675b244..85a9c04a3fefc2 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -73,6 +73,7 @@ class AArch64AsmPrinter : public AsmPrinter { StackMaps SM; FaultMaps FM; const AArch64Subtarget *STI; + bool ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = false; public: AArch64AsmPrinter(TargetMachine &TM, std::unique_ptr Streamer) @@ -186,6 +187,10 @@ class AArch64AsmPrinter : public AsmPrinter { using MInstToMCSymbol = std::map; MInstToMCSymbol LOHInstToLabel; + + bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags() const override { + return ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags; + } }; } // end anonymous namespace @@ -1132,6 +1137,15 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { if (emitPseudoExpansionLowering(*OutStreamer, MI)) return; + if (MI->getOpcode() == AArch64::ADRP) { + for (auto &Opd : MI->operands()) { + if (Opd.isSymbol() && StringRef(Opd.getSymbolName()) == + "swift_async_extendedFramePointerFlags") { + ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = true; + } + } + } + if (AArch64FI->getLOHRelated().count(MI)) { // Generate a label for LOH related instruction MCSymbol *LOHLabel = createTempSymbol("loh"); diff --git a/llvm/lib/Target/X86/X86AsmPrinter.h b/llvm/lib/Target/X86/X86AsmPrinter.h index fe6df2e9b2ea49..b22f25af26cfd9 100644 --- a/llvm/lib/Target/X86/X86AsmPrinter.h +++ b/llvm/lib/Target/X86/X86AsmPrinter.h @@ -31,6 +31,7 @@ class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter { FaultMaps FM; std::unique_ptr CodeEmitter; bool EmitFPOData = false; + bool ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = false; // This utility class tracks the length of a stackmap instruction's 'shadow'. // It is used by the X86AsmPrinter to ensure that the stackmap shadow @@ -151,6 +152,10 @@ class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter { bool runOnMachineFunction(MachineFunction &MF) override; void emitFunctionBodyStart() override; void emitFunctionBodyEnd() override; + + bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags() const override { + return ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags; + } }; } // end namespace llvm diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp index 9c73d0bcabbce9..9044f10ec63077 100644 --- a/llvm/lib/Target/X86/X86MCInstLower.cpp +++ b/llvm/lib/Target/X86/X86MCInstLower.cpp @@ -2410,6 +2410,15 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) { const X86RegisterInfo *RI = MF->getSubtarget().getRegisterInfo(); + if (MI->getOpcode() == X86::OR64rm) { + for (auto &Opd : MI->operands()) { + if (Opd.isSymbol() && StringRef(Opd.getSymbolName()) == + "swift_async_extendedFramePointerFlags") { + ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = true; + } + } + } + // Add a comment about EVEX-2-VEX compression for AVX-512 instrs that // are compressed from EVEX encoding to VEX encoding. if (TM.Options.MCOptions.ShowMCEncoding) { diff --git a/llvm/test/CodeGen/AArch64/swift-dynamic-async-frame.ll b/llvm/test/CodeGen/AArch64/swift-dynamic-async-frame.ll index b6be40fdf03f0f..94babeabab66d4 100644 --- a/llvm/test/CodeGen/AArch64/swift-dynamic-async-frame.ll +++ b/llvm/test/CodeGen/AArch64/swift-dynamic-async-frame.ll @@ -23,11 +23,13 @@ ; 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: .weak_reference _swift_async_extendedFramePointerFlags ; 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 +; CHECK-DYNAMIC-32: .weak_reference _swift_async_extendedFramePointerFlags define void @foo(i8* swiftasync) "frame-pointer"="all" { ret void diff --git a/llvm/test/CodeGen/X86/swift-dynamic-async-frame.ll b/llvm/test/CodeGen/X86/swift-dynamic-async-frame.ll index 439b57efed4ca4..384c2fbfd46460 100644 --- a/llvm/test/CodeGen/X86/swift-dynamic-async-frame.ll +++ b/llvm/test/CodeGen/X86/swift-dynamic-async-frame.ll @@ -12,6 +12,7 @@ ; CHECK-DYNAMIC-LABEL: foo: ; CHECK-DYNAMIC: orq _swift_async_extendedFramePointerFlags@GOTPCREL(%rip), %rbp +; CHECK-DYNAMIC: .weak_reference _swift_async_extendedFramePointerFlags ; CHECK-NEVER-LABEL: foo: ; CHECK-NEVER-NOT: btsq $60, %rbp