brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.5 KiB · 3951169 Raw
201 lines · c
1// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s2// RUN: %clang_cc1 -no-enable-noundef-analysis -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s3// RUN: %clang_cc1 -no-enable-noundef-analysis -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s4// RUN: %clang_cc1 -no-enable-noundef-analysis -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s5// RUN: %clang_cc1 -no-enable-noundef-analysis -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s6 7// RUN: %clang_cc1 -no-enable-noundef-analysis -x c++ -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY8// RUN: %clang_cc1 -no-enable-noundef-analysis -x c++ -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY9// RUN: %clang_cc1 -no-enable-noundef-analysis -x c++ -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY10// RUN: %clang_cc1 -no-enable-noundef-analysis -x c++ -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY11// RUN: %clang_cc1 -no-enable-noundef-analysis -x c++ -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY12 13// Test tail call behavior when a swiftasynccall function is called14// from another swiftasynccall function.15 16#define SWIFTCALL __attribute__((swiftcall))17#define SWIFTASYNCCALL __attribute__((swiftasynccall))18#define ASYNC_CONTEXT __attribute__((swift_async_context))19 20// CHECK-LABEL: swifttailcc void {{.*}}async_leaf1{{.*}}(ptr swiftasync21SWIFTASYNCCALL void async_leaf1(char * ASYNC_CONTEXT ctx) {22  *ctx += 1;23}24 25// CHECK-LABEL: swifttailcc void {{.*}}async_leaf2{{.*}}(ptr swiftasync26SWIFTASYNCCALL void async_leaf2(char * ASYNC_CONTEXT ctx) {27  *ctx += 2;28}29 30#if __cplusplus31  #define MYBOOL bool32#else33  #define MYBOOL _Bool34#endif35 36// CHECK-LABEL: swifttailcc void {{.*}}async_branch{{.*}}ptr swiftasync37// CHECK: musttail call swifttailcc void @{{.*}}async_leaf138// CHECK-NEXT: ret void39// CHECK: musttail call swifttailcc void @{{.*}}async_leaf240// CHECK-NEXT: ret void41SWIFTASYNCCALL void async_branch(MYBOOL b, char * ASYNC_CONTEXT ctx) {42  if (b) {43    return async_leaf1(ctx);44  } else {45    return async_leaf2(ctx);46  }47}48 49// CHECK-LABEL: swifttailcc void {{.*}}async_not_all_tail50// CHECK-NOT:  musttail call swifttailcc void @{{.*}}async_leaf151// CHECK:      call swifttailcc void @{{.*}}async_leaf152// CHECK-NOT:  ret void53// CHECK:      musttail call swifttailcc void @{{.*}}async_leaf254// CHECK-NEXT: ret void55SWIFTASYNCCALL void async_not_all_tail(char * ASYNC_CONTEXT ctx) {56  async_leaf1(ctx);57  return async_leaf2(ctx);58}59 60// CHECK-LABEL: swifttailcc void {{.*}}async_loop61// CHECK: musttail call swifttailcc void @{{.*}}async_leaf162// CHECK-NEXT: ret void63// CHECK: musttail call swifttailcc void @{{.*}}async_leaf264// CHECK-NEXT: ret void65// CHECK: musttail call swifttailcc void @{{.*}}async_loop66// CHECK-NEXT: ret void67SWIFTASYNCCALL void async_loop(unsigned u, char * ASYNC_CONTEXT ctx) {68  if (u == 0) {69    return async_leaf1(ctx);70  } else if (u == 1) {71    return async_leaf2(ctx);72  }73  return async_loop(u - 2, ctx);74}75 76// Forward-declaration + mutual recursion is okay.77 78SWIFTASYNCCALL void async_mutual_loop2(unsigned u, char * ASYNC_CONTEXT ctx);79 80// CHECK-LABEL: swifttailcc void {{.*}}async_mutual_loop181// CHECK: musttail call swifttailcc void @{{.*}}async_leaf182// CHECK-NEXT: ret void83// CHECK: musttail call swifttailcc void @{{.*}}async_leaf284// CHECK-NEXT: ret void85// There is some bugginess around FileCheck's greediness/matching,86// so skipping the check for async_mutual_loop2 here.87SWIFTASYNCCALL void async_mutual_loop1(unsigned u, char * ASYNC_CONTEXT ctx) {88  if (u == 0) {89    return async_leaf1(ctx);90  } else if (u == 1) {91    return async_leaf2(ctx);92  }93  return async_mutual_loop2(u - 2, ctx);94}95 96// CHECK-LABEL: swifttailcc void {{.*}}async_mutual_loop297// CHECK: musttail call swifttailcc void @{{.*}}async_leaf198// CHECK-NEXT: ret void99// CHECK: musttail call swifttailcc void @{{.*}}async_leaf2100// CHECK-NEXT: ret void101// CHECK: musttail call swifttailcc void @{{.*}}async_mutual_loop1102// CHECK-NEXT: ret void103SWIFTASYNCCALL void async_mutual_loop2(unsigned u, char * ASYNC_CONTEXT ctx) {104  if (u == 0) {105    return async_leaf1(ctx);106  } else if (u == 1) {107    return async_leaf2(ctx);108  }109  return async_mutual_loop1(u - 2, ctx);110}111 112// When swiftasynccall functions are called by non-swiftasynccall functions,113// the call isn't marked as a tail call.114 115// CHECK-LABEL: swiftcc i8 {{.*}}sync_calling_async116// CHECK-NOT: tail call117// CHECK: call swifttailcc void @{{.*}}async_branch118// CHECK-NOT: tail call119// CHECK: call swifttailcc void @{{.*}}async_loop120SWIFTCALL char sync_calling_async(MYBOOL b, unsigned u) {121  char x = 'a';122  async_branch(b, &x);123  async_loop(u, &x);124  return x;125}126 127// CHECK-LABEL: i8 {{.*}}c_calling_async128// CHECK-NOT: tail call129// CHECK: call swifttailcc void @{{.*}}async_branch130// CHECK-NOT: tail call131// CHECK: call swifttailcc void @{{.*}}async_loop132char c_calling_async(MYBOOL b, unsigned u) {133  char x = 'a';134  async_branch(b, &x);135  async_loop(u, &x);136  return x;137}138 139#if __cplusplus140struct S {141  SWIFTASYNCCALL void (*fptr)(char * ASYNC_CONTEXT);142 143  SWIFTASYNCCALL void async_leaf_method(char * ASYNC_CONTEXT ctx) {144    *ctx += 1;145  }146  SWIFTASYNCCALL void async_nonleaf_method1(char * ASYNC_CONTEXT ctx) {147    return async_leaf_method(ctx);148  }149  SWIFTASYNCCALL void async_nonleaf_method2(char * ASYNC_CONTEXT ctx) {150    return this->async_leaf_method(ctx);151  }152};153 154SWIFTASYNCCALL void (S::*async_leaf_method_ptr)(char * ASYNC_CONTEXT) = &S::async_leaf_method;155 156// CPPONLY-LABEL: swifttailcc void {{.*}}async_struct_field_and_methods157// CPPONLY: musttail call swifttailcc void %{{[0-9]+}}158// CPPONLY: musttail call swifttailcc void @{{.*}}async_nonleaf_method1159// CPPONLY: musttail call swifttailcc void %{{[0-9]+}}160// CPPONLY: musttail call swifttailcc void @{{.*}}async_nonleaf_method2161// CPPONLY-NOT: musttail call swifttailcc void @{{.*}}async_leaf_method162// ^ TODO: Member pointers should also work.163SWIFTASYNCCALL void async_struct_field_and_methods(int i, S &sref, S *sptr) {164  char x = 'a';165  if (i == 0) {166    return (*sref.fptr)(&x);167  } else if (i == 1) {168    return sref.async_nonleaf_method1(&x);169  } else if (i == 2) {170    return (*(sptr->fptr))(&x);171  } else if (i == 3) {172    return sptr->async_nonleaf_method2(&x);173  } else if (i == 4) {174    return (sref.*async_leaf_method_ptr)(&x);175  }176  return (sptr->*async_leaf_method_ptr)(&x);177}178 179// CPPONLY-LABEL: define{{.*}} swifttailcc void @{{.*}}async_nonleaf_method1180// CPPONLY: musttail call swifttailcc void @{{.*}}async_leaf_method181 182// CPPONLY-LABEL: define{{.*}} swifttailcc void @{{.*}}async_nonleaf_method2183// CPPONLY: musttail call swifttailcc void @{{.*}}async_leaf_method184#endif185 186// Passing this as an argument requires a coerce-and-expand operation,187// which requires a temporary.  Make sure that cleaning up that temporary188// doesn't mess around with the musttail handling.189struct coerce_and_expand {190  char a,b,c,d;191};192struct coerce_and_expand return_coerced(void);193SWIFTASYNCCALL void take_coerced_async(struct coerce_and_expand);194 195// CHECK-LABEL: swifttailcc void @{{.*}}test_coerced196SWIFTASYNCCALL void test_coerced() {197  // CHECK:      musttail call swifttailcc void @{{.*}}take_coerced_async198  // CHECK-NEXT: ret void199  return take_coerced_async(return_coerced());200}201