blob: 9f5f670b859bce8fa83571fb1e7798f83b26dd6c [file] [log] [blame]
John McCallbd04b742011-05-27 18:34:38 +00001; RUN: opt < %s -inline -S | FileCheck %s
2
3; Test that the inliner correctly handles inlining into invoke sites
4; by appending selectors and forwarding _Unwind_Resume directly to the
5; enclosing landing pad.
6
John McCallfca77862011-06-01 02:17:11 +00007;; Test 0 - basic functionality.
John McCallf19cf992011-05-30 01:08:04 +00008
John McCallbd04b742011-05-27 18:34:38 +00009%struct.A = type { i8 }
10
11@_ZTIi = external constant i8*
12
13declare void @_ZN1AC1Ev(%struct.A*)
14
15declare void @_ZN1AD1Ev(%struct.A*)
16
John McCallf19cf992011-05-30 01:08:04 +000017declare void @use(i32) nounwind
18
John McCallfc1ca362011-06-09 20:06:24 +000019declare void @opaque()
20
John McCallbd04b742011-05-27 18:34:38 +000021declare i32 @llvm.eh.typeid.for(i8*) nounwind
22
John McCallbd04b742011-05-27 18:34:38 +000023declare i32 @__gxx_personality_v0(...)
24
25declare i8* @__cxa_begin_catch(i8*)
26
27declare void @__cxa_end_catch()
28
29declare void @_ZSt9terminatev()
30
31define internal void @test0_in() alwaysinline uwtable ssp {
32entry:
33 %a = alloca %struct.A, align 1
34 %b = alloca %struct.A, align 1
35 call void @_ZN1AC1Ev(%struct.A* %a)
36 invoke void @_ZN1AC1Ev(%struct.A* %b)
37 to label %invoke.cont unwind label %lpad
38
39invoke.cont:
40 invoke void @_ZN1AD1Ev(%struct.A* %b)
41 to label %invoke.cont1 unwind label %lpad
42
43invoke.cont1:
44 call void @_ZN1AD1Ev(%struct.A* %a)
45 ret void
46
47lpad:
Bill Wendling723cec72011-09-02 01:25:11 +000048 %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
49 cleanup
John McCallbd04b742011-05-27 18:34:38 +000050 invoke void @_ZN1AD1Ev(%struct.A* %a)
51 to label %invoke.cont2 unwind label %terminate.lpad
52
53invoke.cont2:
Bill Wendling723cec72011-09-02 01:25:11 +000054 resume { i8*, i32 } %exn
John McCallbd04b742011-05-27 18:34:38 +000055
56terminate.lpad:
Bill Wendling723cec72011-09-02 01:25:11 +000057 %exn1 = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
58 catch i8* null
John McCallbd04b742011-05-27 18:34:38 +000059 call void @_ZSt9terminatev() noreturn nounwind
60 unreachable
61}
62
63define void @test0_out() uwtable ssp {
64entry:
65 invoke void @test0_in()
66 to label %ret unwind label %lpad
67
68ret:
69 ret void
70
71lpad: ; preds = %entry
Bill Wendling723cec72011-09-02 01:25:11 +000072 %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
73 catch i8* bitcast (i8** @_ZTIi to i8*)
74 %eh.exc = extractvalue { i8*, i32 } %exn, 0
75 %eh.selector = extractvalue { i8*, i32 } %exn, 1
John McCallbd04b742011-05-27 18:34:38 +000076 %0 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) nounwind
77 %1 = icmp eq i32 %eh.selector, %0
78 br i1 %1, label %catch, label %eh.resume
79
80catch:
Bill Wendling723cec72011-09-02 01:25:11 +000081 %ignored = call i8* @__cxa_begin_catch(i8* %eh.exc) nounwind
John McCallbd04b742011-05-27 18:34:38 +000082 call void @__cxa_end_catch() nounwind
83 br label %ret
84
85eh.resume:
Bill Wendling723cec72011-09-02 01:25:11 +000086 resume { i8*, i32 } %exn
John McCallbd04b742011-05-27 18:34:38 +000087}
88
John McCall046c47e2011-05-28 07:45:59 +000089; CHECK: define void @test0_out()
90; CHECK: [[A:%.*]] = alloca %struct.A,
91; CHECK: [[B:%.*]] = alloca %struct.A,
92; CHECK: invoke void @_ZN1AC1Ev(%struct.A* [[A]])
93; CHECK: invoke void @_ZN1AC1Ev(%struct.A* [[B]])
94; CHECK: invoke void @_ZN1AD1Ev(%struct.A* [[B]])
95; CHECK: invoke void @_ZN1AD1Ev(%struct.A* [[A]])
Bill Wendling723cec72011-09-02 01:25:11 +000096; CHECK: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
Bill Wendlingba198e62011-08-27 06:11:03 +000097; CHECK-NEXT: cleanup
98; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
John McCallbd04b742011-05-27 18:34:38 +000099; CHECK-NEXT: invoke void @_ZN1AD1Ev(%struct.A* [[A]])
100; CHECK-NEXT: to label %[[LBL:[^\s]+]] unwind
101; CHECK: [[LBL]]:
102; CHECK-NEXT: br label %[[LPAD:[^\s]+]]
John McCall046c47e2011-05-28 07:45:59 +0000103; CHECK: ret void
Bill Wendling723cec72011-09-02 01:25:11 +0000104; CHECK: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
Bill Wendlingba198e62011-08-27 06:11:03 +0000105; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
John McCall046c47e2011-05-28 07:45:59 +0000106; CHECK-NEXT: br label %[[LPAD]]
107; CHECK: [[LPAD]]:
Bill Wendlingba198e62011-08-27 06:11:03 +0000108; CHECK-NEXT: phi { i8*, i32 } [
109; CHECK-NEXT: extractvalue { i8*, i32 }
110; CHECK-NEXT: extractvalue { i8*, i32 }
John McCallf19cf992011-05-30 01:08:04 +0000111; CHECK-NEXT: call i32 @llvm.eh.typeid.for(
112
113
John McCallfca77862011-06-01 02:17:11 +0000114;; Test 1 - Correctly handle phis in outer landing pads.
John McCallf19cf992011-05-30 01:08:04 +0000115
116define void @test1_out() uwtable ssp {
117entry:
118 invoke void @test0_in()
119 to label %cont unwind label %lpad
120
121cont:
122 invoke void @test0_in()
123 to label %ret unwind label %lpad
124
125ret:
126 ret void
127
128lpad:
129 %x = phi i32 [ 0, %entry ], [ 1, %cont ]
130 %y = phi i32 [ 1, %entry ], [ 4, %cont ]
Bill Wendling723cec72011-09-02 01:25:11 +0000131 %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
132 catch i8* bitcast (i8** @_ZTIi to i8*)
133 %eh.exc = extractvalue { i8*, i32 } %exn, 0
134 %eh.selector = extractvalue { i8*, i32 } %exn, 1
John McCallf19cf992011-05-30 01:08:04 +0000135 %0 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) nounwind
136 %1 = icmp eq i32 %eh.selector, %0
137 br i1 %1, label %catch, label %eh.resume
138
139catch:
Bill Wendling723cec72011-09-02 01:25:11 +0000140 %ignored = call i8* @__cxa_begin_catch(i8* %eh.exc) nounwind
John McCallf19cf992011-05-30 01:08:04 +0000141 call void @use(i32 %x)
142 call void @use(i32 %y)
143 call void @__cxa_end_catch() nounwind
144 br label %ret
145
146eh.resume:
Bill Wendling723cec72011-09-02 01:25:11 +0000147 resume { i8*, i32 } %exn
John McCallf19cf992011-05-30 01:08:04 +0000148}
149
150; CHECK: define void @test1_out()
151; CHECK: [[A2:%.*]] = alloca %struct.A,
152; CHECK: [[B2:%.*]] = alloca %struct.A,
153; CHECK: [[A1:%.*]] = alloca %struct.A,
154; CHECK: [[B1:%.*]] = alloca %struct.A,
155; CHECK: invoke void @_ZN1AC1Ev(%struct.A* [[A1]])
156; CHECK-NEXT: unwind label %[[LPAD:[^\s]+]]
157; CHECK: invoke void @_ZN1AC1Ev(%struct.A* [[B1]])
158; CHECK-NEXT: unwind label %[[LPAD1:[^\s]+]]
159; CHECK: invoke void @_ZN1AD1Ev(%struct.A* [[B1]])
160; CHECK-NEXT: unwind label %[[LPAD1]]
161; CHECK: invoke void @_ZN1AD1Ev(%struct.A* [[A1]])
162; CHECK-NEXT: unwind label %[[LPAD]]
163
164; Inner landing pad from first inlining.
165; CHECK: [[LPAD1]]:
Bill Wendling723cec72011-09-02 01:25:11 +0000166; CHECK-NEXT: [[LPADVAL1:%.*]] = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
Bill Wendlingba198e62011-08-27 06:11:03 +0000167; CHECK-NEXT: cleanup
168; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
John McCallf19cf992011-05-30 01:08:04 +0000169; CHECK-NEXT: invoke void @_ZN1AD1Ev(%struct.A* [[A1]])
170; CHECK-NEXT: to label %[[RESUME1:[^\s]+]] unwind
171; CHECK: [[RESUME1]]:
172; CHECK-NEXT: br label %[[LPAD_JOIN1:[^\s]+]]
173
174; CHECK: invoke void @_ZN1AC1Ev(%struct.A* [[A2]])
175; CHECK-NEXT: unwind label %[[LPAD]]
176; CHECK: invoke void @_ZN1AC1Ev(%struct.A* [[B2]])
177; CHECK-NEXT: unwind label %[[LPAD2:[^\s]+]]
178; CHECK: invoke void @_ZN1AD1Ev(%struct.A* [[B2]])
179; CHECK-NEXT: unwind label %[[LPAD2]]
180; CHECK: invoke void @_ZN1AD1Ev(%struct.A* [[A2]])
181; CHECK-NEXT: unwind label %[[LPAD]]
182
183; Inner landing pad from second inlining.
184; CHECK: [[LPAD2]]:
Bill Wendling723cec72011-09-02 01:25:11 +0000185; CHECK-NEXT: [[LPADVAL2:%.*]] = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
Bill Wendlingba198e62011-08-27 06:11:03 +0000186; CHECK-NEXT: cleanup
187; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
John McCallf19cf992011-05-30 01:08:04 +0000188; CHECK-NEXT: invoke void @_ZN1AD1Ev(%struct.A* [[A2]])
189; CHECK-NEXT: to label %[[RESUME2:[^\s]+]] unwind
190; CHECK: [[RESUME2]]:
191; CHECK-NEXT: br label %[[LPAD_JOIN2:[^\s]+]]
192
193; CHECK: ret void
194
195; CHECK: [[LPAD]]:
196; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, %entry ], [ 0, {{%.*}} ], [ 1, %cont ], [ 1, {{%.*}} ]
197; CHECK-NEXT: [[Y:%.*]] = phi i32 [ 1, %entry ], [ 1, {{%.*}} ], [ 4, %cont ], [ 4, {{%.*}} ]
Bill Wendling723cec72011-09-02 01:25:11 +0000198; CHECK-NEXT: [[LPADVAL:%.*]] = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
Bill Wendlingba198e62011-08-27 06:11:03 +0000199; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
John McCallf19cf992011-05-30 01:08:04 +0000200; CHECK-NEXT: br label %[[LPAD_JOIN2]]
201
202; CHECK: [[LPAD_JOIN2]]:
203; CHECK-NEXT: [[XJ2:%.*]] = phi i32 [ [[X]], %[[LPAD]] ], [ 1, %[[RESUME2]] ]
204; CHECK-NEXT: [[YJ2:%.*]] = phi i32 [ [[Y]], %[[LPAD]] ], [ 4, %[[RESUME2]] ]
Bill Wendlingba198e62011-08-27 06:11:03 +0000205; CHECK-NEXT: [[EXNJ2:%.*]] = phi { i8*, i32 } [ [[LPADVAL]], %[[LPAD]] ], [ [[LPADVAL2]], %[[RESUME2]] ]
John McCallf19cf992011-05-30 01:08:04 +0000206; CHECK-NEXT: br label %[[LPAD_JOIN1]]
207
208; CHECK: [[LPAD_JOIN1]]:
209; CHECK-NEXT: [[XJ1:%.*]] = phi i32 [ [[XJ2]], %[[LPAD_JOIN2]] ], [ 0, %[[RESUME1]] ]
210; CHECK-NEXT: [[YJ1:%.*]] = phi i32 [ [[YJ2]], %[[LPAD_JOIN2]] ], [ 1, %[[RESUME1]] ]
Bill Wendlingba198e62011-08-27 06:11:03 +0000211; CHECK-NEXT: [[EXNJ1:%.*]] = phi { i8*, i32 } [ [[EXNJ2]], %[[LPAD_JOIN2]] ], [ [[LPADVAL1]], %[[RESUME1]] ]
212; CHECK-NEXT: extractvalue { i8*, i32 } [[EXNJ1]], 0
213; CHECK-NEXT: [[SELJ1:%.*]] = extractvalue { i8*, i32 } [[EXNJ1]], 1
John McCallf19cf992011-05-30 01:08:04 +0000214; CHECK-NEXT: [[T:%.*]] = call i32 @llvm.eh.typeid.for(
215; CHECK-NEXT: icmp eq i32 [[SELJ1]], [[T]]
216
217; CHECK: call void @use(i32 [[XJ1]])
218; CHECK: call void @use(i32 [[YJ1]])
219
Bill Wendlingba198e62011-08-27 06:11:03 +0000220; CHECK: resume { i8*, i32 }
John McCallfca77862011-06-01 02:17:11 +0000221
John McCallfca77862011-06-01 02:17:11 +0000222
John McCallfc1ca362011-06-09 20:06:24 +0000223;; Test 2 - Don't make invalid IR for inlines into landing pads without eh.exception calls
John McCallfca77862011-06-01 02:17:11 +0000224define void @test2_out() uwtable ssp {
225entry:
226 invoke void @test0_in()
227 to label %ret unwind label %lpad
228
229ret:
230 ret void
231
232lpad:
Bill Wendling723cec72011-09-02 01:25:11 +0000233 %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
234 cleanup
John McCallfca77862011-06-01 02:17:11 +0000235 call void @_ZSt9terminatev()
236 unreachable
237}
238
239; CHECK: define void @test2_out()
240; CHECK: [[A:%.*]] = alloca %struct.A,
241; CHECK: [[B:%.*]] = alloca %struct.A,
242; CHECK: invoke void @_ZN1AC1Ev(%struct.A* [[A]])
243; CHECK-NEXT: unwind label %[[LPAD:[^\s]+]]
244; CHECK: invoke void @_ZN1AC1Ev(%struct.A* [[B]])
245; CHECK-NEXT: unwind label %[[LPAD2:[^\s]+]]
246; CHECK: invoke void @_ZN1AD1Ev(%struct.A* [[B]])
247; CHECK-NEXT: unwind label %[[LPAD2]]
248; CHECK: invoke void @_ZN1AD1Ev(%struct.A* [[A]])
249; CHECK-NEXT: unwind label %[[LPAD]]
John McCallfc1ca362011-06-09 20:06:24 +0000250
251
252;; Test 3 - Deal correctly with split unwind edges.
253define void @test3_out() uwtable ssp {
254entry:
255 invoke void @test0_in()
256 to label %ret unwind label %lpad
257
258ret:
259 ret void
260
261lpad:
Bill Wendling723cec72011-09-02 01:25:11 +0000262 %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
263 catch i8* bitcast (i8** @_ZTIi to i8*)
John McCallfc1ca362011-06-09 20:06:24 +0000264 br label %lpad.cont
265
266lpad.cont:
John McCallfc1ca362011-06-09 20:06:24 +0000267 call void @_ZSt9terminatev()
268 unreachable
269}
270
271; CHECK: define void @test3_out()
Bill Wendling723cec72011-09-02 01:25:11 +0000272; CHECK: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
Bill Wendlingba198e62011-08-27 06:11:03 +0000273; CHECK-NEXT: cleanup
274; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
John McCallfc1ca362011-06-09 20:06:24 +0000275; CHECK-NEXT: invoke void @_ZN1AD1Ev(
276; CHECK-NEXT: to label %[[L:[^\s]+]] unwind
277; CHECK: [[L]]:
278; CHECK-NEXT: br label %[[JOIN:[^\s]+]]
279; CHECK: [[JOIN]]:
Bill Wendlingba198e62011-08-27 06:11:03 +0000280; CHECK-NEXT: phi { i8*, i32 }
John McCallfc1ca362011-06-09 20:06:24 +0000281; CHECK-NEXT: br label %lpad.cont
282; CHECK: lpad.cont:
283; CHECK-NEXT: call void @_ZSt9terminatev()
284
285
286;; Test 4 - Split unwind edges with a dominance problem
287define void @test4_out() uwtable ssp {
288entry:
289 invoke void @test0_in()
290 to label %cont unwind label %lpad.crit
291
292cont:
293 invoke void @opaque()
294 to label %ret unwind label %lpad
295
296ret:
297 ret void
298
299lpad.crit:
Bill Wendling723cec72011-09-02 01:25:11 +0000300 %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
301 catch i8* bitcast (i8** @_ZTIi to i8*)
Bill Wendlingba198e62011-08-27 06:11:03 +0000302 call void @opaque() nounwind
303 br label %terminate
304
305lpad:
Bill Wendling723cec72011-09-02 01:25:11 +0000306 %exn2 = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
307 catch i8* bitcast (i8** @_ZTIi to i8*)
Bill Wendlingba198e62011-08-27 06:11:03 +0000308 br label %terminate
309
310terminate:
311 %phi = phi i32 [ 0, %lpad.crit ], [ 1, %lpad ]
John McCallfc1ca362011-06-09 20:06:24 +0000312 call void @use(i32 %phi)
313 call void @_ZSt9terminatev()
314 unreachable
315}
316
317; CHECK: define void @test4_out()
Bill Wendling723cec72011-09-02 01:25:11 +0000318; CHECK: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
Bill Wendlingba198e62011-08-27 06:11:03 +0000319; CHECK-NEXT: cleanup
320; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
John McCallfc1ca362011-06-09 20:06:24 +0000321; CHECK-NEXT: invoke void @_ZN1AD1Ev(
322; CHECK-NEXT: to label %[[L:[^\s]+]] unwind
323; CHECK: [[L]]:
324; CHECK-NEXT: br label %[[JOIN:[^\s]+]]
325; CHECK: invoke void @opaque()
326; CHECK-NEXT: unwind label %lpad
327; CHECK: lpad.crit:
Bill Wendling723cec72011-09-02 01:25:11 +0000328; CHECK-NEXT: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
Bill Wendlingba198e62011-08-27 06:11:03 +0000329; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
John McCallfc1ca362011-06-09 20:06:24 +0000330; CHECK-NEXT: br label %[[JOIN]]
331; CHECK: [[JOIN]]:
Bill Wendlingba198e62011-08-27 06:11:03 +0000332; CHECK-NEXT: phi { i8*, i32 }
John McCallfc1ca362011-06-09 20:06:24 +0000333; CHECK-NEXT: call void @opaque() nounwind
334; CHECK-NEXT: br label %[[FIX:[^\s]+]]
335; CHECK: lpad:
Bill Wendling723cec72011-09-02 01:25:11 +0000336; CHECK-NEXT: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
Bill Wendlingba198e62011-08-27 06:11:03 +0000337; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
John McCallfc1ca362011-06-09 20:06:24 +0000338; CHECK-NEXT: br label %[[FIX]]
339; CHECK: [[FIX]]:
Bill Wendlingba198e62011-08-27 06:11:03 +0000340; CHECK-NEXT: [[T1:%.*]] = phi i32 [ 0, %[[JOIN]] ], [ 1, %lpad ]
John McCallfc1ca362011-06-09 20:06:24 +0000341; CHECK-NEXT: call void @use(i32 [[T1]])
342; CHECK-NEXT: call void @_ZSt9terminatev()