xref: /llvm-project/llvm/test/Transforms/FunctionAttrs/cold.ll (revision 6b11573b8c5e3d36beee099dbe7347c2a007bf53)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals --version 2
2; RUN: opt -passes=function-attrs -S < %s | FileCheck --check-prefixes=COMMON,FNATTRS %s
3; RUN: opt -passes=attributor-light -S < %s | FileCheck --check-prefixes=COMMON,ATTRIBUTOR %s
4
5declare i32 @get_val()
6
7declare void @cold0() cold
8declare void @cold1() cold
9declare void @cold_at_cb()
10
11declare void @not_cold0()
12declare void @not_cold1()
13declare void @not_cold2()
14
15define void @test_no_exit_fail() {
16; COMMON: Function Attrs: nofree norecurse noreturn nosync nounwind memory(none)
17; COMMON-LABEL: define void @test_no_exit_fail
18; COMMON-SAME: () #[[ATTR1:[0-9]+]] {
19; COMMON-NEXT:  entry:
20; COMMON-NEXT:    br label [[WHILE_BODY:%.*]]
21; COMMON:       while.body:
22; COMMON-NEXT:    br label [[WHILE_BODY]]
23;
24entry:
25  br label %while.body
26
27while.body:
28  br label %while.body
29}
30
31define void @test_no_exit_fail2() {
32; COMMON: Function Attrs: noreturn
33; COMMON-LABEL: define void @test_no_exit_fail2
34; COMMON-SAME: () #[[ATTR2:[0-9]+]] {
35; COMMON-NEXT:  entry:
36; COMMON-NEXT:    br label [[WHILE_BODY:%.*]]
37; COMMON:       while.body:
38; COMMON-NEXT:    call void @not_cold0()
39; COMMON-NEXT:    br label [[WHILE_BODY2:%.*]]
40; COMMON:       while.body2:
41; COMMON-NEXT:    call void @not_cold1()
42; COMMON-NEXT:    br label [[WHILE_BODY]]
43;
44entry:
45  br label %while.body
46
47while.body:
48  call void @not_cold0()
49  br label %while.body2
50
51while.body2:
52  call void @not_cold1()
53  br label %while.body
54}
55
56define void @test_no_exit() {
57; FNATTRS: Function Attrs: cold noreturn
58; FNATTRS-LABEL: define void @test_no_exit
59; FNATTRS-SAME: () #[[ATTR3:[0-9]+]] {
60; FNATTRS-NEXT:  entry:
61; FNATTRS-NEXT:    br label [[WHILE_BODY:%.*]]
62; FNATTRS:       while.body:
63; FNATTRS-NEXT:    call void @cold0()
64; FNATTRS-NEXT:    br label [[WHILE_BODY]]
65;
66; ATTRIBUTOR: Function Attrs: noreturn
67; ATTRIBUTOR-LABEL: define void @test_no_exit
68; ATTRIBUTOR-SAME: () #[[ATTR2]] {
69; ATTRIBUTOR-NEXT:  entry:
70; ATTRIBUTOR-NEXT:    br label [[WHILE_BODY:%.*]]
71; ATTRIBUTOR:       while.body:
72; ATTRIBUTOR-NEXT:    call void @cold0()
73; ATTRIBUTOR-NEXT:    br label [[WHILE_BODY]]
74;
75entry:
76  br label %while.body
77
78while.body:
79  call void @cold0()
80  br label %while.body
81}
82
83define void @test_no_exit2() {
84; FNATTRS: Function Attrs: cold noreturn
85; FNATTRS-LABEL: define void @test_no_exit2
86; FNATTRS-SAME: () #[[ATTR3]] {
87; FNATTRS-NEXT:  entry:
88; FNATTRS-NEXT:    br label [[WHILE_BODY:%.*]]
89; FNATTRS:       while.body:
90; FNATTRS-NEXT:    call void @not_cold0()
91; FNATTRS-NEXT:    br label [[WHILE_BODY2:%.*]]
92; FNATTRS:       while.body2:
93; FNATTRS-NEXT:    call void @cold1()
94; FNATTRS-NEXT:    br label [[WHILE_BODY]]
95;
96; ATTRIBUTOR: Function Attrs: noreturn
97; ATTRIBUTOR-LABEL: define void @test_no_exit2
98; ATTRIBUTOR-SAME: () #[[ATTR2]] {
99; ATTRIBUTOR-NEXT:  entry:
100; ATTRIBUTOR-NEXT:    br label [[WHILE_BODY:%.*]]
101; ATTRIBUTOR:       while.body:
102; ATTRIBUTOR-NEXT:    call void @not_cold0()
103; ATTRIBUTOR-NEXT:    br label [[WHILE_BODY2:%.*]]
104; ATTRIBUTOR:       while.body2:
105; ATTRIBUTOR-NEXT:    call void @cold1()
106; ATTRIBUTOR-NEXT:    br label [[WHILE_BODY]]
107;
108entry:
109  br label %while.body
110
111while.body:
112  call void @not_cold0()
113  br label %while.body2
114
115while.body2:
116  call void @cold1()
117  br label %while.body
118}
119
120define dso_local void @test_entry(i32 noundef %x) {
121; FNATTRS: Function Attrs: cold
122; FNATTRS-LABEL: define dso_local void @test_entry
123; FNATTRS-SAME: (i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] {
124; FNATTRS-NEXT:  entry:
125; FNATTRS-NEXT:    tail call void @cold0()
126; FNATTRS-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0
127; FNATTRS-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
128; FNATTRS:       if.then:
129; FNATTRS-NEXT:    tail call void @not_cold0()
130; FNATTRS-NEXT:    br label [[IF_END]]
131; FNATTRS:       if.end:
132; FNATTRS-NEXT:    tail call void @not_cold1()
133; FNATTRS-NEXT:    ret void
134;
135; ATTRIBUTOR-LABEL: define dso_local void @test_entry
136; ATTRIBUTOR-SAME: (i32 noundef [[X:%.*]]) {
137; ATTRIBUTOR-NEXT:  entry:
138; ATTRIBUTOR-NEXT:    tail call void @cold0()
139; ATTRIBUTOR-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0
140; ATTRIBUTOR-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
141; ATTRIBUTOR:       if.then:
142; ATTRIBUTOR-NEXT:    tail call void @not_cold0()
143; ATTRIBUTOR-NEXT:    br label [[IF_END]]
144; ATTRIBUTOR:       if.end:
145; ATTRIBUTOR-NEXT:    tail call void @not_cold1()
146; ATTRIBUTOR-NEXT:    ret void
147;
148entry:
149  tail call void @cold0()
150  %tobool.not = icmp eq i32 %x, 0
151  br i1 %tobool.not, label %if.end, label %if.then
152
153if.then:
154  tail call void @not_cold0()
155  br label %if.end
156
157if.end:
158  tail call void @not_cold1()
159  ret void
160}
161
162define dso_local void @test_hot_fail(i32 noundef %x) hot {
163; FNATTRS: Function Attrs: hot
164; FNATTRS-LABEL: define dso_local void @test_hot_fail
165; FNATTRS-SAME: (i32 noundef [[X:%.*]]) #[[ATTR4:[0-9]+]] {
166; FNATTRS-NEXT:  entry:
167; FNATTRS-NEXT:    tail call void @cold0()
168; FNATTRS-NEXT:    ret void
169;
170; ATTRIBUTOR: Function Attrs: hot
171; ATTRIBUTOR-LABEL: define dso_local void @test_hot_fail
172; ATTRIBUTOR-SAME: (i32 noundef [[X:%.*]]) #[[ATTR3:[0-9]+]] {
173; ATTRIBUTOR-NEXT:  entry:
174; ATTRIBUTOR-NEXT:    tail call void @cold0()
175; ATTRIBUTOR-NEXT:    ret void
176;
177entry:
178  tail call void @cold0()
179  ret void
180}
181
182define dso_local void @test_br2(i32 noundef %x) {
183; FNATTRS: Function Attrs: cold
184; FNATTRS-LABEL: define dso_local void @test_br2
185; FNATTRS-SAME: (i32 noundef [[X:%.*]]) #[[ATTR0]] {
186; FNATTRS-NEXT:  entry:
187; FNATTRS-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0
188; FNATTRS-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
189; FNATTRS:       if.then:
190; FNATTRS-NEXT:    tail call void @cold0()
191; FNATTRS-NEXT:    br label [[IF_END:%.*]]
192; FNATTRS:       if.else:
193; FNATTRS-NEXT:    tail call void @cold1()
194; FNATTRS-NEXT:    br label [[IF_END]]
195; FNATTRS:       if.end:
196; FNATTRS-NEXT:    ret void
197;
198; ATTRIBUTOR-LABEL: define dso_local void @test_br2
199; ATTRIBUTOR-SAME: (i32 noundef [[X:%.*]]) {
200; ATTRIBUTOR-NEXT:  entry:
201; ATTRIBUTOR-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0
202; ATTRIBUTOR-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
203; ATTRIBUTOR:       if.then:
204; ATTRIBUTOR-NEXT:    tail call void @cold0()
205; ATTRIBUTOR-NEXT:    br label [[IF_END:%.*]]
206; ATTRIBUTOR:       if.else:
207; ATTRIBUTOR-NEXT:    tail call void @cold1()
208; ATTRIBUTOR-NEXT:    br label [[IF_END]]
209; ATTRIBUTOR:       if.end:
210; ATTRIBUTOR-NEXT:    ret void
211;
212entry:
213  %tobool.not = icmp eq i32 %x, 0
214  br i1 %tobool.not, label %if.else, label %if.then
215
216if.then:
217  tail call void @cold0()
218  br label %if.end
219
220if.else:
221  tail call void @cold1()
222  br label %if.end
223
224if.end:
225  ret void
226}
227
228define dso_local void @test_exit(i32 noundef %x) {
229; FNATTRS: Function Attrs: cold
230; FNATTRS-LABEL: define dso_local void @test_exit
231; FNATTRS-SAME: (i32 noundef [[X:%.*]]) #[[ATTR0]] {
232; FNATTRS-NEXT:  entry:
233; FNATTRS-NEXT:    tail call void @not_cold0()
234; FNATTRS-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0
235; FNATTRS-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
236; FNATTRS:       if.then:
237; FNATTRS-NEXT:    tail call void @not_cold1()
238; FNATTRS-NEXT:    br label [[IF_END:%.*]]
239; FNATTRS:       if.else:
240; FNATTRS-NEXT:    tail call void @not_cold2()
241; FNATTRS-NEXT:    br label [[IF_END]]
242; FNATTRS:       if.end:
243; FNATTRS-NEXT:    tail call void @cold0()
244; FNATTRS-NEXT:    ret void
245;
246; ATTRIBUTOR-LABEL: define dso_local void @test_exit
247; ATTRIBUTOR-SAME: (i32 noundef [[X:%.*]]) {
248; ATTRIBUTOR-NEXT:  entry:
249; ATTRIBUTOR-NEXT:    tail call void @not_cold0()
250; ATTRIBUTOR-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0
251; ATTRIBUTOR-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
252; ATTRIBUTOR:       if.then:
253; ATTRIBUTOR-NEXT:    tail call void @not_cold1()
254; ATTRIBUTOR-NEXT:    br label [[IF_END:%.*]]
255; ATTRIBUTOR:       if.else:
256; ATTRIBUTOR-NEXT:    tail call void @not_cold2()
257; ATTRIBUTOR-NEXT:    br label [[IF_END]]
258; ATTRIBUTOR:       if.end:
259; ATTRIBUTOR-NEXT:    tail call void @cold0()
260; ATTRIBUTOR-NEXT:    ret void
261;
262entry:
263  tail call void @not_cold0()
264  %tobool.not = icmp eq i32 %x, 0
265  br i1 %tobool.not, label %if.else, label %if.then
266
267if.then:
268  tail call void @not_cold1()
269  br label %if.end
270
271if.else:
272  tail call void @not_cold2()
273  br label %if.end
274
275if.end:
276  tail call void @cold0()
277  ret void
278}
279
280define dso_local void @test_complex(i32 noundef %x) {
281; FNATTRS: Function Attrs: cold
282; FNATTRS-LABEL: define dso_local void @test_complex
283; FNATTRS-SAME: (i32 noundef [[X:%.*]]) #[[ATTR0]] {
284; FNATTRS-NEXT:  entry:
285; FNATTRS-NEXT:    tail call void @not_cold0()
286; FNATTRS-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0
287; FNATTRS-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_ELSE11:%.*]], label [[IF_THEN:%.*]]
288; FNATTRS:       if.then:
289; FNATTRS-NEXT:    [[CALL:%.*]] = tail call i32 @get_val()
290; FNATTRS-NEXT:    [[TOBOOL1_NOT:%.*]] = icmp eq i32 [[CALL]], 0
291; FNATTRS-NEXT:    br i1 [[TOBOOL1_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]]
292; FNATTRS:       if.then2:
293; FNATTRS-NEXT:    tail call void @cold1()
294; FNATTRS-NEXT:    br label [[IF_END12:%.*]]
295; FNATTRS:       if.else:
296; FNATTRS-NEXT:    [[CALL3:%.*]] = tail call i32 @get_val()
297; FNATTRS-NEXT:    [[TOBOOL4_NOT:%.*]] = icmp eq i32 [[CALL3]], 0
298; FNATTRS-NEXT:    br i1 [[TOBOOL4_NOT]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]]
299; FNATTRS:       if.then5:
300; FNATTRS-NEXT:    tail call void @cold0()
301; FNATTRS-NEXT:    br label [[IF_END12]]
302; FNATTRS:       if.else6:
303; FNATTRS-NEXT:    tail call void @not_cold0()
304; FNATTRS-NEXT:    [[CALL7:%.*]] = tail call i32 @get_val()
305; FNATTRS-NEXT:    switch i32 [[CALL7]], label [[SW_DEFAULT:%.*]] [
306; FNATTRS-NEXT:      i32 0, label [[SW_BB:%.*]]
307; FNATTRS-NEXT:      i32 1, label [[SW_BB8:%.*]]
308; FNATTRS-NEXT:      i32 2, label [[SW_BB9:%.*]]
309; FNATTRS-NEXT:    ]
310; FNATTRS:       sw.bb:
311; FNATTRS-NEXT:    tail call void @not_cold0()
312; FNATTRS-NEXT:    br label [[CALL_COLD:%.*]]
313; FNATTRS:       sw.bb8:
314; FNATTRS-NEXT:    tail call void @not_cold1()
315; FNATTRS-NEXT:    br label [[CALL_COLD]]
316; FNATTRS:       sw.bb9:
317; FNATTRS-NEXT:    tail call void @not_cold2()
318; FNATTRS-NEXT:    br label [[CALL_COLD]]
319; FNATTRS:       sw.default:
320; FNATTRS-NEXT:    tail call void @cold0()
321; FNATTRS-NEXT:    br label [[IF_END12]]
322; FNATTRS:       call_cold:
323; FNATTRS-NEXT:    tail call void @cold_at_cb() #[[ATTR0]]
324; FNATTRS-NEXT:    br label [[IF_END12]]
325; FNATTRS:       if.else11:
326; FNATTRS-NEXT:    tail call void @cold0()
327; FNATTRS-NEXT:    br label [[IF_END12]]
328; FNATTRS:       if.end12:
329; FNATTRS-NEXT:    ret void
330;
331; ATTRIBUTOR-LABEL: define dso_local void @test_complex
332; ATTRIBUTOR-SAME: (i32 noundef [[X:%.*]]) {
333; ATTRIBUTOR-NEXT:  entry:
334; ATTRIBUTOR-NEXT:    tail call void @not_cold0()
335; ATTRIBUTOR-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0
336; ATTRIBUTOR-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_ELSE11:%.*]], label [[IF_THEN:%.*]]
337; ATTRIBUTOR:       if.then:
338; ATTRIBUTOR-NEXT:    [[CALL:%.*]] = tail call i32 @get_val()
339; ATTRIBUTOR-NEXT:    [[TOBOOL1_NOT:%.*]] = icmp eq i32 [[CALL]], 0
340; ATTRIBUTOR-NEXT:    br i1 [[TOBOOL1_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]]
341; ATTRIBUTOR:       if.then2:
342; ATTRIBUTOR-NEXT:    tail call void @cold1()
343; ATTRIBUTOR-NEXT:    br label [[IF_END12:%.*]]
344; ATTRIBUTOR:       if.else:
345; ATTRIBUTOR-NEXT:    [[CALL3:%.*]] = tail call i32 @get_val()
346; ATTRIBUTOR-NEXT:    [[TOBOOL4_NOT:%.*]] = icmp eq i32 [[CALL3]], 0
347; ATTRIBUTOR-NEXT:    br i1 [[TOBOOL4_NOT]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]]
348; ATTRIBUTOR:       if.then5:
349; ATTRIBUTOR-NEXT:    tail call void @cold0()
350; ATTRIBUTOR-NEXT:    br label [[IF_END12]]
351; ATTRIBUTOR:       if.else6:
352; ATTRIBUTOR-NEXT:    tail call void @not_cold0()
353; ATTRIBUTOR-NEXT:    [[CALL7:%.*]] = tail call i32 @get_val()
354; ATTRIBUTOR-NEXT:    switch i32 [[CALL7]], label [[SW_DEFAULT:%.*]] [
355; ATTRIBUTOR-NEXT:      i32 0, label [[SW_BB:%.*]]
356; ATTRIBUTOR-NEXT:      i32 1, label [[SW_BB8:%.*]]
357; ATTRIBUTOR-NEXT:      i32 2, label [[SW_BB9:%.*]]
358; ATTRIBUTOR-NEXT:    ]
359; ATTRIBUTOR:       sw.bb:
360; ATTRIBUTOR-NEXT:    tail call void @not_cold0()
361; ATTRIBUTOR-NEXT:    br label [[CALL_COLD:%.*]]
362; ATTRIBUTOR:       sw.bb8:
363; ATTRIBUTOR-NEXT:    tail call void @not_cold1()
364; ATTRIBUTOR-NEXT:    br label [[CALL_COLD]]
365; ATTRIBUTOR:       sw.bb9:
366; ATTRIBUTOR-NEXT:    tail call void @not_cold2()
367; ATTRIBUTOR-NEXT:    br label [[CALL_COLD]]
368; ATTRIBUTOR:       sw.default:
369; ATTRIBUTOR-NEXT:    tail call void @cold0()
370; ATTRIBUTOR-NEXT:    br label [[IF_END12]]
371; ATTRIBUTOR:       call_cold:
372; ATTRIBUTOR-NEXT:    tail call void @cold_at_cb() #[[ATTR0:[0-9]+]]
373; ATTRIBUTOR-NEXT:    br label [[IF_END12]]
374; ATTRIBUTOR:       if.else11:
375; ATTRIBUTOR-NEXT:    tail call void @cold0()
376; ATTRIBUTOR-NEXT:    br label [[IF_END12]]
377; ATTRIBUTOR:       if.end12:
378; ATTRIBUTOR-NEXT:    ret void
379;
380entry:
381  tail call void @not_cold0()
382  %tobool.not = icmp eq i32 %x, 0
383  br i1 %tobool.not, label %if.else11, label %if.then
384
385if.then:
386  %call = tail call i32 @get_val()
387  %tobool1.not = icmp eq i32 %call, 0
388  br i1 %tobool1.not, label %if.else, label %if.then2
389
390if.then2:
391  tail call void @cold1()
392  br label %if.end12
393
394if.else:
395  %call3 = tail call i32 @get_val()
396  %tobool4.not = icmp eq i32 %call3, 0
397  br i1 %tobool4.not, label %if.else6, label %if.then5
398
399if.then5:
400  tail call void @cold0()
401  br label %if.end12
402
403if.else6:
404  tail call void @not_cold0()
405  %call7 = tail call i32 @get_val()
406  switch i32 %call7, label %sw.default [
407  i32 0, label %sw.bb
408  i32 1, label %sw.bb8
409  i32 2, label %sw.bb9
410  ]
411
412sw.bb:
413  tail call void @not_cold0()
414  br label %call_cold
415
416sw.bb8:
417  tail call void @not_cold1()
418  br label %call_cold
419
420sw.bb9:
421  tail call void @not_cold2()
422  br label %call_cold
423
424sw.default:
425  tail call void @cold0()
426  br label %if.end12
427
428call_cold:
429  tail call void @cold_at_cb() cold
430  br label %if.end12
431
432if.else11:
433  tail call void @cold0()
434  br label %if.end12
435
436if.end12:
437  ret void
438}
439
440define dso_local void @test_complex2(i32 noundef %x) {
441; FNATTRS: Function Attrs: cold
442; FNATTRS-LABEL: define dso_local void @test_complex2
443; FNATTRS-SAME: (i32 noundef [[X:%.*]]) #[[ATTR0]] {
444; FNATTRS-NEXT:  entry:
445; FNATTRS-NEXT:    tail call void @not_cold0()
446; FNATTRS-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0
447; FNATTRS-NEXT:    [[CALL12:%.*]] = tail call i32 @get_val()
448; FNATTRS-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_ELSE11:%.*]], label [[IF_THEN:%.*]]
449; FNATTRS:       if.then:
450; FNATTRS-NEXT:    [[TOBOOL1_NOT:%.*]] = icmp eq i32 [[CALL12]], 0
451; FNATTRS-NEXT:    br i1 [[TOBOOL1_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]]
452; FNATTRS:       if.then2:
453; FNATTRS-NEXT:    tail call void @cold1()
454; FNATTRS-NEXT:    br label [[IF_END16:%.*]]
455; FNATTRS:       if.else:
456; FNATTRS-NEXT:    [[CALL3:%.*]] = tail call i32 @get_val()
457; FNATTRS-NEXT:    [[TOBOOL4_NOT:%.*]] = icmp eq i32 [[CALL3]], 0
458; FNATTRS-NEXT:    br i1 [[TOBOOL4_NOT]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]]
459; FNATTRS:       if.then5:
460; FNATTRS-NEXT:    tail call void @cold0()
461; FNATTRS-NEXT:    br label [[IF_END16]]
462; FNATTRS:       if.else6:
463; FNATTRS-NEXT:    tail call void @not_cold0()
464; FNATTRS-NEXT:    [[CALL7:%.*]] = tail call i32 @get_val()
465; FNATTRS-NEXT:    switch i32 [[CALL7]], label [[SW_DEFAULT:%.*]] [
466; FNATTRS-NEXT:      i32 0, label [[SW_BB:%.*]]
467; FNATTRS-NEXT:      i32 1, label [[SW_BB8:%.*]]
468; FNATTRS-NEXT:      i32 2, label [[SW_BB9:%.*]]
469; FNATTRS-NEXT:    ]
470; FNATTRS:       sw.bb:
471; FNATTRS-NEXT:    tail call void @not_cold0()
472; FNATTRS-NEXT:    br label [[CALL_COLD:%.*]]
473; FNATTRS:       sw.bb8:
474; FNATTRS-NEXT:    tail call void @not_cold1()
475; FNATTRS-NEXT:    br label [[CALL_COLD]]
476; FNATTRS:       sw.bb9:
477; FNATTRS-NEXT:    tail call void @not_cold2()
478; FNATTRS-NEXT:    br label [[CALL_COLD]]
479; FNATTRS:       sw.default:
480; FNATTRS-NEXT:    tail call void @cold0()
481; FNATTRS-NEXT:    br label [[IF_END16]]
482; FNATTRS:       call_cold:
483; FNATTRS-NEXT:    tail call void @cold_at_cb() #[[ATTR0]]
484; FNATTRS-NEXT:    br label [[IF_END16]]
485; FNATTRS:       if.else11:
486; FNATTRS-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CALL12]], 1
487; FNATTRS-NEXT:    br i1 [[CMP]], label [[IF_END14:%.*]], label [[FOR_BODY:%.*]]
488; FNATTRS:       if.end14:
489; FNATTRS-NEXT:    tail call void @cold1()
490; FNATTRS-NEXT:    br label [[IF_END16]]
491; FNATTRS:       for.body:
492; FNATTRS-NEXT:    [[I_021:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[IF_ELSE11]] ]
493; FNATTRS-NEXT:    tail call void @cold0()
494; FNATTRS-NEXT:    [[INC]] = add nuw nsw i32 [[I_021]], 1
495; FNATTRS-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[CALL12]]
496; FNATTRS-NEXT:    br i1 [[EXITCOND_NOT]], label [[IF_END16]], label [[FOR_BODY]]
497; FNATTRS:       if.end16:
498; FNATTRS-NEXT:    ret void
499;
500; ATTRIBUTOR-LABEL: define dso_local void @test_complex2
501; ATTRIBUTOR-SAME: (i32 noundef [[X:%.*]]) {
502; ATTRIBUTOR-NEXT:  entry:
503; ATTRIBUTOR-NEXT:    tail call void @not_cold0()
504; ATTRIBUTOR-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0
505; ATTRIBUTOR-NEXT:    [[CALL12:%.*]] = tail call i32 @get_val()
506; ATTRIBUTOR-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_ELSE11:%.*]], label [[IF_THEN:%.*]]
507; ATTRIBUTOR:       if.then:
508; ATTRIBUTOR-NEXT:    [[TOBOOL1_NOT:%.*]] = icmp eq i32 [[CALL12]], 0
509; ATTRIBUTOR-NEXT:    br i1 [[TOBOOL1_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]]
510; ATTRIBUTOR:       if.then2:
511; ATTRIBUTOR-NEXT:    tail call void @cold1()
512; ATTRIBUTOR-NEXT:    br label [[IF_END16:%.*]]
513; ATTRIBUTOR:       if.else:
514; ATTRIBUTOR-NEXT:    [[CALL3:%.*]] = tail call i32 @get_val()
515; ATTRIBUTOR-NEXT:    [[TOBOOL4_NOT:%.*]] = icmp eq i32 [[CALL3]], 0
516; ATTRIBUTOR-NEXT:    br i1 [[TOBOOL4_NOT]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]]
517; ATTRIBUTOR:       if.then5:
518; ATTRIBUTOR-NEXT:    tail call void @cold0()
519; ATTRIBUTOR-NEXT:    br label [[IF_END16]]
520; ATTRIBUTOR:       if.else6:
521; ATTRIBUTOR-NEXT:    tail call void @not_cold0()
522; ATTRIBUTOR-NEXT:    [[CALL7:%.*]] = tail call i32 @get_val()
523; ATTRIBUTOR-NEXT:    switch i32 [[CALL7]], label [[SW_DEFAULT:%.*]] [
524; ATTRIBUTOR-NEXT:      i32 0, label [[SW_BB:%.*]]
525; ATTRIBUTOR-NEXT:      i32 1, label [[SW_BB8:%.*]]
526; ATTRIBUTOR-NEXT:      i32 2, label [[SW_BB9:%.*]]
527; ATTRIBUTOR-NEXT:    ]
528; ATTRIBUTOR:       sw.bb:
529; ATTRIBUTOR-NEXT:    tail call void @not_cold0()
530; ATTRIBUTOR-NEXT:    br label [[CALL_COLD:%.*]]
531; ATTRIBUTOR:       sw.bb8:
532; ATTRIBUTOR-NEXT:    tail call void @not_cold1()
533; ATTRIBUTOR-NEXT:    br label [[CALL_COLD]]
534; ATTRIBUTOR:       sw.bb9:
535; ATTRIBUTOR-NEXT:    tail call void @not_cold2()
536; ATTRIBUTOR-NEXT:    br label [[CALL_COLD]]
537; ATTRIBUTOR:       sw.default:
538; ATTRIBUTOR-NEXT:    tail call void @cold0()
539; ATTRIBUTOR-NEXT:    br label [[IF_END16]]
540; ATTRIBUTOR:       call_cold:
541; ATTRIBUTOR-NEXT:    tail call void @cold_at_cb() #[[ATTR0]]
542; ATTRIBUTOR-NEXT:    br label [[IF_END16]]
543; ATTRIBUTOR:       if.else11:
544; ATTRIBUTOR-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CALL12]], 1
545; ATTRIBUTOR-NEXT:    br i1 [[CMP]], label [[IF_END14:%.*]], label [[FOR_BODY:%.*]]
546; ATTRIBUTOR:       if.end14:
547; ATTRIBUTOR-NEXT:    tail call void @cold1()
548; ATTRIBUTOR-NEXT:    br label [[IF_END16]]
549; ATTRIBUTOR:       for.body:
550; ATTRIBUTOR-NEXT:    [[I_021:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[IF_ELSE11]] ]
551; ATTRIBUTOR-NEXT:    tail call void @cold0()
552; ATTRIBUTOR-NEXT:    [[INC]] = add nuw nsw i32 [[I_021]], 1
553; ATTRIBUTOR-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[CALL12]]
554; ATTRIBUTOR-NEXT:    br i1 [[EXITCOND_NOT]], label [[IF_END16]], label [[FOR_BODY]]
555; ATTRIBUTOR:       if.end16:
556; ATTRIBUTOR-NEXT:    ret void
557;
558entry:
559  tail call void @not_cold0()
560  %tobool.not = icmp eq i32 %x, 0
561  %call12 = tail call i32 @get_val()
562  br i1 %tobool.not, label %if.else11, label %if.then
563
564if.then:
565  %tobool1.not = icmp eq i32 %call12, 0
566  br i1 %tobool1.not, label %if.else, label %if.then2
567
568if.then2:
569  tail call void @cold1()
570  br label %if.end16
571
572if.else:
573  %call3 = tail call i32 @get_val()
574  %tobool4.not = icmp eq i32 %call3, 0
575  br i1 %tobool4.not, label %if.else6, label %if.then5
576
577if.then5:
578  tail call void @cold0()
579  br label %if.end16
580
581if.else6:
582  tail call void @not_cold0()
583  %call7 = tail call i32 @get_val()
584  switch i32 %call7, label %sw.default [
585  i32 0, label %sw.bb
586  i32 1, label %sw.bb8
587  i32 2, label %sw.bb9
588  ]
589
590sw.bb:
591  tail call void @not_cold0()
592  br label %call_cold
593
594sw.bb8:
595  tail call void @not_cold1()
596  br label %call_cold
597
598sw.bb9:
599  tail call void @not_cold2()
600  br label %call_cold
601
602sw.default:
603  tail call void @cold0()
604  br label %if.end16
605
606call_cold:
607  tail call void @cold_at_cb() cold
608  br label %if.end16
609
610if.else11:
611  %cmp = icmp slt i32 %call12, 1
612  br i1 %cmp, label %if.end14, label %for.body
613
614if.end14:
615  tail call void @cold1()
616  br label %if.end16
617
618for.body:
619  %i.021 = phi i32 [ %inc, %for.body ], [ 0, %if.else11 ]
620  tail call void @cold0()
621  %inc = add nuw nsw i32 %i.021, 1
622  %exitcond.not = icmp eq i32 %inc, %call12
623  br i1 %exitcond.not, label %if.end16, label %for.body
624
625if.end16:
626  ret void
627}
628
629define dso_local void @test_complex_fail(i32 noundef %x) {
630; COMMON-LABEL: define dso_local void @test_complex_fail
631; COMMON-SAME: (i32 noundef [[X:%.*]]) {
632; COMMON-NEXT:  entry:
633; COMMON-NEXT:    tail call void @not_cold0()
634; COMMON-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0
635; COMMON-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_ELSE11:%.*]], label [[IF_THEN:%.*]]
636; COMMON:       if.then:
637; COMMON-NEXT:    [[CALL:%.*]] = tail call i32 @get_val()
638; COMMON-NEXT:    [[TOBOOL1_NOT:%.*]] = icmp eq i32 [[CALL]], 0
639; COMMON-NEXT:    br i1 [[TOBOOL1_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]]
640; COMMON:       if.then2:
641; COMMON-NEXT:    tail call void @cold1()
642; COMMON-NEXT:    br label [[IF_END12:%.*]]
643; COMMON:       if.else:
644; COMMON-NEXT:    [[CALL3:%.*]] = tail call i32 @get_val()
645; COMMON-NEXT:    [[TOBOOL4_NOT:%.*]] = icmp eq i32 [[CALL3]], 0
646; COMMON-NEXT:    br i1 [[TOBOOL4_NOT]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]]
647; COMMON:       if.then5:
648; COMMON-NEXT:    tail call void @cold0()
649; COMMON-NEXT:    br label [[IF_END12]]
650; COMMON:       if.else6:
651; COMMON-NEXT:    tail call void @not_cold0()
652; COMMON-NEXT:    [[CALL7:%.*]] = tail call i32 @get_val()
653; COMMON-NEXT:    switch i32 [[CALL7]], label [[SW_DEFAULT:%.*]] [
654; COMMON-NEXT:      i32 0, label [[SW_BB:%.*]]
655; COMMON-NEXT:      i32 1, label [[SW_BB8:%.*]]
656; COMMON-NEXT:      i32 2, label [[SW_BB9:%.*]]
657; COMMON-NEXT:    ]
658; COMMON:       sw.bb:
659; COMMON-NEXT:    tail call void @not_cold0()
660; COMMON-NEXT:    br label [[CALL_COLD:%.*]]
661; COMMON:       sw.bb8:
662; COMMON-NEXT:    tail call void @not_cold1()
663; COMMON-NEXT:    br label [[CALL_COLD]]
664; COMMON:       sw.bb9:
665; COMMON-NEXT:    tail call void @not_cold2()
666; COMMON-NEXT:    br label [[IF_END12]]
667; COMMON:       sw.default:
668; COMMON-NEXT:    tail call void @cold0()
669; COMMON-NEXT:    br label [[IF_END12]]
670; COMMON:       call_cold:
671; COMMON-NEXT:    tail call void @cold_at_cb() #[[ATTR0:[0-9]+]]
672; COMMON-NEXT:    br label [[IF_END12]]
673; COMMON:       if.else11:
674; COMMON-NEXT:    tail call void @cold0()
675; COMMON-NEXT:    br label [[IF_END12]]
676; COMMON:       if.end12:
677; COMMON-NEXT:    ret void
678;
679entry:
680  tail call void @not_cold0()
681  %tobool.not = icmp eq i32 %x, 0
682  br i1 %tobool.not, label %if.else11, label %if.then
683
684if.then:
685  %call = tail call i32 @get_val()
686  %tobool1.not = icmp eq i32 %call, 0
687  br i1 %tobool1.not, label %if.else, label %if.then2
688
689if.then2:
690  tail call void @cold1()
691  br label %if.end12
692
693if.else:
694  %call3 = tail call i32 @get_val()
695  %tobool4.not = icmp eq i32 %call3, 0
696  br i1 %tobool4.not, label %if.else6, label %if.then5
697
698if.then5:
699  tail call void @cold0()
700  br label %if.end12
701
702if.else6:
703  tail call void @not_cold0()
704  %call7 = tail call i32 @get_val()
705  switch i32 %call7, label %sw.default [
706  i32 0, label %sw.bb
707  i32 1, label %sw.bb8
708  i32 2, label %sw.bb9
709  ]
710
711sw.bb:
712  tail call void @not_cold0()
713  br label %call_cold
714
715sw.bb8:
716  tail call void @not_cold1()
717  br label %call_cold
718
719sw.bb9:
720  tail call void @not_cold2()
721  br label %if.end12
722
723sw.default:
724  tail call void @cold0()
725  br label %if.end12
726
727call_cold:
728  tail call void @cold_at_cb() cold
729  br label %if.end12
730
731if.else11:
732  tail call void @cold0()
733  br label %if.end12
734
735if.end12:
736  ret void
737}
738
739define dso_local void @test_complex2_fail(i32 noundef %x) {
740; COMMON-LABEL: define dso_local void @test_complex2_fail
741; COMMON-SAME: (i32 noundef [[X:%.*]]) {
742; COMMON-NEXT:  entry:
743; COMMON-NEXT:    tail call void @not_cold0()
744; COMMON-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0
745; COMMON-NEXT:    [[CALL12:%.*]] = tail call i32 @get_val()
746; COMMON-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_ELSE11:%.*]], label [[IF_THEN:%.*]]
747; COMMON:       if.then:
748; COMMON-NEXT:    [[TOBOOL1_NOT:%.*]] = icmp eq i32 [[CALL12]], 0
749; COMMON-NEXT:    br i1 [[TOBOOL1_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]]
750; COMMON:       if.then2:
751; COMMON-NEXT:    tail call void @cold1()
752; COMMON-NEXT:    br label [[IF_END16:%.*]]
753; COMMON:       if.else:
754; COMMON-NEXT:    [[CALL3:%.*]] = tail call i32 @get_val()
755; COMMON-NEXT:    [[TOBOOL4_NOT:%.*]] = icmp eq i32 [[CALL3]], 0
756; COMMON-NEXT:    br i1 [[TOBOOL4_NOT]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]]
757; COMMON:       if.then5:
758; COMMON-NEXT:    tail call void @cold0()
759; COMMON-NEXT:    br label [[IF_END16]]
760; COMMON:       if.else6:
761; COMMON-NEXT:    tail call void @not_cold0()
762; COMMON-NEXT:    [[CALL7:%.*]] = tail call i32 @get_val()
763; COMMON-NEXT:    switch i32 [[CALL7]], label [[SW_DEFAULT:%.*]] [
764; COMMON-NEXT:      i32 0, label [[SW_BB:%.*]]
765; COMMON-NEXT:      i32 1, label [[SW_BB8:%.*]]
766; COMMON-NEXT:      i32 2, label [[SW_BB9:%.*]]
767; COMMON-NEXT:    ]
768; COMMON:       sw.bb:
769; COMMON-NEXT:    tail call void @not_cold0()
770; COMMON-NEXT:    br label [[CALL_COLD:%.*]]
771; COMMON:       sw.bb8:
772; COMMON-NEXT:    tail call void @not_cold1()
773; COMMON-NEXT:    br label [[CALL_COLD]]
774; COMMON:       sw.bb9:
775; COMMON-NEXT:    tail call void @not_cold2()
776; COMMON-NEXT:    br label [[CALL_COLD]]
777; COMMON:       sw.default:
778; COMMON-NEXT:    tail call void @cold0()
779; COMMON-NEXT:    br label [[IF_END16]]
780; COMMON:       call_cold:
781; COMMON-NEXT:    tail call void @cold_at_cb() #[[ATTR0]]
782; COMMON-NEXT:    br label [[IF_END16]]
783; COMMON:       if.else11:
784; COMMON-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CALL12]], 1
785; COMMON-NEXT:    br i1 [[CMP]], label [[IF_END14:%.*]], label [[FOR_BODY:%.*]]
786; COMMON:       if.end14:
787; COMMON-NEXT:    tail call void @not_cold1()
788; COMMON-NEXT:    br label [[IF_END16]]
789; COMMON:       for.body:
790; COMMON-NEXT:    [[I_021:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[IF_ELSE11]] ]
791; COMMON-NEXT:    tail call void @cold0()
792; COMMON-NEXT:    [[INC]] = add nuw nsw i32 [[I_021]], 1
793; COMMON-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[CALL12]]
794; COMMON-NEXT:    br i1 [[EXITCOND_NOT]], label [[IF_END16]], label [[FOR_BODY]]
795; COMMON:       if.end16:
796; COMMON-NEXT:    ret void
797;
798entry:
799  tail call void @not_cold0()
800  %tobool.not = icmp eq i32 %x, 0
801  %call12 = tail call i32 @get_val()
802  br i1 %tobool.not, label %if.else11, label %if.then
803
804if.then:
805  %tobool1.not = icmp eq i32 %call12, 0
806  br i1 %tobool1.not, label %if.else, label %if.then2
807
808if.then2:
809  tail call void @cold1()
810  br label %if.end16
811
812if.else:
813  %call3 = tail call i32 @get_val()
814  %tobool4.not = icmp eq i32 %call3, 0
815  br i1 %tobool4.not, label %if.else6, label %if.then5
816
817if.then5:
818  tail call void @cold0()
819  br label %if.end16
820
821if.else6:
822  tail call void @not_cold0()
823  %call7 = tail call i32 @get_val()
824  switch i32 %call7, label %sw.default [
825  i32 0, label %sw.bb
826  i32 1, label %sw.bb8
827  i32 2, label %sw.bb9
828  ]
829
830sw.bb:
831  tail call void @not_cold0()
832  br label %call_cold
833
834sw.bb8:
835  tail call void @not_cold1()
836  br label %call_cold
837
838sw.bb9:
839  tail call void @not_cold2()
840  br label %call_cold
841
842sw.default:
843  tail call void @cold0()
844  br label %if.end16
845
846call_cold:
847  tail call void @cold_at_cb() cold
848  br label %if.end16
849
850if.else11:
851  %cmp = icmp slt i32 %call12, 1
852  br i1 %cmp, label %if.end14, label %for.body
853
854if.end14:
855  tail call void @not_cold1()
856  br label %if.end16
857
858for.body:
859  %i.021 = phi i32 [ %inc, %for.body ], [ 0, %if.else11 ]
860  tail call void @cold0()
861  %inc = add nuw nsw i32 %i.021, 1
862  %exitcond.not = icmp eq i32 %inc, %call12
863  br i1 %exitcond.not, label %if.end16, label %for.body
864
865if.end16:
866  ret void
867}
868
869;.
870; FNATTRS: attributes #[[ATTR0]] = { cold }
871; FNATTRS: attributes #[[ATTR1]] = { nofree norecurse noreturn nosync nounwind memory(none) }
872; FNATTRS: attributes #[[ATTR2]] = { noreturn }
873; FNATTRS: attributes #[[ATTR3]] = { cold noreturn }
874; FNATTRS: attributes #[[ATTR4]] = { hot }
875;.
876; ATTRIBUTOR: attributes #[[ATTR0]] = { cold }
877; ATTRIBUTOR: attributes #[[ATTR1]] = { nofree norecurse noreturn nosync nounwind memory(none) }
878; ATTRIBUTOR: attributes #[[ATTR2]] = { noreturn }
879; ATTRIBUTOR: attributes #[[ATTR3]] = { hot }
880;.
881