Skip to content

Commit 5d8fc93

Browse files
committed
[CGCilk] Fix crash when removing taskframe.end cleanup block for try-catch taskframe when the catch returns from the parent function.
1 parent 1eb5f61 commit 5d8fc93

2 files changed

Lines changed: 138 additions & 1 deletion

File tree

clang/lib/CodeGen/CGCilk.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ CodeGenFunction::TaskFrameScope::~TaskFrameScope() {
412412
return;
413413

414414
// Pop the taskframe.
415-
CGF.PopCleanupBlock(true);
415+
CGF.PopCleanupBlock();
416416

417417
// Restore the alloca insertion point.
418418
{
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
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

Comments
 (0)