Skip to content

Support for Swift async function pointer compiler flags #3245

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,11 @@ CODEGENOPT(PassByValueIsNoAlias, 1, 0)
/// according to the field declaring type width.
CODEGENOPT(AAPCSBitfieldWidth, 1, 1)

// Whether to emit Swift Async function extended frame information: auto,
// never, always.
ENUM_CODEGENOPT(SwiftAsyncFramePointer, SwiftAsyncFramePointerKind, 2,
SwiftAsyncFramePointerKind::Auto)

#undef CODEGENOPT
#undef ENUM_CODEGENOPT
#undef VALUE_CODEGENOPT
7 changes: 7 additions & 0 deletions clang/include/clang/Basic/CodeGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ class CodeGenOptions : public CodeGenOptionsBase {
All, // Keep all frame pointers.
};

enum class SwiftAsyncFramePointerKind {
Auto, // Choose Swift async extended frame info based on deployment target.
Always, // Unconditionally emit Swift async extended frame info.
Never, // Don't emit Swift async extended frame info.
Default = Auto,
};

enum FiniteLoopsKind {
Language, // Not specified, use language standard.
Always, // All loops are assumed to be finite.
Expand Down
8 changes: 8 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,14 @@ defm pseudo_probe_for_profiling : BoolFOption<"pseudo-probe-for-profiling",
def forder_file_instrumentation : Flag<["-"], "forder-file-instrumentation">,
Group<f_Group>, Flags<[CC1Option, CoreOption]>,
HelpText<"Generate instrumented code to collect order file into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var)">;
def fswift_async_fp_EQ : Joined<["-"], "fswift-async-fp=">,
Group<f_Group>, Flags<[CC1Option, CC1AsOption, CoreOption]>, MetaVarName<"<option>">,
HelpText<"Control emission of Swift async extended frame info (option: auto, always, never)">,
Values<"auto,always,never">,
NormalizedValuesScope<"CodeGenOptions::SwiftAsyncFramePointerKind">,
NormalizedValues<["Auto", "Always", "Never"]>,
MarshallingInfoFlag<"CodeGenOpts.SwiftAsyncFramePointer", "Auto">,
AutoNormalizeEnum;

def fapinotes : Flag<["-"], "fapinotes">, Group<f_clang_Group>,
Flags<[CC1Option]>, HelpText<"Enable external API notes support">;
Expand Down
15 changes: 15 additions & 0 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,21 @@ static bool initTargetOptions(DiagnosticsEngine &Diags,
CodeGenOpts.ValueTrackingVariableLocations;
Options.XRayOmitFunctionIndex = CodeGenOpts.XRayOmitFunctionIndex;

switch (CodeGenOpts.getSwiftAsyncFramePointer()) {
case CodeGenOptions::SwiftAsyncFramePointerKind::Auto:
Options.SwiftAsyncFramePointer =
SwiftAsyncFramePointerMode::DeploymentBased;
break;

case CodeGenOptions::SwiftAsyncFramePointerKind::Always:
Options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Always;
break;

case CodeGenOptions::SwiftAsyncFramePointerKind::Never:
Options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Never;
break;
}

Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5605,6 +5605,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
RenderSCPOptions(TC, Args, CmdArgs);
RenderTrivialAutoVarInitOptions(D, TC, Args, CmdArgs);

Args.AddLastArg(CmdArgs, options::OPT_fswift_async_fp_EQ);

// Translate -mstackrealign
if (Args.hasFlag(options::OPT_mstackrealign, options::OPT_mno_stackrealign,
false))
Expand Down
40 changes: 40 additions & 0 deletions clang/test/CodeGen/swift-async-extended-fp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// RUN: %clang_cc1 -mframe-pointer=all -triple x86_64-apple-darwin10 -target-cpu core2 -S -o - %s | FileCheck %s --check-prefix=AUTO-X86
// RUN: %clang_cc1 -mframe-pointer=all -triple x86_64-apple-darwin12 -target-cpu core2 -S -o - %s | FileCheck %s --check-prefix=ALWAYS-X86
// RUN: %clang_cc1 -fswift-async-fp=never -mframe-pointer=all -triple x86_64-apple-darwin10 -target-cpu core2 -S -o - %s | FileCheck %s --check-prefix=NEVER-X86
// RUN: %clang_cc1 -fswift-async-fp=never -mframe-pointer=all -triple x86_64-apple-darwin12 -target-cpu core2 -S -o - %s | FileCheck %s --check-prefix=NEVER-X86
// RUN: %clang_cc1 -fswift-async-fp=auto -mframe-pointer=all -triple x86_64-apple-darwin10 -target-cpu core2 -S -o - %s | FileCheck %s --check-prefix=AUTO-X86
// RUN: %clang_cc1 -fswift-async-fp=auto -mframe-pointer=all -triple x86_64-apple-darwin12 -target-cpu core2 -S -o - %s | FileCheck %s --check-prefix=ALWAYS-X86
// RUN: %clang_cc1 -fswift-async-fp=always -mframe-pointer=all -triple x86_64-apple-darwin10 -target-cpu core2 -S -o - %s | FileCheck %s --check-prefix=ALWAYS-X86
// RUN: %clang_cc1 -fswift-async-fp=always -mframe-pointer=all -triple x86_64-apple-darwin12 -target-cpu core2 -S -o - %s | FileCheck %s --check-prefix=ALWAYS-X86

// RUN: %clang_cc1 -mframe-pointer=all -triple arm64-apple-ios9 -target-cpu cyclone -S -o - %s | FileCheck %s --check-prefix=AUTO-ARM64
// RUN: %clang_cc1 -mframe-pointer=all -triple arm64-apple-ios15 -target-cpu cyclone -S -o - %s | FileCheck %s --check-prefix=ALWAYS-ARM64
// RUN: %clang_cc1 -fswift-async-fp=never -mframe-pointer=all -triple arm64-apple-ios9 -target-cpu cyclone -S -o - %s | FileCheck %s --check-prefix=NEVER-ARM64
// RUN: %clang_cc1 -fswift-async-fp=never -mframe-pointer=all -triple arm64-apple-ios15 -target-cpu cyclone -S -o - %s | FileCheck %s --check-prefix=NEVER-ARM64

// REQUIRES: aarch64-registered-target,x86-registered-target

#define SWIFTASYNCCALL __attribute__((swiftasynccall))
#define ASYNC_CONTEXT __attribute__((swift_async_context))

SWIFTASYNCCALL void async_context_1(ASYNC_CONTEXT void *ctx) {}

// AUTO-X86: _async_context_1:
// AUTO-X86: _swift_async_extendedFramePointerFlags

// ALWAYS-X86: _async_context_1:
// ALWAYS-X86: btsq $60

// NEVER-X86: _async_context_1:
// NEVER-X86-NOT: _swift_async_extendedFramePointerFlags
// NEVER-X86-NOT: btsq $60

// AUTO-ARM64: _async_context_1
// AUTO-ARM64: _swift_async_extendedFramePointerFlags

// ALWAYS-ARM64: _async_context_1
// ALWAYS-ARM64: orr x29, x29, #0x1000000000000000

// NEVER-ARM64: _async_context_1:
// NEVER-ARM64-NOT: _swift_async_extendedFramePointerFlags
// NEVER-ARM64-NOT: orr x29, x29, #0x1000000000000000
2 changes: 2 additions & 0 deletions llvm/include/llvm/CodeGen/CommandFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ llvm::FloatABI::ABIType getFloatABIForCalls();

llvm::FPOpFusion::FPOpFusionMode getFuseFPOps();

SwiftAsyncFramePointerMode getSwiftAsyncFramePointer();

bool getDontPlaceZerosInBSS();

bool getEnableGuaranteedTailCallOpt();
Expand Down
16 changes: 16 additions & 0 deletions llvm/include/llvm/Target/TargetOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,17 @@ namespace llvm {
DisableWithDiag // Disable the abort but emit a diagnostic on failure.
};

/// Indicates when and how the Swift async frame pointer bit should be set.
enum class SwiftAsyncFramePointerMode {
/// Determine whether to set the bit statically or dynamically based
/// on the deployment target.
DeploymentBased,
/// Always set the bit.
Always,
/// Never set the bit.
Never,
};

class TargetOptions {
public:
TargetOptions()
Expand Down Expand Up @@ -226,6 +237,11 @@ namespace llvm {
/// selection fails to lower/select an instruction.
GlobalISelAbortMode GlobalISelAbort = GlobalISelAbortMode::Enable;

/// Control when and how the Swift async frame pointer bit should
/// be set.
SwiftAsyncFramePointerMode SwiftAsyncFramePointer =
SwiftAsyncFramePointerMode::DeploymentBased;

/// UseInitArray - Use .init_array instead of .ctors for static
/// constructors.
unsigned UseInitArray : 1;
Expand Down
15 changes: 14 additions & 1 deletion llvm/lib/CodeGen/CommandFlags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ CGOPT(DenormalMode::DenormalModeKind, DenormalFP32Math)
CGOPT(bool, EnableHonorSignDependentRoundingFPMath)
CGOPT(FloatABI::ABIType, FloatABIForCalls)
CGOPT(FPOpFusion::FPOpFusionMode, FuseFPOps)
CGOPT(SwiftAsyncFramePointerMode, SwiftAsyncFramePointer)
CGOPT(bool, DontPlaceZerosInBSS)
CGOPT(bool, EnableGuaranteedTailCallOpt)
CGOPT(bool, DisableTailCalls)
Expand Down Expand Up @@ -279,6 +280,18 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
"Only fuse FP ops when the result won't be affected.")));
CGBINDOPT(FuseFPOps);

static cl::opt<SwiftAsyncFramePointerMode> SwiftAsyncFramePointer(
"swift-async-fp",
cl::desc("Determine when the Swift async frame pointer should be set"),
cl::init(SwiftAsyncFramePointerMode::DeploymentBased),
cl::values(clEnumValN(SwiftAsyncFramePointerMode::DeploymentBased, "auto",
"Determine based on deployment target"),
clEnumValN(SwiftAsyncFramePointerMode::Always, "always",
"Always set the bit"),
clEnumValN(SwiftAsyncFramePointerMode::Never, "never",
"Never set the bit")));
CGBINDOPT(SwiftAsyncFramePointer);

static cl::opt<bool> DontPlaceZerosInBSS(
"nozero-initialized-in-bss",
cl::desc("Don't place zero-initialized symbols into bss section"),
Expand Down Expand Up @@ -571,7 +584,7 @@ codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
Options.ThreadModel = getThreadModel();
Options.EABIVersion = getEABIVersion();
Options.DebuggerTuning = getDebuggerTuningOpt();

Options.SwiftAsyncFramePointer = getSwiftAsyncFramePointer();
return Options;
}

Expand Down
32 changes: 27 additions & 5 deletions llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1110,11 +1110,33 @@ 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);
switch (MF.getTarget().Options.SwiftAsyncFramePointer) {
case SwiftAsyncFramePointerMode::DeploymentBased:
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);
break;
}
LLVM_FALLTHROUGH;

case SwiftAsyncFramePointerMode::Always:
// 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);
break;

case SwiftAsyncFramePointerMode::Never:
break;
}
}

// All calls are tail calls in GHC calling conv, and functions have no
Expand Down
25 changes: 25 additions & 0 deletions llvm/lib/Target/AArch64/AArch64Subtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
32 changes: 27 additions & 5 deletions llvm/lib/Target/X86/X86FrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1342,11 +1342,33 @@ 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);
switch (MF.getTarget().Options.SwiftAsyncFramePointer) {
case SwiftAsyncFramePointerMode::DeploymentBased:
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);
break;
}
LLVM_FALLTHROUGH;

case SwiftAsyncFramePointerMode::Always:
BuildMI(MBB, MBBI, DL, TII.get(X86::BTS64ri8), MachineFramePtr)
.addUse(MachineFramePtr)
.addImm(60)
.setMIFlag(MachineInstr::FrameSetup);
break;

case SwiftAsyncFramePointerMode::Never:
break;
}
}

// Re-align the stack on 64-bit if the x86-interrupt calling convention is
Expand Down
25 changes: 25 additions & 0 deletions llvm/lib/Target/X86/X86Subtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/CodeGen/AArch64/swift-async.ll
Original file line number Diff line number Diff line change
@@ -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
Expand Down
28 changes: 28 additions & 0 deletions llvm/test/CodeGen/AArch64/swift-dynamic-async-frame.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
; RUN: llc -mtriple arm64-apple-ios15.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
; RUN: llc -mtriple arm64-apple-ios15.0.0 -swift-async-fp=auto %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
; RUN: llc -mtriple arm64-apple-ios14.9.0 -swift-async-fp=always %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-ios14.9.0 -swift-async-fp=auto %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
}
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/X86/swift-async.ll
Original file line number Diff line number Diff line change
@@ -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


Expand Down
16 changes: 16 additions & 0 deletions llvm/test/CodeGen/X86/swift-dynamic-async-frame.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
; RUN: llc -mtriple x86_64-apple-macosx12.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
; RUN: llc -mtriple x86_64-apple-macosx12.0.0 -swift-async-fp=always %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
; RUN: llc -mtriple x86_64-apple-macosx12.0.0 -swift-async-fp=auto %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
; RUN: llc -mtriple x86_64-apple-macosx11.9.0 -swift-async-fp=always %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
; RUN: llc -mtriple x86_64-apple-macosx11.9.0 -swift-async-fp=auto %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
}
Loading