1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -march=amdgcn -mcpu=verde -verify-machineinstrs | FileCheck --check-prefix=SI %s
3; RUN: llc < %s -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs | FileCheck --check-prefix=FLAT %s
4
5define amdgpu_kernel void @break_inserted_outside_of_loop(i32 addrspace(1)* %out, i32 %a) {
6; SI-LABEL: break_inserted_outside_of_loop:
7; SI:       ; %bb.0: ; %main_body
8; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
9; SI-NEXT:    s_load_dword s0, s[0:1], 0xb
10; SI-NEXT:    v_mbcnt_lo_u32_b32_e64 v0, -1, 0
11; SI-NEXT:    s_waitcnt lgkmcnt(0)
12; SI-NEXT:    v_and_b32_e32 v0, s0, v0
13; SI-NEXT:    v_and_b32_e32 v0, 1, v0
14; SI-NEXT:    v_cmp_eq_u32_e32 vcc, 1, v0
15; SI-NEXT:    s_mov_b64 s[0:1], 0
16; SI-NEXT:  BB0_1: ; %ENDIF
17; SI-NEXT:    ; =>This Inner Loop Header: Depth=1
18; SI-NEXT:    s_and_b64 s[2:3], exec, vcc
19; SI-NEXT:    s_or_b64 s[0:1], s[2:3], s[0:1]
20; SI-NEXT:    s_andn2_b64 exec, exec, s[0:1]
21; SI-NEXT:    s_cbranch_execnz BB0_1
22; SI-NEXT:  ; %bb.2: ; %ENDLOOP
23; SI-NEXT:    s_or_b64 exec, exec, s[0:1]
24; SI-NEXT:    s_mov_b32 s7, 0xf000
25; SI-NEXT:    s_mov_b32 s6, -1
26; SI-NEXT:    v_mov_b32_e32 v0, 0
27; SI-NEXT:    buffer_store_dword v0, off, s[4:7], 0
28; SI-NEXT:    s_endpgm
29;
30; FLAT-LABEL: break_inserted_outside_of_loop:
31; FLAT:       ; %bb.0: ; %main_body
32; FLAT-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
33; FLAT-NEXT:    s_load_dword s0, s[0:1], 0x2c
34; FLAT-NEXT:    v_mbcnt_lo_u32_b32 v0, -1, 0
35; FLAT-NEXT:    s_waitcnt lgkmcnt(0)
36; FLAT-NEXT:    v_and_b32_e32 v0, s0, v0
37; FLAT-NEXT:    v_and_b32_e32 v0, 1, v0
38; FLAT-NEXT:    v_cmp_eq_u32_e32 vcc, 1, v0
39; FLAT-NEXT:    s_mov_b64 s[0:1], 0
40; FLAT-NEXT:  BB0_1: ; %ENDIF
41; FLAT-NEXT:    ; =>This Inner Loop Header: Depth=1
42; FLAT-NEXT:    s_and_b64 s[2:3], exec, vcc
43; FLAT-NEXT:    s_or_b64 s[0:1], s[2:3], s[0:1]
44; FLAT-NEXT:    s_andn2_b64 exec, exec, s[0:1]
45; FLAT-NEXT:    s_cbranch_execnz BB0_1
46; FLAT-NEXT:  ; %bb.2: ; %ENDLOOP
47; FLAT-NEXT:    s_or_b64 exec, exec, s[0:1]
48; FLAT-NEXT:    s_mov_b32 s7, 0xf000
49; FLAT-NEXT:    s_mov_b32 s6, -1
50; FLAT-NEXT:    v_mov_b32_e32 v0, 0
51; FLAT-NEXT:    buffer_store_dword v0, off, s[4:7], 0
52; FLAT-NEXT:    s_endpgm
53main_body:
54  %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
55  %0 = and i32 %a, %tid
56  %1 = trunc i32 %0 to i1
57  br label %ENDIF
58
59ENDLOOP:
60  store i32 0, i32 addrspace(1)* %out
61  ret void
62
63ENDIF:
64  br i1 %1, label %ENDLOOP, label %ENDIF
65}
66
67define amdgpu_kernel void @phi_cond_outside_loop(i32 %b) {
68; SI-LABEL: phi_cond_outside_loop:
69; SI:       ; %bb.0: ; %entry
70; SI-NEXT:    v_mbcnt_lo_u32_b32_e64 v0, -1, 0
71; SI-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v0
72; SI-NEXT:    s_mov_b64 s[2:3], 0
73; SI-NEXT:    s_mov_b64 s[4:5], 0
74; SI-NEXT:    s_and_saveexec_b64 s[6:7], vcc
75; SI-NEXT:    s_cbranch_execz BB1_2
76; SI-NEXT:  ; %bb.1: ; %else
77; SI-NEXT:    s_load_dword s0, s[0:1], 0x9
78; SI-NEXT:    s_waitcnt lgkmcnt(0)
79; SI-NEXT:    v_cmp_eq_u32_e64 s[0:1], s0, 0
80; SI-NEXT:    s_and_b64 s[4:5], s[0:1], exec
81; SI-NEXT:  BB1_2: ; %endif
82; SI-NEXT:    s_or_b64 exec, exec, s[6:7]
83; SI-NEXT:  BB1_3: ; %loop
84; SI-NEXT:    ; =>This Inner Loop Header: Depth=1
85; SI-NEXT:    s_and_b64 s[0:1], exec, s[4:5]
86; SI-NEXT:    s_or_b64 s[2:3], s[0:1], s[2:3]
87; SI-NEXT:    s_andn2_b64 exec, exec, s[2:3]
88; SI-NEXT:    s_cbranch_execnz BB1_3
89; SI-NEXT:  ; %bb.4: ; %exit
90; SI-NEXT:    s_endpgm
91;
92; FLAT-LABEL: phi_cond_outside_loop:
93; FLAT:       ; %bb.0: ; %entry
94; FLAT-NEXT:    v_mbcnt_lo_u32_b32 v0, -1, 0
95; FLAT-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v0
96; FLAT-NEXT:    s_mov_b64 s[2:3], 0
97; FLAT-NEXT:    s_mov_b64 s[4:5], 0
98; FLAT-NEXT:    s_and_saveexec_b64 s[6:7], vcc
99; FLAT-NEXT:    s_cbranch_execz BB1_2
100; FLAT-NEXT:  ; %bb.1: ; %else
101; FLAT-NEXT:    s_load_dword s0, s[0:1], 0x24
102; FLAT-NEXT:    s_waitcnt lgkmcnt(0)
103; FLAT-NEXT:    v_cmp_eq_u32_e64 s[0:1], s0, 0
104; FLAT-NEXT:    s_and_b64 s[4:5], s[0:1], exec
105; FLAT-NEXT:  BB1_2: ; %endif
106; FLAT-NEXT:    s_or_b64 exec, exec, s[6:7]
107; FLAT-NEXT:  BB1_3: ; %loop
108; FLAT-NEXT:    ; =>This Inner Loop Header: Depth=1
109; FLAT-NEXT:    s_and_b64 s[0:1], exec, s[4:5]
110; FLAT-NEXT:    s_or_b64 s[2:3], s[0:1], s[2:3]
111; FLAT-NEXT:    s_andn2_b64 exec, exec, s[2:3]
112; FLAT-NEXT:    s_cbranch_execnz BB1_3
113; FLAT-NEXT:  ; %bb.4: ; %exit
114; FLAT-NEXT:    s_endpgm
115entry:
116  %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
117  %0 = icmp eq i32 %tid , 0
118  br i1 %0, label %if, label %else
119
120if:
121  br label %endif
122
123else:
124  %1 = icmp eq i32 %b, 0
125  br label %endif
126
127endif:
128  %2 = phi i1 [0, %if], [%1, %else]
129  br label %loop
130
131loop:
132  br i1 %2, label %exit, label %loop
133
134exit:
135  ret void
136}
137
138define amdgpu_kernel void @switch_unreachable(i32 addrspace(1)* %g, i8 addrspace(3)* %l, i32 %x) nounwind {
139; SI-LABEL: switch_unreachable:
140; SI:       ; %bb.0: ; %centry
141;
142; FLAT-LABEL: switch_unreachable:
143; FLAT:       ; %bb.0: ; %centry
144centry:
145  switch i32 %x, label %sw.default [
146    i32 0, label %sw.bb
147    i32 60, label %sw.bb
148  ]
149
150sw.bb:
151  unreachable
152
153sw.default:
154  unreachable
155
156sw.epilog:
157  ret void
158}
159
160declare float @llvm.fabs.f32(float) nounwind readnone
161
162define amdgpu_kernel void @loop_land_info_assert(i32 %c0, i32 %c1, i32 %c2, i32 %c3, i32 %x, i32 %y, i1 %arg) nounwind {
163; SI-LABEL: loop_land_info_assert:
164; SI:       ; %bb.0: ; %entry
165; SI-NEXT:    s_mov_b32 s7, 0xf000
166; SI-NEXT:    s_mov_b32 s6, -1
167; SI-NEXT:    buffer_load_dword v0, off, s[4:7], 0
168; SI-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x9
169; SI-NEXT:    s_load_dword s4, s[0:1], 0xc
170; SI-NEXT:    s_brev_b32 s5, 44
171; SI-NEXT:    s_waitcnt lgkmcnt(0)
172; SI-NEXT:    v_cmp_gt_i32_e64 s[0:1], s2, 0
173; SI-NEXT:    v_cmp_lt_i32_e64 s[2:3], s3, 4
174; SI-NEXT:    s_or_b64 s[8:9], s[0:1], s[2:3]
175; SI-NEXT:    s_and_b64 s[0:1], exec, s[2:3]
176; SI-NEXT:    s_and_b64 s[2:3], exec, s[8:9]
177; SI-NEXT:    s_waitcnt vmcnt(0)
178; SI-NEXT:    v_cmp_lt_f32_e64 s[8:9], |v0|, s5
179; SI-NEXT:    v_mov_b32_e32 v0, 3
180; SI-NEXT:  BB3_1: ; %while.cond
181; SI-NEXT:    ; =>This Inner Loop Header: Depth=1
182; SI-NEXT:    s_mov_b64 vcc, s[0:1]
183; SI-NEXT:    s_cbranch_vccz BB3_5
184; SI-NEXT:  ; %bb.2: ; %convex.exit
185; SI-NEXT:    ; in Loop: Header=BB3_1 Depth=1
186; SI-NEXT:    s_mov_b64 vcc, s[2:3]
187; SI-NEXT:    s_cbranch_vccnz BB3_8
188; SI-NEXT:  ; %bb.3: ; %if.end
189; SI-NEXT:    ; in Loop: Header=BB3_1 Depth=1
190; SI-NEXT:    s_andn2_b64 vcc, exec, s[8:9]
191; SI-NEXT:    s_cbranch_vccnz BB3_1
192; SI-NEXT:  ; %bb.4: ; %if.else
193; SI-NEXT:    ; in Loop: Header=BB3_1 Depth=1
194; SI-NEXT:    buffer_store_dword v0, off, s[4:7], 0
195; SI-NEXT:    s_branch BB3_1
196; SI-NEXT:  BB3_5: ; %for.cond.preheader
197; SI-NEXT:    s_waitcnt expcnt(0)
198; SI-NEXT:    v_mov_b32_e32 v0, 0x3e8
199; SI-NEXT:    v_cmp_lt_i32_e32 vcc, s4, v0
200; SI-NEXT:    s_and_b64 vcc, exec, vcc
201; SI-NEXT:    s_cbranch_vccz BB3_8
202; SI-NEXT:  ; %bb.6: ; %for.body
203; SI-NEXT:    s_and_b64 vcc, exec, 0
204; SI-NEXT:  BB3_7: ; %self.loop
205; SI-NEXT:    ; =>This Inner Loop Header: Depth=1
206; SI-NEXT:    s_cbranch_vccz BB3_7
207; SI-NEXT:  BB3_8: ; %DummyReturnBlock
208; SI-NEXT:    s_endpgm
209;
210; FLAT-LABEL: loop_land_info_assert:
211; FLAT:       ; %bb.0: ; %entry
212; FLAT-NEXT:    s_mov_b32 s7, 0xf000
213; FLAT-NEXT:    s_mov_b32 s6, -1
214; FLAT-NEXT:    buffer_load_dword v0, off, s[4:7], 0
215; FLAT-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x24
216; FLAT-NEXT:    s_load_dword s4, s[0:1], 0x30
217; FLAT-NEXT:    s_brev_b32 s5, 44
218; FLAT-NEXT:    s_waitcnt lgkmcnt(0)
219; FLAT-NEXT:    v_cmp_gt_i32_e64 s[0:1], s2, 0
220; FLAT-NEXT:    v_cmp_lt_i32_e64 s[2:3], s3, 4
221; FLAT-NEXT:    s_or_b64 s[8:9], s[0:1], s[2:3]
222; FLAT-NEXT:    s_and_b64 s[0:1], exec, s[2:3]
223; FLAT-NEXT:    s_and_b64 s[2:3], exec, s[8:9]
224; FLAT-NEXT:    s_waitcnt vmcnt(0)
225; FLAT-NEXT:    v_cmp_lt_f32_e64 s[8:9], |v0|, s5
226; FLAT-NEXT:    v_mov_b32_e32 v0, 3
227; FLAT-NEXT:  BB3_1: ; %while.cond
228; FLAT-NEXT:    ; =>This Inner Loop Header: Depth=1
229; FLAT-NEXT:    s_mov_b64 vcc, s[0:1]
230; FLAT-NEXT:    s_cbranch_vccz BB3_5
231; FLAT-NEXT:  ; %bb.2: ; %convex.exit
232; FLAT-NEXT:    ; in Loop: Header=BB3_1 Depth=1
233; FLAT-NEXT:    s_mov_b64 vcc, s[2:3]
234; FLAT-NEXT:    s_cbranch_vccnz BB3_8
235; FLAT-NEXT:  ; %bb.3: ; %if.end
236; FLAT-NEXT:    ; in Loop: Header=BB3_1 Depth=1
237; FLAT-NEXT:    s_andn2_b64 vcc, exec, s[8:9]
238; FLAT-NEXT:    s_cbranch_vccnz BB3_1
239; FLAT-NEXT:  ; %bb.4: ; %if.else
240; FLAT-NEXT:    ; in Loop: Header=BB3_1 Depth=1
241; FLAT-NEXT:    buffer_store_dword v0, off, s[4:7], 0
242; FLAT-NEXT:    s_branch BB3_1
243; FLAT-NEXT:  BB3_5: ; %for.cond.preheader
244; FLAT-NEXT:    v_mov_b32_e32 v0, 0x3e8
245; FLAT-NEXT:    v_cmp_lt_i32_e32 vcc, s4, v0
246; FLAT-NEXT:    s_and_b64 vcc, exec, vcc
247; FLAT-NEXT:    s_cbranch_vccz BB3_8
248; FLAT-NEXT:  ; %bb.6: ; %for.body
249; FLAT-NEXT:    s_and_b64 vcc, exec, 0
250; FLAT-NEXT:  BB3_7: ; %self.loop
251; FLAT-NEXT:    ; =>This Inner Loop Header: Depth=1
252; FLAT-NEXT:    s_cbranch_vccz BB3_7
253; FLAT-NEXT:  BB3_8: ; %DummyReturnBlock
254; FLAT-NEXT:    s_endpgm
255entry:
256  %cmp = icmp sgt i32 %c0, 0
257  br label %while.cond.outer
258
259while.cond.outer:
260  %tmp = load float, float addrspace(1)* undef
261  br label %while.cond
262
263while.cond:
264  %cmp1 = icmp slt i32 %c1, 4
265  br i1 %cmp1, label %convex.exit, label %for.cond
266
267convex.exit:
268  %or = or i1 %cmp, %cmp1
269  br i1 %or, label %return, label %if.end
270
271if.end:
272  %tmp3 = call float @llvm.fabs.f32(float %tmp) nounwind readnone
273  %cmp2 = fcmp olt float %tmp3, 0x3E80000000000000
274  br i1 %cmp2, label %if.else, label %while.cond.outer
275
276if.else:
277  store volatile i32 3, i32 addrspace(1)* undef, align 4
278  br label %while.cond
279
280for.cond:
281  %cmp3 = icmp slt i32 %c3, 1000
282  br i1 %cmp3, label %for.body, label %return
283
284for.body:
285  br i1 %cmp3, label %self.loop, label %if.end.2
286
287if.end.2:
288  %or.cond2 = or i1 %cmp3, %arg
289  br i1 %or.cond2, label %return, label %for.cond
290
291self.loop:
292 br label %self.loop
293
294return:
295  ret void
296}
297
298declare i32 @llvm.amdgcn.mbcnt.lo(i32, i32) #0
299
300attributes #0 = { nounwind readnone }
301