|
| 1 | +// RUN: %clang_cc1 -std=c++1z -fexceptions -fcxx-exceptions -fopencilk -ftapir=none -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s |
| 2 | +// expected-no-diagnostics |
| 3 | +extern "C" int sleep(int); |
| 4 | + |
| 5 | +struct S { |
| 6 | + int s; |
| 7 | + S() noexcept; |
| 8 | + ~S(); |
| 9 | +}; |
| 10 | + |
| 11 | +int __attribute__((noinline)) spawning() |
| 12 | +{ |
| 13 | + S s1; |
| 14 | + cilk_spawn sleep(3); |
| 15 | + try { |
| 16 | + S s2; |
| 17 | + cilk_spawn sleep(1); |
| 18 | + } catch (int x) { |
| 19 | + return x; |
| 20 | + } |
| 21 | + sleep(2); |
| 22 | + return 0; |
| 23 | +} |
| 24 | + |
| 25 | +// CHECK: define dso_local noundef i32 @_Z8spawningv() |
| 26 | +// CHECK: entry: |
| 27 | +// CHECK-NEXT: %[[RETVAL:.+]] = alloca i32 |
| 28 | +// CHECK-NEXT: %[[S1:.+]] = alloca %struct.S |
| 29 | +// CHECK-NEXT: %[[SYNCREG:.+]] = call token @llvm.syncregion.start() |
| 30 | +// CHECK-NEXT: alloca ptr |
| 31 | +// CHECK-NEXT: alloca i32 |
| 32 | +// CHECK-NEXT: %[[CLEANUP_DEST_SLOT:.+]] = alloca i32 |
| 33 | +// CHECK-NEXT: call void @_ZN1SC1Ev(ptr {{.*}}%[[S1]]) |
| 34 | +// CHECK: detach within %[[SYNCREG]], label %[[DETACHED:.+]], label %[[CONTINUE:.+]] unwind |
| 35 | + |
| 36 | +// CHECK: [[CONTINUE]]: |
| 37 | +// CHECK: %[[TF1:.+]] = call token @llvm.taskframe.create() |
| 38 | +// CHECK: %[[S2:.+]] = alloca %struct.S |
| 39 | +// CHECK: %[[SYNCREG12:.+]] = call token @llvm.syncregion.start() |
| 40 | +// CHECK-NEXT: alloca ptr |
| 41 | +// CHECK-NEXT: alloca i32 |
| 42 | +// CHECK-NEXT: %[[X:.+]] = alloca i32 |
| 43 | +// CHECK-NEXT: call void @_ZN1SC1Ev(ptr {{.*}}%[[S2]]) |
| 44 | +// CHECK: %[[TF2:.+]] = call token @llvm.taskframe.create() |
| 45 | +// CHECK: detach within %[[SYNCREG12]], label %[[DETACHED13:.+]], label %[[CONTINUE27:.+]] unwind label %[[LPAD24:.+]] |
| 46 | + |
| 47 | +// CHECK: [[CONTINUE27]]: |
| 48 | +// CHECK-NEXT: sync within %[[SYNCREG12]], label %[[SYNC_CONTINUE:.+]] |
| 49 | + |
| 50 | +// CHECK: [[SYNC_CONTINUE]]: |
| 51 | +// CHECK-NEXT: invoke void @llvm.sync.unwind(token %[[SYNCREG12]]) |
| 52 | +// CHECK-NEXT: to label %[[INVOKE_CONT36:.+]] unwind label %[[LPAD33:.+]] |
| 53 | + |
| 54 | +// CHECK: [[INVOKE_CONT36]]: |
| 55 | +// CHECK-NEXT: call void @_ZN1SD1Ev(ptr {{.*}}%[[S2]]) |
| 56 | +// CHECK-NEXT: br label %[[TRY_CONT:.+]] |
| 57 | + |
| 58 | +// CHECK: [[LPAD24]]: |
| 59 | +// CHECK-NEXT: landingpad |
| 60 | +// CHECK-NEXT: cleanup |
| 61 | +// CHECK: invoke void @llvm.taskframe.resume.sl_p0i32s(token %[[TF2]], |
| 62 | +// CHECK-NEXT: to label %[[UNREACHABLE:.+]] unwind label %[[LPAD33]] |
| 63 | + |
| 64 | +// CHECK: [[LPAD33]]: |
| 65 | +// CHECK-NEXT: landingpad |
| 66 | +// CHECK-NEXT: cleanup |
| 67 | +// CHECK-NEXT: catch ptr @_ZTIi |
| 68 | +// CHECK: call void @_ZN1SD1Ev(ptr {{.*}}%[[S2]]) |
| 69 | + |
| 70 | +// CHECK: call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) |
| 71 | +// CHECK: br i1 {{.+}}, label %[[CATCH:.+]], label %[[EHCLEANUP44:.+]] |
| 72 | + |
| 73 | +// CHECK: [[CATCH]]: |
| 74 | +// CHECK: %[[CAUGHT:.+]] = call ptr @__cxa_begin_catch(ptr |
| 75 | +// CHECK-NEXT: %[[LOAD23:.+]] = load i32, ptr %[[CAUGHT]] |
| 76 | +// CHECK-NEXT: store i32 %[[LOAD23]], ptr %[[X]] |
| 77 | +// CHECK-NEXT: %[[LOAD24:.+]] = load i32, ptr %[[X]] |
| 78 | +// CHECK-NEXT: store i32 %[[LOAD24]], ptr %[[RETVAL]] |
| 79 | +// CHECK-NEXT: sync within %[[SYNCREG]], label %[[SYNC_CONTINUE40:.+]] |
| 80 | + |
| 81 | +// CHECK: [[SYNC_CONTINUE40]]: |
| 82 | +// CHECK-NEXT: invoke void @llvm.sync.unwind(token %[[SYNCREG]]) |
| 83 | +// CHECK-NEXT: to label %[[INVOKE_CONT42:.+]] unwind label %[[LPAD41:.+]] |
| 84 | + |
| 85 | +// CHECK: [[INVOKE_CONT42]]: |
| 86 | +// CHECK-NEXT: store i32 1, ptr %[[CLEANUP_DEST_SLOT]] |
| 87 | +// CHECK-NEXT: call void @__cxa_end_catch() |
| 88 | +// CHECK-NEXT: br label %[[CLEANUP:.+]] |
| 89 | + |
| 90 | +// CHECK: [[LPAD41]]: |
| 91 | +// CHECK-NEXT: landingpad |
| 92 | +// CHECK-NEXT: cleanup |
| 93 | +// CHECK: call void @__cxa_end_catch() |
| 94 | +// CHECK-NEXT: br label %[[EHCLEANUP44]] |
| 95 | + |
| 96 | +// CHECK: [[TRY_CONT]]: |
| 97 | +// CHECK-NEXT: store i32 0, ptr %[[CLEANUP_DEST_SLOT]] |
| 98 | +// CHECK-NEXT: br label %[[CLEANUP]] |
| 99 | + |
| 100 | +// CHECK: [[CLEANUP]]: |
| 101 | +// CHECK-NEXT: call void @llvm.taskframe.end(token %[[TF1]]) |
| 102 | +// CHECK-NEXT: %[[CLEANUP_DEST:.+]] = load i32, ptr %[[CLEANUP_DEST_SLOT]] |
| 103 | +// CHECK-NEXT: switch i32 %[[CLEANUP_DEST]], label %[[CLEANUP53:.+]] [ |
| 104 | +// CHECK-NEXT: i32 0, label %[[CLEANUP_CONT:.+]] |
| 105 | +// CHECK-NEXT: ] |
| 106 | + |
| 107 | +// CHECK: [[CLEANUP_CONT]]: |
| 108 | +// CHECK-NEXT: invoke i32 @sleep(i32 {{.*}}2) |
| 109 | +// CHECK-NEXT: to label %[[INVOKE_CONT49:.+]] unwind |
| 110 | + |
| 111 | +// CHECK: [[INVOKE_CONT49]]: |
| 112 | +// CHECK-NEXT: store i32 0, ptr %[[RETVAL]] |
| 113 | +// CHECK-NEXT: sync within %[[SYNCREG]], label %[[SYNC_CONTINUE51:.+]] |
| 114 | + |
| 115 | +// CHECK: [[SYNC_CONTINUE51]]: |
| 116 | +// CHECK-NEXT: invoke void @llvm.sync.unwind(token %[[SYNCREG]]) |
| 117 | +// CHECK-NEXT: to label %[[INVOKE_CONT52:.+]] unwind |
| 118 | + |
| 119 | +// CHECK: [[INVOKE_CONT52]]: |
| 120 | +// CHECK-NEXT: store i32 1, ptr %[[CLEANUP_DEST_SLOT]] |
| 121 | +// CHECK-NEXT: br label %[[CLEANUP53]] |
| 122 | + |
| 123 | +// CHECK: [[EHCLEANUP44]]: |
| 124 | +// CHECK: invoke void @llvm.taskframe.resume.sl_p0i32s(token %[[TF1]], |
| 125 | +// CHECK-NEXT: to label %[[UNREACHABLE]] unwind |
| 126 | + |
| 127 | +// CHECK: [[CLEANUP53]]: |
| 128 | +// CHECK-NEXT: sync within %[[SYNCREG]], label %[[SYNC_CONTINUE54:.+]] |
| 129 | + |
| 130 | +// CHECK: [[SYNC_CONTINUE54]]: |
| 131 | +// CHECK-NEXT: invoke void @llvm.sync.unwind(token %[[SYNCREG]]) |
| 132 | +// CHECK-NEXT: to label %[[INVOKE_CONT55:.+]] unwind |
| 133 | + |
| 134 | +// CHECK: [[INVOKE_CONT55]]: |
| 135 | +// CHECK-NEXT: call void @_ZN1SD1Ev(ptr {{.*}}%[[S1]]) |
| 136 | +// CHECK-NEXT: %[[LOAD28:.+]] = load i32, ptr %[[RETVAL]] |
| 137 | +// CHECK-NEXT: ret i32 %[[LOAD28]] |
0 commit comments