Skip to content

Commit f996966

Browse files
committed
[5.5] Runtime: Workaround armv7k code lowering bug
This is to workaround a bug in llvm's codegen when emitting the callee-pop stack adjustment on a regular return from a swiftasync function (vs. a tail call). Without the workaround we fail to emit the callee-pop stack adjustment leading to a mis-aligned stack on return. ``` pop {r7, pc} add sp, swiftlang#16 ``` Workaround for rdar://79726989
1 parent 45699ce commit f996966

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

stdlib/public/Concurrency/Task.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,22 @@ swift::swift_task_create_group_future(
690690
initialContextSize);
691691
}
692692

693+
#ifdef __ARM_ARCH_7K__
694+
__attribute__((noinline))
695+
SWIFT_CC(swiftasync) static void workaround_function_swift_task_future_waitImpl(
696+
OpaqueValue *result, SWIFT_ASYNC_CONTEXT AsyncContext *callerContext,
697+
AsyncTask *task, TaskContinuationFunction resumeFunction,
698+
AsyncContext *callContext) {
699+
// Make sure we don't eliminate calls to this function.
700+
asm volatile("" // Do nothing.
701+
: // Output list, empty.
702+
: "r"(result), "r"(callerContext), "r"(task) // Input list.
703+
: // Clobber list, empty.
704+
);
705+
return;
706+
}
707+
#endif
708+
693709
SWIFT_CC(swiftasync)
694710
static void swift_task_future_waitImpl(
695711
OpaqueValue *result,
@@ -709,7 +725,12 @@ static void swift_task_future_waitImpl(
709725
result)) {
710726
case FutureFragment::Status::Executing:
711727
// The waiting task has been queued on the future.
728+
#ifdef __ARM_ARCH_7K__
729+
return workaround_function_swift_task_future_waitImpl(
730+
result, callerContext, task, resumeFn, callContext);
731+
#else
712732
return;
733+
#endif
713734

714735
case FutureFragment::Status::Success: {
715736
// Run the task with a successful result.
@@ -724,6 +745,22 @@ static void swift_task_future_waitImpl(
724745
}
725746
}
726747

748+
#ifdef __ARM_ARCH_7K__
749+
__attribute__((noinline))
750+
SWIFT_CC(swiftasync) static void workaround_function_swift_task_future_wait_throwingImpl(
751+
OpaqueValue *result, SWIFT_ASYNC_CONTEXT AsyncContext *callerContext,
752+
AsyncTask *task, ThrowingTaskFutureWaitContinuationFunction resumeFunction,
753+
AsyncContext *callContext) {
754+
// Make sure we don't eliminate calls to this function.
755+
asm volatile("" // Do nothing.
756+
: // Output list, empty.
757+
: "r"(result), "r"(callerContext), "r"(task) // Input list.
758+
: // Clobber list, empty.
759+
);
760+
return;
761+
}
762+
#endif
763+
727764
SWIFT_CC(swiftasync)
728765
void swift_task_future_wait_throwingImpl(
729766
OpaqueValue *result, SWIFT_ASYNC_CONTEXT AsyncContext *callerContext,
@@ -744,7 +781,12 @@ void swift_task_future_wait_throwingImpl(
744781
result)) {
745782
case FutureFragment::Status::Executing:
746783
// The waiting task has been queued on the future.
784+
#ifdef __ARM_ARCH_7K__
785+
return workaround_function_swift_task_future_wait_throwingImpl(
786+
result, callerContext, task, resumeFunction, callContext);
787+
#else
747788
return;
789+
#endif
748790

749791
case FutureFragment::Status::Success: {
750792
auto future = task->futureFragment();

stdlib/public/Concurrency/TaskGroup.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,23 @@ task_group_wait_resume_adapter(SWIFT_ASYNC_CONTEXT AsyncContext *_context) {
648648
return resumeWithError(context->Parent, context->errorResult);
649649
}
650650

651+
#ifdef __ARM_ARCH_7K__
652+
__attribute__((noinline))
653+
SWIFT_CC(swiftasync) static void workaround_function_swift_taskGroup_wait_next_throwingImpl(
654+
OpaqueValue *result, SWIFT_ASYNC_CONTEXT AsyncContext *callerContext,
655+
TaskGroup *_group,
656+
ThrowingTaskFutureWaitContinuationFunction resumeFunction,
657+
AsyncContext *callContext) {
658+
// Make sure we don't eliminate calls to this function.
659+
asm volatile("" // Do nothing.
660+
: // Output list, empty.
661+
: "r"(result), "r"(callerContext), "r"(_group) // Input list.
662+
: // Clobber list, empty.
663+
);
664+
return;
665+
}
666+
#endif
667+
651668
// =============================================================================
652669
// ==== group.next() implementation (wait_next and groupPoll) ------------------
653670
SWIFT_CC(swiftasync)
@@ -675,7 +692,12 @@ static void swift_taskGroup_wait_next_throwingImpl(
675692
case PollStatus::MustWait:
676693
// The waiting task has been queued on the channel,
677694
// there were pending tasks so it will be woken up eventually.
695+
#ifdef __ARM_ARCH_7K__
696+
return workaround_function_swift_taskGroup_wait_next_throwingImpl(
697+
resultPointer, callerContext, _group, resumeFunction, rawContext);
698+
#else
678699
return;
700+
#endif
679701

680702
case PollStatus::Empty:
681703
case PollStatus::Error:

0 commit comments

Comments
 (0)