1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
2; RUN: opt -S -openmpopt < %s | FileCheck %s
3; RUN: opt -S -passes=openmpopt < %s | FileCheck %s
4
5%struct.ident_t = type { i32, i32, i32, i32, i8* }
6
7@.str = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1
8@0 = private unnamed_addr global %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0) }, align 8
9
10; doesn't modify any ICVs.
11define i32 @icv_free_use(i32 %0) {
12; CHECK-LABEL: define {{[^@]+}}@icv_free_use
13; CHECK-SAME: (i32 [[TMP0:%.*]])
14; CHECK-NEXT:    [[TMP2:%.*]] = add nsw i32 [[TMP0]], 1
15; CHECK-NEXT:    ret i32 [[TMP2]]
16;
17  %2 = add nsw i32 %0, 1
18  ret i32 %2
19}
20
21define i32 @bad_use(i32 %0) {
22; CHECK-LABEL: define {{[^@]+}}@bad_use
23; CHECK-SAME: (i32 [[TMP0:%.*]])
24; CHECK-NEXT:    tail call void @use(i32 [[TMP0]])
25; CHECK-NEXT:    [[TMP2:%.*]] = add nsw i32 [[TMP0]], 1
26; CHECK-NEXT:    ret i32 [[TMP2]]
27;
28  tail call void @use(i32 %0)
29  %2 = add nsw i32 %0, 1
30  ret i32 %2
31}
32
33define i32 @ok_use_assume(i32 %0) {
34; CHECK-LABEL: define {{[^@]+}}@ok_use_assume
35; CHECK-SAME: (i32 [[TMP0:%.*]]) {
36; CHECK-NEXT:    call void @use(i32 [[TMP0]]) [[ATTR1:#.*]]
37; CHECK-NEXT:    call void @use(i32 [[TMP0]]) [[ATTR2:#.*]]
38; CHECK-NEXT:    call void @no_openmp_use(i32 [[TMP0]])
39; CHECK-NEXT:    [[TMP2:%.*]] = add nsw i32 [[TMP0]], 1
40; CHECK-NEXT:    ret i32 [[TMP2]]
41;
42  call void @use(i32 %0) "no_openmp"
43  call void @use(i32 %0) "no_openmp_routines"
44  call void @no_openmp_use(i32 %0)
45  %2 = add nsw i32 %0, 1
46  ret i32 %2
47}
48
49define void @indirect_call(void ()* %0) {
50; CHECK-LABEL: define {{[^@]+}}@indirect_call
51; CHECK-SAME: (void ()* [[TMP0:%.*]])
52; CHECK-NEXT:    call void @omp_set_num_threads(i32 4)
53; CHECK-NEXT:    tail call void [[TMP0]]()
54; CHECK-NEXT:    [[TMP2:%.*]] = tail call i32 @omp_get_max_threads()
55; CHECK-NEXT:    tail call void @use(i32 [[TMP2]])
56; CHECK-NEXT:    ret void
57  call void @omp_set_num_threads(i32 4)
58  tail call void %0()
59  %2 = tail call i32 @omp_get_max_threads()
60  tail call void @use(i32 %2)
61  ret void
62}
63
64define dso_local i32 @foo(i32 %0, i32 %1) {
65; CHECK-LABEL: define {{[^@]+}}@foo
66; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]])
67; CHECK-NEXT:    tail call void @omp_set_num_threads(i32 [[TMP0]])
68; CHECK-NEXT:    tail call void @omp_set_num_threads(i32 [[TMP1]])
69; CHECK-NEXT:    tail call void @use(i32 [[TMP1]])
70; CHECK-NEXT:    tail call void @use(i32 [[TMP1]])
71; CHECK-NEXT:    tail call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
72; CHECK-NEXT:    [[TMP3:%.*]] = tail call i32 @omp_get_max_threads()
73; CHECK-NEXT:    tail call void @use(i32 [[TMP3]])
74; CHECK-NEXT:    ret i32 0
75;
76  tail call void @omp_set_num_threads(i32 %0)
77  %3 = tail call i32 @omp_get_max_threads()
78; FIXME: this value should be tracked and the rest of the getters deduplicated and replaced with it.
79  tail call void @omp_set_num_threads(i32 %1)
80  %4 = tail call i32 @omp_get_max_threads()
81  %5 = tail call i32 @omp_get_max_threads()
82  %6 = tail call i32 @omp_get_max_threads()
83  tail call void @use(i32 %4)
84  tail call void @use(i32 %5)
85  tail call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
86  %7 = tail call i32 @omp_get_max_threads()
87  tail call void @use(i32 %7)
88  ret i32 0
89}
90
91declare dso_local void @omp_set_num_threads(i32)
92
93declare dso_local i32 @omp_get_max_threads()
94
95declare dso_local void @use(i32)
96declare dso_local void @no_openmp_use(i32) "no_openmp"
97
98define internal void @.omp_outlined.(i32* %0, i32* %1) {
99; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.
100; CHECK-SAME: (i32* [[TMP0:%.*]], i32* [[TMP1:%.*]])
101; CHECK-NEXT:    [[TMP3:%.*]] = tail call i32 @omp_get_max_threads()
102; CHECK-NEXT:    [[TMP4:%.*]] = tail call i32 @omp_get_max_threads()
103; CHECK-NEXT:    tail call void @use(i32 [[TMP4]])
104; CHECK-NEXT:    tail call void @omp_set_num_threads(i32 10)
105; CHECK-NEXT:    tail call void @use(i32 10)
106; CHECK-NEXT:    ret void
107;
108; FIXME: this value should be tracked and the rest of the getters deduplicated and replaced with it.
109  %3 = tail call i32 @omp_get_max_threads()
110  %4 = tail call i32 @omp_get_max_threads()
111  tail call void @use(i32 %4)
112  tail call void @omp_set_num_threads(i32 10)
113  %5 = tail call i32 @omp_get_max_threads()
114  tail call void @use(i32 %5)
115  ret void
116}
117
118declare !callback !0 void @__kmpc_fork_call(%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...)
119
120define dso_local i32 @bar(i32 %0, i32 %1) {
121; CHECK-LABEL: define {{[^@]+}}@bar
122; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]])
123; CHECK-NEXT:    [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], [[TMP1]]
124; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i32 [[TMP0]], i32 [[TMP1]]
125; CHECK-NEXT:    tail call void @omp_set_num_threads(i32 [[TMP4]])
126; CHECK-NEXT:    tail call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*))
127; CHECK-NEXT:    [[TMP5:%.*]] = tail call i32 @omp_get_max_threads()
128; CHECK-NEXT:    tail call void @use(i32 [[TMP5]])
129; CHECK-NEXT:    ret i32 0
130;
131  %3 = icmp sgt i32 %0, %1
132  %4 = select i1 %3, i32 %0, i32 %1
133; FIXME: getters can be replaced with %4
134  tail call void @omp_set_num_threads(i32 %4)
135  %5 = tail call i32 @omp_get_max_threads()
136  tail call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*))
137  %6 = tail call i32 @omp_get_max_threads()
138  tail call void @use(i32 %6)
139  ret i32 0
140}
141
142define internal void @.omp_outlined..1(i32* %0, i32*  %1) {
143; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..1
144; CHECK-SAME: (i32* [[TMP0:%.*]], i32* [[TMP1:%.*]])
145; CHECK-NEXT:    [[TMP3:%.*]] = tail call i32 @omp_get_max_threads()
146; CHECK-NEXT:    tail call void @use(i32 [[TMP3]])
147; CHECK-NEXT:    tail call void @omp_set_num_threads(i32 10)
148; CHECK-NEXT:    tail call void @use(i32 10)
149; CHECK-NEXT:    [[TMP4:%.*]] = tail call i32 @omp_get_max_threads()
150; CHECK-NEXT:    tail call void @use(i32 [[TMP4]])
151; CHECK-NEXT:    ret void
152;
153  %3 = tail call i32 @omp_get_max_threads()
154  tail call void @use(i32 %3)
155  tail call void @omp_set_num_threads(i32 10)
156  %4 = tail call i32 @omp_get_max_threads()
157  tail call void @use(i32 %4)
158  %5 = tail call i32 @omp_get_max_threads()
159  tail call void @use(i32 %5)
160  ret void
161}
162
163define dso_local i32 @bar1(i32 %0, i32 %1) {
164; CHECK-LABEL: define {{[^@]+}}@bar1
165; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]])
166; CHECK-NEXT:    [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], [[TMP1]]
167; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i32 [[TMP0]], i32 [[TMP1]]
168; CHECK-NEXT:    tail call void @omp_set_num_threads(i32 [[TMP4]])
169; CHECK-NEXT:    tail call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..2 to void (i32*, i32*, ...)*))
170; CHECK-NEXT:    [[TMP5:%.*]] = tail call i32 @omp_get_max_threads()
171; CHECK-NEXT:    tail call void @use(i32 [[TMP5]])
172; CHECK-NEXT:    ret i32 0
173;
174  %3 = icmp sgt i32 %0, %1
175  %4 = select i1 %3, i32 %0, i32 %1
176  tail call void @omp_set_num_threads(i32 %4)
177  %5 = tail call i32 @omp_get_max_threads()
178  tail call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..2 to void (i32*, i32*, ...)*))
179  %6 = tail call i32 @omp_get_max_threads()
180  tail call void @use(i32 %6)
181  ret i32 0
182}
183
184define internal void @.omp_outlined..2(i32* %0, i32*  %1) {
185; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..2
186; CHECK-SAME: (i32* [[TMP0:%.*]], i32* [[TMP1:%.*]])
187; CHECK-NEXT:    [[TMP3:%.*]] = tail call i32 @omp_get_max_threads()
188; CHECK-NEXT:    [[TMP4:%.*]] = tail call i32 @icv_free_use(i32 [[TMP3]])
189; CHECK-NEXT:    tail call void @omp_set_num_threads(i32 10)
190; CHECK-NEXT:    [[TMP5:%.*]] = tail call i32 @icv_free_use(i32 10)
191; CHECK-NEXT:    [[TMP6:%.*]] = tail call i32 @icv_free_use(i32 10)
192; CHECK-NEXT:    ret void
193;
194  %3 = tail call i32 @omp_get_max_threads()
195  %4 = tail call i32 @icv_free_use(i32 %3)
196  tail call void @omp_set_num_threads(i32 10)
197  %5 = tail call i32 @omp_get_max_threads()
198  %6 = tail call i32 @icv_free_use(i32 %5)
199  %7 = tail call i32 @omp_get_max_threads()
200  %8 = tail call i32 @icv_free_use(i32 %7)
201  ret void
202}
203define void @test(i1 %0) {
204; CHECK-LABEL: define {{[^@]+}}@test
205; CHECK-SAME: (i1 [[TMP0:%.*]])
206; CHECK-NEXT:    call void @omp_set_num_threads(i32 2)
207; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false
208; CHECK-NEXT:    br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]]
209; CHECK:       3:
210; CHECK-NEXT:    call void @use(i32 10)
211; CHECK-NEXT:    br label [[TMP4]]
212; CHECK:       4:
213; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @omp_get_max_threads()
214; CHECK-NEXT:    call void @use(i32 [[TMP5]])
215; CHECK-NEXT:    ret void
216;
217  call void @omp_set_num_threads(i32 2)
218  %2 = icmp eq i1 %0, 0
219  br i1 %2, label %4, label %3
220
2213:                                                ; preds = %1
222  call void @use(i32 10)
223  br label %4
224
2254:                                                ; preds = %3, %1
226  %5 = call i32 @omp_get_max_threads()
227  call void @use(i32 %5)
228  ret void
229}
230
231define void @test1(i1 %0) {
232; CHECK-LABEL: define {{[^@]+}}@test1
233; CHECK-SAME: (i1 [[TMP0:%.*]])
234; CHECK-NEXT:    call void @omp_set_num_threads(i32 2)
235; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false
236; CHECK-NEXT:    br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
237; CHECK:       3:
238; CHECK-NEXT:    [[TMP4:%.*]] = call i32 @icv_free_use(i32 10)
239; CHECK-NEXT:    br label [[TMP5]]
240; CHECK:       5:
241; CHECK-NEXT:    call void @use(i32 2)
242; CHECK-NEXT:    ret void
243;
244  call void @omp_set_num_threads(i32 2)
245  %2 = icmp eq i1 %0, 0
246  br i1 %2, label %5, label %3
247
2483:                                                ; preds = %1
249  %4 = call i32 @icv_free_use(i32 10)
250  br label %5
251
2525:                                                ; preds = %3, %1
253  %6 = call i32 @omp_get_max_threads()
254  call void @use(i32 %6)
255  ret void
256}
257
258define void @bad_use_test(i1 %0) {
259; CHECK-LABEL: define {{[^@]+}}@bad_use_test
260; CHECK-SAME: (i1 [[TMP0:%.*]])
261; CHECK-NEXT:    call void @omp_set_num_threads(i32 2)
262; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false
263; CHECK-NEXT:    br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
264; CHECK:       3:
265; CHECK-NEXT:    [[TMP4:%.*]] = call i32 @bad_use(i32 10)
266; CHECK-NEXT:    br label [[TMP5]]
267; CHECK:       5:
268; CHECK-NEXT:    [[TMP6:%.*]] = call i32 @omp_get_max_threads()
269; CHECK-NEXT:    call void @use(i32 [[TMP6]])
270; CHECK-NEXT:    ret void
271;
272  call void @omp_set_num_threads(i32 2)
273  %2 = icmp eq i1 %0, 0
274  br i1 %2, label %5, label %3
275
2763:                                                ; preds = %1
277  %4 = call i32 @bad_use(i32 10)
278  br label %5
279
2805:                                                ; preds = %3, %1
281  %6 = call i32 @omp_get_max_threads()
282  call void @use(i32 %6)
283  ret void
284}
285
286define void @ok_use_assume_test(i1 %0) {
287; CHECK-LABEL: define {{[^@]+}}@ok_use_assume_test
288; CHECK-SAME: (i1 [[TMP0:%.*]]) {
289; CHECK-NEXT:    call void @omp_set_num_threads(i32 2)
290; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false
291; CHECK-NEXT:    br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
292; CHECK:       3:
293; CHECK-NEXT:    [[TMP4:%.*]] = call i32 @ok_use_assume(i32 10)
294; CHECK-NEXT:    br label [[TMP5]]
295; CHECK:       5:
296; CHECK-NEXT:    call void @use(i32 2)
297; CHECK-NEXT:    ret void
298;
299  call void @omp_set_num_threads(i32 2)
300  %2 = icmp eq i1 %0, 0
301  br i1 %2, label %5, label %3
302
3033:                                                ; preds = %1
304  %4 = call i32 @ok_use_assume(i32 10)
305  br label %5
306
3075:                                                ; preds = %3, %1
308  %6 = call i32 @omp_get_max_threads()
309  call void @use(i32 %6)
310  ret void
311}
312
313define weak void @weak_known_unique_icv(i1 %0) {
314; CHECK-LABEL: define {{[^@]+}}@weak_known_unique_icv
315; CHECK-SAME: (i1 [[TMP0:%.*]])
316; CHECK-NEXT:    call void @omp_set_num_threads(i32 2)
317; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false
318; CHECK-NEXT:    br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
319; CHECK:       3:
320; CHECK-NEXT:    [[TMP4:%.*]] = call i32 @icv_free_use(i32 10)
321; CHECK-NEXT:    br label [[TMP5]]
322; CHECK:       5:
323; CHECK-NEXT:    [[TMP6:%.*]] = call i32 @omp_get_max_threads()
324; CHECK-NEXT:    [[TMP7:%.*]] = call i32 @icv_free_use(i32 [[TMP6]])
325; CHECK-NEXT:    ret void
326;
327  call void @omp_set_num_threads(i32 2)
328  %2 = icmp eq i1 %0, 0
329  br i1 %2, label %5, label %3
330
3313:                                                ; preds = %1
332  %4 = call i32 @icv_free_use(i32 10)
333  br label %5
334
3355:                                                ; preds = %3, %1
336  %6 = call i32 @omp_get_max_threads()
337  %7 = call i32 @icv_free_use(i32 %6)
338  ret void
339}
340
341define void @known_unique_icv(i1 %0) {
342; CHECK-LABEL: define {{[^@]+}}@known_unique_icv
343; CHECK-SAME: (i1 [[TMP0:%.*]])
344; CHECK-NEXT:    call void @omp_set_num_threads(i32 2)
345; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false
346; CHECK-NEXT:    br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
347; CHECK:       3:
348; CHECK-NEXT:    [[TMP4:%.*]] = call i32 @icv_free_use(i32 10)
349; CHECK-NEXT:    br label [[TMP5]]
350; CHECK:       5:
351; CHECK-NEXT:    [[TMP6:%.*]] = call i32 @icv_free_use(i32 2)
352; CHECK-NEXT:    ret void
353;
354  call void @omp_set_num_threads(i32 2)
355  %2 = icmp eq i1 %0, 0
356  br i1 %2, label %5, label %3
357
3583:                                                ; preds = %1
359  %4 = call i32 @icv_free_use(i32 10)
360  br label %5
361
3625:                                                ; preds = %3, %1
363  %6 = call i32 @omp_get_max_threads()
364  %7 = call i32 @icv_free_use(i32 %6)
365  ret void
366}
367
368define i32 @no_unique_icv(i1 %0) {
369; CHECK-LABEL: define {{[^@]+}}@no_unique_icv
370; CHECK-SAME: (i1 [[TMP0:%.*]])
371; CHECK-NEXT:    call void @omp_set_num_threads(i32 4)
372; CHECK-NEXT:    br i1 [[TMP0]], label [[TMP3:%.*]], label [[TMP2:%.*]]
373; CHECK:       2:
374; CHECK-NEXT:    call void @omp_set_num_threads(i32 2)
375; CHECK-NEXT:    br label [[TMP3]]
376; CHECK:       3:
377; CHECK-NEXT:    [[TMP4:%.*]] = call i32 @omp_get_max_threads()
378; CHECK-NEXT:    ret i32 [[TMP4]]
379;
380  call void @omp_set_num_threads(i32 4)
381  br i1 %0, label %3, label %2
382
3832:                                                ; preds = %1
384  call void @omp_set_num_threads(i32 2)
385  br label %3
386
3873:                                                ; preds = %1, %2
388  %4 = call i32 @omp_get_max_threads()
389  ret i32 %4
390}
391
392define void @test2(i1 %0) {
393; CHECK-LABEL: define {{[^@]+}}@test2
394; CHECK-SAME: (i1 [[TMP0:%.*]])
395; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false
396; CHECK-NEXT:    br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]]
397; CHECK:       3:
398; CHECK-NEXT:    call void @omp_set_num_threads(i32 4)
399; CHECK-NEXT:    br label [[TMP4]]
400; CHECK:       4:
401; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @omp_get_max_threads()
402; CHECK-NEXT:    call void @use(i32 [[TMP5]])
403; CHECK-NEXT:    ret void
404;
405  %2 = icmp eq i1 %0, 0
406  br i1 %2, label %4, label %3
407
4083:                                                ; preds = %1
409  call void @omp_set_num_threads(i32 4)
410  br label %4
411
4124:                                                ; preds = %3, %1
413  %5 = call i32 @omp_get_max_threads()
414  call void @use(i32 %5)
415  ret void
416}
417
418define void @test3(i1 %0) {
419; CHECK-LABEL: define {{[^@]+}}@test3
420; CHECK-SAME: (i1 [[TMP0:%.*]])
421; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false
422; CHECK-NEXT:    br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]]
423; CHECK:       3:
424; CHECK-NEXT:    call void @omp_set_num_threads(i32 4)
425; CHECK-NEXT:    br label [[TMP4]]
426; CHECK:       4:
427; CHECK-NEXT:    call void @weak_known_unique_icv(i1 [[TMP0]])
428; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @omp_get_max_threads()
429; CHECK-NEXT:    [[TMP6:%.*]] = call i32 @icv_free_use(i32 [[TMP5]])
430; CHECK-NEXT:    ret void
431;
432  %2 = icmp eq i1 %0, 0
433  br i1 %2, label %4, label %3
434
4353:                                                ; preds = %1
436  call void @omp_set_num_threads(i32 4)
437  br label %4
438
4394:                                                ; preds = %3, %1
440  call void @weak_known_unique_icv(i1 %0)
441  %5 = call i32 @omp_get_max_threads()
442  %6 = call i32 @icv_free_use(i32 %5)
443  ret void
444}
445
446declare void @__cxa_rethrow()
447
448define i32 @maybe_throw(i1 zeroext %0) {
449; CHECK-LABEL: define {{[^@]+}}@maybe_throw
450; CHECK-SAME: (i1 zeroext [[TMP0:%.*]])
451; CHECK-NEXT:    call void @omp_set_num_threads(i32 4)
452; CHECK-NEXT:    br i1 [[TMP0]], label [[TMP2:%.*]], label [[TMP3:%.*]]
453; CHECK:       2:
454; CHECK-NEXT:    tail call void @__cxa_rethrow()
455; CHECK-NEXT:    unreachable
456; CHECK:       3:
457; CHECK-NEXT:    ret i32 -1
458;
459  call void @omp_set_num_threads(i32 4)
460  br i1 %0, label %2, label %3
461
4622:                                                ; preds = %1
463  tail call void @__cxa_rethrow() #1
464  unreachable
465
4663:                                                ; preds = %1
467  ret i32 -1
468}
469
470define void @test4(i1 %0) {
471; CHECK-LABEL: define {{[^@]+}}@test4
472; CHECK-SAME: (i1 [[TMP0:%.*]])
473; CHECK-NEXT:    call void @known_unique_icv(i1 [[TMP0]])
474; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false
475; CHECK-NEXT:    br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]]
476; CHECK:       3:
477; CHECK-NEXT:    [[VAL:%.*]] = call i32 @icv_free_use(i32 10)
478; CHECK-NEXT:    br label [[TMP4]]
479; CHECK:       4:
480; CHECK-NEXT:    call void @use(i32 2)
481; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @omp_get_max_threads()
482; CHECK-NEXT:    [[TMP6:%.*]] = call i32 @no_unique_icv(i1 [[TMP0]])
483; CHECK-NEXT:    call void @use(i32 [[TMP5]])
484; CHECK-NEXT:    ret void
485;
486  call void @known_unique_icv(i1 %0)
487  %2 = icmp eq i1 %0, 0
488  br i1 %2, label %4, label %3
489
4903:                                                ; preds = %1
491  %val = call i32 @icv_free_use(i32 10)
492  br label %4
493
4944:                                                ; preds = %3, %1
495  %5 = call i32 @omp_get_max_threads()
496  call void @use(i32 %5)
497  %6 = call i32 @omp_get_max_threads()
498  call i32 @no_unique_icv(i1 %0)
499  call void @use(i32 %6)
500  ret void
501}
502
503define void @test4_invoke(i1 %0) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
504; CHECK-LABEL: define {{[^@]+}}@test4_invoke
505; CHECK-SAME: (i1 [[TMP0:%.*]]) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
506; CHECK-NEXT:    call void @known_unique_icv(i1 [[TMP0]])
507; CHECK-NEXT:    [[TMP2:%.*]] = invoke i32 @maybe_throw(i1 [[TMP0]])
508; CHECK-NEXT:    to label [[CONT:%.*]] unwind label [[EXC:%.*]]
509; CHECK:       cont:
510; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i1 [[TMP0]], false
511; CHECK-NEXT:    br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]]
512; CHECK:       exc:
513; CHECK-NEXT:    [[LP:%.*]] = landingpad { i8*, i32 }
514; CHECK-NEXT:    filter [0 x i8*] zeroinitializer
515; CHECK-NEXT:    unreachable
516; CHECK:       4:
517; CHECK-NEXT:    [[VAL:%.*]] = call i32 @icv_free_use(i32 10)
518; CHECK-NEXT:    br label [[TMP5]]
519; CHECK:       5:
520; CHECK-NEXT:    call void @use(i32 2)
521; CHECK-NEXT:    ret void
522;
523  call void @known_unique_icv(i1 %0)
524  invoke i32 @maybe_throw(i1 %0)
525  to label %cont unwind label %exc
526
527cont:
528  %3 = icmp eq i1 %0, 0
529  br i1 %3, label %5, label %4
530
531exc:
532  %lp = landingpad { i8*, i32 }
533  filter [0 x i8*] zeroinitializer
534  unreachable
535
5364:                                                ; preds = %1
537  %val = call i32 @icv_free_use(i32 10)
538  br label %5
539
5405:                                                ; preds = %3, %1
541  %6 = call i32 @omp_get_max_threads()
542  call void @use(i32 %6)
543  ret void
544}
545
546define i32 @test5(i32 %0)  #0 {
547; CHECK-LABEL: define {{[^@]+}}@test5
548; CHECK-SAME: (i32 [[TMP0:%.*]])
549; CHECK-NEXT:    call void @omp_set_num_threads(i32 4)
550; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[TMP0]], 3
551; CHECK-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]]
552; CHECK:       3:
553; CHECK-NEXT:    call void @use(i32 4)
554; CHECK-NEXT:    br label [[TMP12:%.*]]
555; CHECK:       4:
556; CHECK-NEXT:    [[TMP5:%.*]] = icmp sgt i32 [[TMP0]], 0
557; CHECK-NEXT:    br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP8:%.*]]
558; CHECK:       6:
559; CHECK-NEXT:    [[TMP7:%.*]] = call i32 @icv_free_use(i32 [[TMP0]])
560; CHECK-NEXT:    br label [[TMP15:%.*]]
561; CHECK:       8:
562; CHECK-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP0]], 0
563; CHECK-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP12]]
564; CHECK:       10:
565; CHECK-NEXT:    [[TMP11:%.*]] = call i32 @icv_free_use(i32 10)
566; CHECK-NEXT:    br label [[TMP15]]
567; CHECK:       12:
568; CHECK-NEXT:    [[TMP13:%.*]] = add nsw i32 [[TMP0]], 1
569; CHECK-NEXT:    [[TMP14:%.*]] = call i32 @icv_free_use(i32 [[TMP13]])
570; CHECK-NEXT:    br label [[TMP15]]
571; CHECK:       15:
572; CHECK-NEXT:    [[TMP16:%.*]] = call i32 @omp_get_max_threads()
573; CHECK-NEXT:    [[TMP17:%.*]] = call i32 @icv_free_use(i32 [[TMP16]])
574; CHECK-NEXT:    ret i32 [[TMP17]]
575;
576  call void @omp_set_num_threads(i32 4)
577  %2 = icmp sgt i32 %0, 3
578  br i1 %2, label %3, label %5
579
5803:
581  %4 = call i32 @omp_get_max_threads()
582  call void @use(i32 %4)
583  br label %13
584
5855:
586  %6 = icmp sgt i32 %0, 0
587  br i1 %6, label %7, label %9
588
5897:
590  %8 = call i32 @icv_free_use(i32 %0)
591  br label %16
592
5939:
594  %10 = icmp eq i32 %0, 0
595  br i1 %10, label %11, label %13
596
59711:
598  %12 = call i32 @icv_free_use(i32 10)
599  br label %16
600
60113:
602  %14 = add nsw i32 %0, 1
603  %15 = call i32 @icv_free_use(i32 %14)
604  br label %16
605
60616:
607  %17 = call i32 @omp_get_max_threads()
608  %18 = call i32 @icv_free_use(i32 %17)
609  ret i32 %18
610}
611
612define i32 @test6(i32 %0) {
613; CHECK-LABEL: define {{[^@]+}}@test6
614; CHECK-SAME: (i32 [[TMP0:%.*]])
615; CHECK-NEXT:    call void @omp_set_num_threads(i32 4)
616; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[TMP0]], 3
617; CHECK-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
618; CHECK:       3:
619; CHECK-NEXT:    [[TMP4:%.*]] = call i32 @icv_free_use(i32 10)
620; CHECK-NEXT:    br label [[TMP16:%.*]]
621; CHECK:       5:
622; CHECK-NEXT:    [[TMP6:%.*]] = icmp sgt i32 [[TMP0]], 0
623; CHECK-NEXT:    br i1 [[TMP6]], label [[TMP7:%.*]], label [[TMP9:%.*]]
624; CHECK:       7:
625; CHECK-NEXT:    [[TMP8:%.*]] = call i32 @icv_free_use(i32 [[TMP0]])
626; CHECK-NEXT:    br label [[TMP16]]
627; CHECK:       9:
628; CHECK-NEXT:    [[TMP10:%.*]] = icmp eq i32 [[TMP0]], 0
629; CHECK-NEXT:    br i1 [[TMP10]], label [[TMP11:%.*]], label [[TMP13:%.*]]
630; CHECK:       11:
631; CHECK-NEXT:    [[TMP12:%.*]] = call i32 @icv_free_use(i32 5)
632; CHECK-NEXT:    br label [[TMP16]]
633; CHECK:       13:
634; CHECK-NEXT:    [[TMP14:%.*]] = add nsw i32 [[TMP0]], 1
635; CHECK-NEXT:    [[TMP15:%.*]] = call i32 @icv_free_use(i32 [[TMP14]])
636; CHECK-NEXT:    br label [[TMP16]]
637; CHECK:       16:
638; CHECK-NEXT:    [[TMP17:%.*]] = call i32 @icv_free_use(i32 4)
639; CHECK-NEXT:    ret i32 [[TMP17]]
640;
641  call void @omp_set_num_threads(i32 4)
642  %2 = icmp sgt i32 %0, 3
643  br i1 %2, label %3, label %5
644
6453:                                                ; preds = %1
646  %4 = call i32 @icv_free_use(i32 10)
647  br label %16
648
6495:                                                ; preds = %1
650  %6 = icmp sgt i32 %0, 0
651  br i1 %6, label %7, label %9
652
6537:                                                ; preds = %5
654  %8 = call i32 @icv_free_use(i32 %0)
655  br label %16
656
6579:                                                ; preds = %5
658  %10 = icmp eq i32 %0, 0
659  br i1 %10, label %11, label %13
660
66111:                                               ; preds = %9
662  %12 = call i32 @icv_free_use(i32 5)
663  br label %16
664
66513:                                               ; preds = %9
666  %14 = add nsw i32 %0, 1
667  %15 = call i32 @icv_free_use(i32 %14)
668  br label %16
669
67016:                                               ; preds = %7, %13, %11, %3
671  %17 = call i32 @omp_get_max_threads()
672  %18 = call i32 @icv_free_use(i32 %17)
673  ret i32 %18
674}
675
676declare i32 @__gxx_personality_v0(...)
677
678!0 = !{!1}
679!1 = !{i64 2, i64 -1, i64 -1, i1 true}
680