[PATCH] D95984: [CodeGen] Fix codegen for __attribute__((swiftasynccall)).

2021-06-23 Thread Varun Gandhi via Phabricator via cfe-commits
varungandhi-apple abandoned this revision.
varungandhi-apple added a comment.
Herald added a subscriber: ormris.

Combined changes into D95561 .


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95984/new/

https://reviews.llvm.org/D95984

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D95984: [CodeGen] Fix codegen for __attribute__((swiftasynccall)).

2021-04-05 Thread Varun Gandhi via Phabricator via cfe-commits
varungandhi-apple updated this revision to Diff 335293.
varungandhi-apple added a comment.
Herald added subscribers: llvm-commits, dexonsmith, hiraditya.
Herald added a project: LLVM.

1. Remove '::' when calling static function.
2. Fix bug in function merging around missing musttail.
3. Add off-by-default check in verifier for swifttailcc->swifttailcc tail calls 
that are not marked musttail.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95984/new/

https://reviews.llvm.org/D95984

Files:
  clang/lib/AST/ExprCXX.cpp
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/test/CodeGen/64bit-swiftcall.c
  clang/test/CodeGen/arm-swiftcall.c
  clang/test/CodeGen/swift-async-call-conv.c
  clang/test/CodeGen/swift-call-conv.c
  llvm/lib/IR/Verifier.cpp
  llvm/lib/Transforms/IPO/MergeFunctions.cpp

Index: llvm/lib/Transforms/IPO/MergeFunctions.cpp
===
--- llvm/lib/Transforms/IPO/MergeFunctions.cpp
+++ llvm/lib/Transforms/IPO/MergeFunctions.cpp
@@ -713,7 +713,10 @@
 
   CallInst *CI = Builder.CreateCall(F, Args);
   ReturnInst *RI = nullptr;
-  CI->setTailCall();
+  bool isSwiftTailCall = F->getCallingConv() == CallingConv::SwiftTail &&
+ G->getCallingConv() == CallingConv::SwiftTail;
+  CI->setTailCallKind(isSwiftTailCall ? llvm::CallInst::TCK_MustTail
+  : llvm::CallInst::TCK_Tail);
   CI->setCallingConv(F->getCallingConv());
   CI->setAttributes(F->getAttributes());
   if (H->getReturnType()->isVoidTy()) {
Index: llvm/lib/IR/Verifier.cpp
===
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -3288,7 +3288,24 @@
   return Copy;
 }
 
+static cl::opt EnableSwiftTailCCMustTailCheck(
+"enable-swifttailcc-musttail-check", cl::init(false),
+cl::desc("Check that tail calls from swifttailcc functions to"
+ " swifttailcc functions are marked musttail."));
+
 void Verifier::verifyMustTailCall(CallInst ) {
+  if (!CI.isMustTailCall()) {
+if (EnableSwiftTailCCMustTailCheck &&
+CI.getCallingConv() == CallingConv::SwiftTail &&
+CI.getCaller()->getCallingConv() == CallingConv::SwiftTail &&
+isa_and_nonnull(CI.getNextNode())) {
+  Assert(false,
+ "tail call from swifttail->swiftail should be marked musttail",
+ );
+}
+return;
+  }
+
   Assert(!CI.isInlineAsm(), "cannot use musttail call with inline asm", );
 
   // - The caller and callee prototypes must match.  Pointer types of
@@ -3354,9 +3371,7 @@
 
 void Verifier::visitCallInst(CallInst ) {
   visitCallBase(CI);
-
-  if (CI.isMustTailCall())
-verifyMustTailCall(CI);
+  verifyMustTailCall(CI);
 }
 
 void Verifier::visitInvokeInst(InvokeInst ) {
Index: clang/test/CodeGen/swift-call-conv.c
===
--- clang/test/CodeGen/swift-call-conv.c
+++ clang/test/CodeGen/swift-call-conv.c
@@ -6,3 +6,5 @@
 void __attribute__((__swiftcall__)) f(void) {}
 // CHECK-LABEL: define dso_local swiftcc void @f()
 
+void __attribute__((__swiftasynccall__)) f_async(void) {}
+// CHECK-LABEL: define dso_local swifttailcc void @f_async()
Index: clang/test/CodeGen/swift-async-call-conv.c
===
--- /dev/null
+++ clang/test/CodeGen/swift-async-call-conv.c
@@ -0,0 +1,184 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+
+// RUN: %clang_cc1 -x c++ -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY
+// RUN: %clang_cc1 -x c++ -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY
+// RUN: %clang_cc1 -x c++ -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY
+// RUN: %clang_cc1 -x c++ -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY
+// RUN: %clang_cc1 -x c++ -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY
+
+// Test tail call behavior when a swiftasynccall function is called
+// from another swiftasynccall function.
+
+#define SWIFTCALL __attribute__((swiftcall))
+#define SWIFTASYNCCALL __attribute__((swiftasynccall))
+#define ASYNC_CONTEXT __attribute__((swift_async_context))
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_leaf1{{.*}}(i8* swiftasync

[PATCH] D95984: [CodeGen] Fix codegen for __attribute__((swiftasynccall)).

2021-03-29 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: clang/lib/CodeGen/CGStmt.cpp:1240
+  if (auto *CE = dyn_cast(RV))
+::makeTailCallIfSwiftAsync(CE, Builder, CurFnInfo);
+}

What's with the explicit `::` here?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95984/new/

https://reviews.llvm.org/D95984

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D95984: [CodeGen] Fix codegen for __attribute__((swiftasynccall)).

2021-03-25 Thread Varun Gandhi via Phabricator via cfe-commits
varungandhi-apple updated this revision to Diff 333421.
varungandhi-apple added a comment.

Fix codegen + add tests for methods and function pointers.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95984/new/

https://reviews.llvm.org/D95984

Files:
  clang/lib/AST/ExprCXX.cpp
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/test/CodeGen/64bit-swiftcall.c
  clang/test/CodeGen/arm-swiftcall.c
  clang/test/CodeGen/swift-async-call-conv.c
  clang/test/CodeGen/swift-call-conv.c

Index: clang/test/CodeGen/swift-call-conv.c
===
--- clang/test/CodeGen/swift-call-conv.c
+++ clang/test/CodeGen/swift-call-conv.c
@@ -6,3 +6,5 @@
 void __attribute__((__swiftcall__)) f(void) {}
 // CHECK-LABEL: define dso_local swiftcc void @f()
 
+void __attribute__((__swiftasynccall__)) f_async(void) {}
+// CHECK-LABEL: define dso_local swifttailcc void @f_async()
Index: clang/test/CodeGen/swift-async-call-conv.c
===
--- /dev/null
+++ clang/test/CodeGen/swift-async-call-conv.c
@@ -0,0 +1,184 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+
+// RUN: %clang_cc1 -x c++ -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY
+// RUN: %clang_cc1 -x c++ -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY
+// RUN: %clang_cc1 -x c++ -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY
+// RUN: %clang_cc1 -x c++ -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY
+// RUN: %clang_cc1 -x c++ -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY
+
+// Test tail call behavior when a swiftasynccall function is called
+// from another swiftasynccall function.
+
+#define SWIFTCALL __attribute__((swiftcall))
+#define SWIFTASYNCCALL __attribute__((swiftasynccall))
+#define ASYNC_CONTEXT __attribute__((swift_async_context))
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_leaf1{{.*}}(i8* swiftasync
+SWIFTASYNCCALL void async_leaf1(char * ASYNC_CONTEXT ctx) {
+  *ctx += 1;
+}
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_leaf2{{.*}}(i8* swiftasync
+SWIFTASYNCCALL void async_leaf2(char * ASYNC_CONTEXT ctx) {
+  *ctx += 2;
+}
+
+#if __cplusplus
+  #define MYBOOL bool
+#else
+  #define MYBOOL _Bool
+#endif
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_branch{{.*}}i8* swiftasync
+// CHECK: musttail call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: musttail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_branch(MYBOOL b, char * ASYNC_CONTEXT ctx) {
+  if (b) {
+return async_leaf1(ctx);
+  } else {
+return async_leaf2(ctx);
+  }
+}
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_not_all_tail
+// CHECK-NOT:  musttail call swifttailcc void @{{.*}}async_leaf1
+// CHECK:  call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NOT:  ret void
+// CHECK:  musttail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_not_all_tail(char * ASYNC_CONTEXT ctx) {
+  async_leaf1(ctx);
+  return async_leaf2(ctx);
+}
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_loop
+// CHECK: musttail call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: musttail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+// CHECK: musttail call swifttailcc void @{{.*}}async_loop
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_loop(unsigned u, char * ASYNC_CONTEXT ctx) {
+  if (u == 0) {
+return async_leaf1(ctx);
+  } else if (u == 1) {
+return async_leaf2(ctx);
+  }
+  return async_loop(u - 2, ctx);
+}
+
+// Forward-declaration + mutual recursion is okay.
+
+SWIFTASYNCCALL void async_mutual_loop2(unsigned u, char * ASYNC_CONTEXT ctx);
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_mutual_loop1
+// CHECK: musttail call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: musttail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+// There is some bugginess around FileCheck's greediness/matching,
+// so skipping the check for async_mutual_loop2 here.
+SWIFTASYNCCALL void async_mutual_loop1(unsigned u, char * ASYNC_CONTEXT ctx) {
+  if (u == 0) {
+return async_leaf1(ctx);
+  } else if (u == 1) {
+return 

[PATCH] D95984: [CodeGen] Fix codegen for __attribute__((swiftasynccall)).

2021-03-11 Thread Varun Gandhi via Phabricator via cfe-commits
varungandhi-apple updated this revision to Diff 329889.
varungandhi-apple added a comment.

Use musttail call instead of tail call.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95984/new/

https://reviews.llvm.org/D95984

Files:
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/test/CodeGen/64bit-swiftcall.c
  clang/test/CodeGen/arm-swiftcall.c
  clang/test/CodeGen/swift-async-call-conv.c
  clang/test/CodeGen/swift-call-conv.c

Index: clang/test/CodeGen/swift-call-conv.c
===
--- clang/test/CodeGen/swift-call-conv.c
+++ clang/test/CodeGen/swift-call-conv.c
@@ -6,3 +6,5 @@
 void __attribute__((__swiftcall__)) f(void) {}
 // CHECK-LABEL: define dso_local swiftcc void @f()
 
+void __attribute__((__swiftasynccall__)) f_async(void) {}
+// CHECK-LABEL: define dso_local swifttailcc void @f_async()
Index: clang/test/CodeGen/swift-async-call-conv.c
===
--- /dev/null
+++ clang/test/CodeGen/swift-async-call-conv.c
@@ -0,0 +1,138 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+
+// RUN: %clang_cc1 -x c++ -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -x c++ -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -x c++ -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -x c++ -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -x c++ -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+
+// Test tail call behavior when a swiftasynccall function is called
+// from another swiftasynccall function.
+
+#define SWIFTCALL __attribute__((swiftcall))
+#define SWIFTASYNCCALL __attribute__((swiftasynccall))
+#define ASYNC_CONTEXT __attribute__((swift_async_context))
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_leaf1{{.*}}(i8* swiftasync
+SWIFTASYNCCALL void async_leaf1(char * ASYNC_CONTEXT ctx) {
+  *ctx += 1;
+}
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_leaf2{{.*}}(i8* swiftasync
+SWIFTASYNCCALL void async_leaf2(char * ASYNC_CONTEXT ctx) {
+  *ctx += 2;
+}
+
+#if __cplusplus
+  #define MYBOOL bool
+#else
+  #define MYBOOL _Bool
+#endif
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_branch{{.*}}i8* swiftasync
+// CHECK: musttail call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: musttail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_branch(MYBOOL b, char * ASYNC_CONTEXT ctx) {
+  if (b) {
+return async_leaf1(ctx);
+  } else {
+return async_leaf2(ctx);
+  }
+}
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_not_all_tail
+// CHECK-NOT:  musttail call swifttailcc void @{{.*}}async_leaf1
+// CHECK:  call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NOT:  ret void
+// CHECK:  musttail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_not_all_tail(char * ASYNC_CONTEXT ctx) {
+  async_leaf1(ctx);
+  return async_leaf2(ctx);
+}
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_loop
+// CHECK: musttail call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: musttail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+// CHECK: musttail call swifttailcc void @{{.*}}async_loop
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_loop(unsigned u, char * ASYNC_CONTEXT ctx) {
+  if (u == 0) {
+return async_leaf1(ctx);
+  } else if (u == 1) {
+return async_leaf2(ctx);
+  }
+  return async_loop(u - 2, ctx);
+}
+
+// Forward-declaration + mutual recursion is okay.
+
+SWIFTASYNCCALL void async_mutual_loop2(unsigned u, char * ASYNC_CONTEXT ctx);
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_mutual_loop1
+// CHECK: musttail call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: musttail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+// There is some bugginess around FileCheck's greediness/matching,
+// so skipping the check for async_mutual_loop2 here.
+SWIFTASYNCCALL void async_mutual_loop1(unsigned u, char * ASYNC_CONTEXT ctx) {
+  if (u == 0) {
+return async_leaf1(ctx);
+  } else if (u == 1) {
+return async_leaf2(ctx);
+  }
+  return async_mutual_loop2(u - 2, ctx);
+}
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_mutual_loop2
+// CHECK: musttail call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: musttail call swifttailcc void 

[PATCH] D95984: [CodeGen] Fix codegen for __attribute__((swiftasynccall)).

2021-03-02 Thread Varun Gandhi via Phabricator via cfe-commits
varungandhi-apple updated this revision to Diff 327510.
varungandhi-apple added a comment.

Add null check for callee; instead of using getFunctionType() directly.

Otherwise, it leads to a crash when compiling gtest-all.cc.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95984/new/

https://reviews.llvm.org/D95984

Files:
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/test/CodeGen/64bit-swiftcall.c
  clang/test/CodeGen/arm-swiftcall.c
  clang/test/CodeGen/swift-async-call-conv.c
  clang/test/CodeGen/swift-call-conv.c

Index: clang/test/CodeGen/swift-call-conv.c
===
--- clang/test/CodeGen/swift-call-conv.c
+++ clang/test/CodeGen/swift-call-conv.c
@@ -6,3 +6,5 @@
 void __attribute__((__swiftcall__)) f(void) {}
 // CHECK-LABEL: define dso_local swiftcc void @f()
 
+void __attribute__((__swiftasynccall__)) f_async(void) {}
+// CHECK-LABEL: define dso_local swifttailcc void @f_async()
Index: clang/test/CodeGen/swift-async-call-conv.c
===
--- /dev/null
+++ clang/test/CodeGen/swift-async-call-conv.c
@@ -0,0 +1,138 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+
+// RUN: %clang_cc1 -x c++ -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -x c++ -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -x c++ -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -x c++ -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -x c++ -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+
+// Test tail call behavior when a swiftasynccall function is called
+// from another swiftasynccall function.
+
+#define SWIFTCALL __attribute__((swiftcall))
+#define SWIFTASYNCCALL __attribute__((swiftasynccall))
+#define ASYNC_CONTEXT __attribute__((swift_async_context))
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_leaf1{{.*}}(i8* swiftasync
+SWIFTASYNCCALL void async_leaf1(char * ASYNC_CONTEXT ctx) {
+  *ctx += 1;
+}
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_leaf2{{.*}}(i8* swiftasync
+SWIFTASYNCCALL void async_leaf2(char * ASYNC_CONTEXT ctx) {
+  *ctx += 2;
+}
+
+#if __cplusplus
+  #define MYBOOL bool
+#else
+  #define MYBOOL _Bool
+#endif
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_branch{{.*}}i8* swiftasync
+// CHECK: tail call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: tail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_branch(MYBOOL b, char * ASYNC_CONTEXT ctx) {
+  if (b) {
+return async_leaf1(ctx);
+  } else {
+return async_leaf2(ctx);
+  }
+}
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_not_all_tail
+// CHECK-NOT:  tail call swifttailcc void @{{.*}}async_leaf1
+// CHECK:  call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NOT:  ret void
+// CHECK:  tail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_not_all_tail(char * ASYNC_CONTEXT ctx) {
+  async_leaf1(ctx);
+  return async_leaf2(ctx);
+}
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_loop
+// CHECK: tail call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: tail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+// CHECK: tail call swifttailcc void @{{.*}}async_loop
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_loop(unsigned u, char * ASYNC_CONTEXT ctx) {
+  if (u == 0) {
+return async_leaf1(ctx);
+  } else if (u == 1) {
+return async_leaf2(ctx);
+  }
+  return async_loop(u - 2, ctx);
+}
+
+// Forward-declaration + mutual recursion is okay.
+
+SWIFTASYNCCALL void async_mutual_loop2(unsigned u, char * ASYNC_CONTEXT ctx);
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_mutual_loop1
+// CHECK: tail call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: tail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+// There is some bugginess around FileCheck's greediness/matching,
+// so skipping the check for async_mutual_loop2 here.
+SWIFTASYNCCALL void async_mutual_loop1(unsigned u, char * ASYNC_CONTEXT ctx) {
+  if (u == 0) {
+return async_leaf1(ctx);
+  } else if (u == 1) {
+return async_leaf2(ctx);
+  }
+  return async_mutual_loop2(u - 2, ctx);
+}
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_mutual_loop2
+// CHECK: tail call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NEXT: ret void

[PATCH] D95984: [CodeGen] Fix codegen for __attribute__((swiftasynccall)).

2021-03-01 Thread John McCall via Phabricator via cfe-commits
rjmccall accepted this revision.
rjmccall added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95984/new/

https://reviews.llvm.org/D95984

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D95984: [CodeGen] Fix codegen for __attribute__((swiftasynccall)).

2021-02-26 Thread Varun Gandhi via Phabricator via cfe-commits
varungandhi-apple updated this revision to Diff 326762.
varungandhi-apple added a comment.

Added checks for C++.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95984/new/

https://reviews.llvm.org/D95984

Files:
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/test/CodeGen/64bit-swiftcall.c
  clang/test/CodeGen/arm-swiftcall.c
  clang/test/CodeGen/swift-async-call-conv.c
  clang/test/CodeGen/swift-call-conv.c

Index: clang/test/CodeGen/swift-call-conv.c
===
--- clang/test/CodeGen/swift-call-conv.c
+++ clang/test/CodeGen/swift-call-conv.c
@@ -6,3 +6,5 @@
 void __attribute__((__swiftcall__)) f(void) {}
 // CHECK-LABEL: define dso_local swiftcc void @f()
 
+void __attribute__((__swiftasynccall__)) f_async(void) {}
+// CHECK-LABEL: define dso_local swifttailcc void @f_async()
Index: clang/test/CodeGen/swift-async-call-conv.c
===
--- /dev/null
+++ clang/test/CodeGen/swift-async-call-conv.c
@@ -0,0 +1,138 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+
+// RUN: %clang_cc1 -x c++ -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -x c++ -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -x c++ -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -x c++ -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -x c++ -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+
+// Test tail call behavior when a swiftasynccall function is called
+// from another swiftasynccall function.
+
+#define SWIFTCALL __attribute__((swiftcall))
+#define SWIFTASYNCCALL __attribute__((swiftasynccall))
+#define ASYNC_CONTEXT __attribute__((swift_async_context))
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_leaf1{{.*}}(i8* swiftasync
+SWIFTASYNCCALL void async_leaf1(char * ASYNC_CONTEXT ctx) {
+  *ctx += 1;
+}
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_leaf2{{.*}}(i8* swiftasync
+SWIFTASYNCCALL void async_leaf2(char * ASYNC_CONTEXT ctx) {
+  *ctx += 2;
+}
+
+#if __cplusplus
+  #define MYBOOL bool
+#else
+  #define MYBOOL _Bool
+#endif
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_branch{{.*}}i8* swiftasync
+// CHECK: tail call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: tail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_branch(MYBOOL b, char * ASYNC_CONTEXT ctx) {
+  if (b) {
+return async_leaf1(ctx);
+  } else {
+return async_leaf2(ctx);
+  }
+}
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_not_all_tail
+// CHECK-NOT:  tail call swifttailcc void @{{.*}}async_leaf1
+// CHECK:  call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NOT:  ret void
+// CHECK:  tail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_not_all_tail(char * ASYNC_CONTEXT ctx) {
+  async_leaf1(ctx);
+  return async_leaf2(ctx);
+}
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_loop
+// CHECK: tail call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: tail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+// CHECK: tail call swifttailcc void @{{.*}}async_loop
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_loop(unsigned u, char * ASYNC_CONTEXT ctx) {
+  if (u == 0) {
+return async_leaf1(ctx);
+  } else if (u == 1) {
+return async_leaf2(ctx);
+  }
+  return async_loop(u - 2, ctx);
+}
+
+// Forward-declaration + mutual recursion is okay.
+
+SWIFTASYNCCALL void async_mutual_loop2(unsigned u, char * ASYNC_CONTEXT ctx);
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_mutual_loop1
+// CHECK: tail call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: tail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+// There is some bugginess around FileCheck's greediness/matching,
+// so skipping the check for async_mutual_loop2 here.
+SWIFTASYNCCALL void async_mutual_loop1(unsigned u, char * ASYNC_CONTEXT ctx) {
+  if (u == 0) {
+return async_leaf1(ctx);
+  } else if (u == 1) {
+return async_leaf2(ctx);
+  }
+  return async_mutual_loop2(u - 2, ctx);
+}
+
+// CHECK-LABEL: swifttailcc void {{.*}}async_mutual_loop2
+// CHECK: tail call swifttailcc void @{{.*}}async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: tail call swifttailcc void @{{.*}}async_leaf2
+// CHECK-NEXT: ret void
+// CHECK: tail call 

[PATCH] D95984: [CodeGen] Fix codegen for __attribute__((swiftasynccall)).

2021-02-24 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

Please add some C++ tests, just in case.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95984/new/

https://reviews.llvm.org/D95984

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D95984: [CodeGen] Fix codegen for __attribute__((swiftasynccall)).

2021-02-24 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

Okay, seems fine to me.




Comment at: clang/lib/CodeGen/CGStmt.cpp:1156
+  CallingConv::CC_SwiftAsync)) {
+auto CI = cast(()->back());
+CI->setTailCallKind(llvm::CallInst::TCK_Tail);

Hmm.  I guess this should work in any situation where we can successfully 
actually do a tail call.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95984/new/

https://reviews.llvm.org/D95984

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D95984: [CodeGen] Fix codegen for __attribute__((swiftasynccall)).

2021-02-24 Thread Varun Gandhi via Phabricator via cfe-commits
varungandhi-apple updated this revision to Diff 326203.
varungandhi-apple added a comment.

Generate tail call when doing codegen for return statement.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95984/new/

https://reviews.llvm.org/D95984

Files:
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/test/CodeGen/64bit-swiftcall.c
  clang/test/CodeGen/arm-swiftcall.c
  clang/test/CodeGen/swift-async-call-conv.c
  clang/test/CodeGen/swift-call-conv.c

Index: clang/test/CodeGen/swift-call-conv.c
===
--- clang/test/CodeGen/swift-call-conv.c
+++ clang/test/CodeGen/swift-call-conv.c
@@ -6,3 +6,5 @@
 void __attribute__((__swiftcall__)) f(void) {}
 // CHECK-LABEL: define dso_local swiftcc void @f()
 
+void __attribute__((__swiftasynccall__)) f_async(void) {}
+// CHECK-LABEL: define dso_local swifttailcc void @f_async()
Index: clang/test/CodeGen/swift-async-call-conv.c
===
--- /dev/null
+++ clang/test/CodeGen/swift-async-call-conv.c
@@ -0,0 +1,126 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+
+// Test tail call behavior when a swiftasynccall function is called
+// from another swiftasynccall function.
+
+#define SWIFTCALL __attribute__((swiftcall))
+#define SWIFTASYNCCALL __attribute__((swiftasynccall))
+#define ASYNC_CONTEXT __attribute__((swift_async_context))
+
+// CHECK-LABEL: swifttailcc void @async_leaf1(i8* swiftasync
+SWIFTASYNCCALL void async_leaf1(char * ASYNC_CONTEXT ctx) {
+  *ctx += 1;
+}
+
+// CHECK-LABEL: swifttailcc void @async_leaf2(i8* swiftasync
+SWIFTASYNCCALL void async_leaf2(char * ASYNC_CONTEXT ctx) {
+  *ctx += 2;
+}
+
+// CHECK-LABEL: swifttailcc void @async_branch
+// CHECK: tail call swifttailcc void @async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: tail call swifttailcc void @async_leaf2
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_branch(_Bool b, char * ASYNC_CONTEXT ctx) {
+  if (b) {
+return async_leaf1(ctx);
+  } else {
+return async_leaf2(ctx);
+  }
+}
+
+// CHECK-LABEL: swifttailcc void @async_not_all_tail
+// CHECK-NOT:  tail call swifttailcc void @async_leaf1
+// CHECK:  call swifttailcc void @async_leaf1
+// CHECK-NOT:  ret void
+// CHECK:  tail call swifttailcc void @async_leaf2
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_not_all_tail(char * ASYNC_CONTEXT ctx) {
+  async_leaf1(ctx);
+  return async_leaf2(ctx);
+}
+
+// CHECK-LABEL: swifttailcc void @async_loop
+// CHECK: tail call swifttailcc void @async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: tail call swifttailcc void @async_leaf2
+// CHECK-NEXT: ret void
+// CHECK: tail call swifttailcc void @async_loop
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_loop(unsigned u, char * ASYNC_CONTEXT ctx) {
+  if (u == 0) {
+return async_leaf1(ctx);
+  } else if (u == 1) {
+return async_leaf2(ctx);
+  }
+  return async_loop(u - 2, ctx);
+}
+
+// Forward-declaration + mutual recursion is okay.
+
+SWIFTASYNCCALL void async_mutual_loop2(unsigned u, char * ASYNC_CONTEXT ctx);
+
+// CHECK: swifttailcc void @async_mutual_loop
+// CHECK: tail call swifttailcc void @async_leaf
+// CHECK-NEXT: ret void
+// CHECK: tail call swifttailcc void @async_leaf
+// CHECK-NEXT: ret void
+// CHECK: tail call swifttailcc void @async_mutual_loop
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_mutual_loop1(unsigned u, char * ASYNC_CONTEXT ctx) {
+  if (u == 0) {
+return async_leaf1(ctx);
+  } else if (u == 1) {
+return async_leaf2(ctx);
+  }
+  return async_mutual_loop2(u - 2, ctx);
+}
+
+// CHECK: swifttailcc void @async_mutual_loop
+// CHECK: tail call swifttailcc void @async_leaf1
+// CHECK-NEXT: ret void
+// CHECK: tail call swifttailcc void @async_leaf2
+// CHECK-NEXT: ret void
+// CHECK: tail call swifttailcc void @async_mutual_loop1
+// CHECK-NEXT: ret void
+SWIFTASYNCCALL void async_mutual_loop2(unsigned u, char * ASYNC_CONTEXT ctx) {
+  if (u == 0) {
+return async_leaf1(ctx);
+  } else if (u == 1) {
+return async_leaf2(ctx);
+  }
+  return async_mutual_loop1(u - 2, ctx);
+}
+
+// When swiftasynccall functions are called by non-swiftasynccall functions,
+// the call isn't marked as a tail call.
+
+// CHECK-LABEL: swiftcc i8 @sync_calling_async
+// CHECK-NOT: tail call
+// CHECK: call swifttailcc void @async_branch
+// CHECK-NOT: tail call
+// CHECK: call swifttailcc void @async_loop
+SWIFTCALL char sync_calling_async(_Bool b, unsigned u) {
+  char x = 'a';
+  async_branch(b, );
+  async_loop(u, );
+  

[PATCH] D95984: [CodeGen] Fix codegen for __attribute__((swiftasynccall)).

2021-02-03 Thread Varun Gandhi via Phabricator via cfe-commits
varungandhi-apple added a comment.

I am planning to add more tests, figured it is better to put up the patch 
sooner rather than later.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95984/new/

https://reviews.llvm.org/D95984

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D95984: [CodeGen] Fix codegen for __attribute__((swiftasynccall)).

2021-02-03 Thread Varun Gandhi via Phabricator via cfe-commits
varungandhi-apple created this revision.
varungandhi-apple added a reviewer: rjmccall.
varungandhi-apple requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

1. It should be mapped to LLVM's swifttailcc, which is now available.
2. We should make sure we generate a tail call instead of an ordinary call.

Fixes rdar://73762895.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D95984

Files:
  clang/lib/CodeGen/CGCall.cpp
  clang/test/CodeGen/64bit-swiftcall.c
  clang/test/CodeGen/arm-swiftcall.c
  clang/test/CodeGen/swift-async-call-conv.c
  clang/test/CodeGen/swift-call-conv.c

Index: clang/test/CodeGen/swift-call-conv.c
===
--- clang/test/CodeGen/swift-call-conv.c
+++ clang/test/CodeGen/swift-call-conv.c
@@ -7,3 +7,5 @@
 void __attribute__((__swiftcall__)) f(void) {}
 // CHECK-LABEL: define dso_local swiftcc void @f()
 
+void __attribute__((__swiftasynccall__)) f_async(void) {}
+// CHECK-LABEL: define dso_local swifttailcc void @f_async()
Index: clang/test/CodeGen/swift-async-call-conv.c
===
--- /dev/null
+++ clang/test/CodeGen/swift-async-call-conv.c
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s
+
+// Test tail call behavior when a swiftasynccall function is called
+// from another swiftasynccall function.
+
+#define SWIFTCALL __attribute__((swiftcall))
+#define SWIFTASYNCCALL __attribute__((swiftasynccall))
+#define ASYNC_CONTEXT __attribute__((swift_async_context))
+
+// CHECK-LABEL: swifttailcc void @async_leaf1(i8* swiftasync
+SWIFTASYNCCALL void async_leaf1(char * ASYNC_CONTEXT ctx) {
+  *ctx += 1;
+}
+
+// CHECK-LABEL: swifttailcc void @async_leaf2(i8* swiftasync
+SWIFTASYNCCALL void async_leaf2(char * ASYNC_CONTEXT ctx) {
+  *ctx += 2;
+}
+
+// CHECK-LABEL: swifttailcc void @async_branch
+// CHECK: tail call swifttailcc void @async_leaf1
+// CHECK: tail call swifttailcc void @async_leaf2
+SWIFTASYNCCALL void async_branch(_Bool b, char * ASYNC_CONTEXT ctx) {
+  if (b) {
+return async_leaf1(ctx);
+  } else {
+return async_leaf2(ctx);
+  }
+}
+
+// CHECK-LABEL: swifttailcc void @async_loop
+// CHECK: tail call swifttailcc void @async_leaf1
+// CHECK: tail call swifttailcc void @async_leaf2
+// CHECK: tail call swifttailcc void @async_loop
+SWIFTASYNCCALL void async_loop(unsigned u, char * ASYNC_CONTEXT ctx) {
+  if (u == 0) {
+return async_leaf1(ctx);
+  } else if (u == 1) {
+return async_leaf2(ctx);
+  }
+  return async_loop(u - 2, ctx);
+}
+
+// Forward-declaration + mutual recursion is okay.
+
+SWIFTASYNCCALL void async_mutual_loop2(unsigned u, char * ASYNC_CONTEXT ctx);
+
+// CHECK: swifttailcc void @async_mutual_loop
+// CHECK: tail call swifttailcc void @async_leaf
+// CHECK: tail call swifttailcc void @async_leaf
+// CHECK: tail call swifttailcc void @async_mutual_loop
+SWIFTASYNCCALL void async_mutual_loop1(unsigned u, char * ASYNC_CONTEXT ctx) {
+  if (u == 0) {
+return async_leaf1(ctx);
+  } else if (u == 1) {
+return async_leaf2(ctx);
+  }
+  return async_mutual_loop2(u - 2, ctx);
+}
+
+// CHECK: swifttailcc void @async_mutual_loop
+// CHECK: tail call swifttailcc void @async_leaf1
+// CHECK: tail call swifttailcc void @async_leaf2
+// CHECK: tail call swifttailcc void @async_mutual_loop1
+SWIFTASYNCCALL void async_mutual_loop2(unsigned u, char * ASYNC_CONTEXT ctx) {
+  if (u == 0) {
+return async_leaf1(ctx);
+  } else if (u == 1) {
+return async_leaf2(ctx);
+  }
+  return async_mutual_loop1(u - 2, ctx);
+}
+
+// When swiftasynccall functions are called by non-swiftasynccall functions,
+// the call isn't marked as a tail call.
+
+// CHECK-LABEL: swiftcc i8 @sync_calling_async
+// CHECK-NOT: tail call
+// CHECK: call swifttailcc void @async_branch
+// CHECK-NOT: tail call
+// CHECK: call swifttailcc void @async_loop
+SWIFTCALL char sync_calling_async(_Bool b, unsigned u) {
+  char x = 'a';
+  async_branch(b, );
+  async_loop(u, );
+  return x;
+}
+
+// CHECK-LABEL: i8 @c_calling_async
+// CHECK-NOT: tail call
+// CHECK: call swifttailcc void @async_branch
+// CHECK-NOT: tail call
+// CHECK: call swifttailcc void @async_loop
+char c_calling_async(_Bool b, unsigned u) {
+  char x = 'a';
+  async_branch(b, );
+  async_loop(u, );
+  return x;
+}
+
Index: clang/test/CodeGen/arm-swiftcall.c
===
--- clang/test/CodeGen/arm-swiftcall.c
+++ clang/test/CodeGen/arm-swiftcall.c
@@ -27,9 +27,15 @@
 SWIFTCALL