xref: /aosp_15_r20/external/llvm/test/CodeGen/AMDGPU/uniform-cfg.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -march=amdgcn -mcpu=verde -verify-machineinstrs | FileCheck --check-prefix=SI %s
2*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -march=amdgcn -mcpu=tonga -verify-machineinstrs | FileCheck --check-prefix=SI %s
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}uniform_if_scc:
5*9880d681SAndroid Build Coastguard Worker; SI-DAG: s_cmp_eq_i32 s{{[0-9]+}}, 0
6*9880d681SAndroid Build Coastguard Worker; SI-DAG: v_mov_b32_e32 [[STORE_VAL:v[0-9]+]], 0
7*9880d681SAndroid Build Coastguard Worker; SI: s_cbranch_scc1 [[IF_LABEL:[0-9_A-Za-z]+]]
8*9880d681SAndroid Build Coastguard Worker
9*9880d681SAndroid Build Coastguard Worker; Fall-through to the else
10*9880d681SAndroid Build Coastguard Worker; SI: v_mov_b32_e32 [[STORE_VAL]], 1
11*9880d681SAndroid Build Coastguard Worker
12*9880d681SAndroid Build Coastguard Worker; SI: [[IF_LABEL]]:
13*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword [[STORE_VAL]]
14*9880d681SAndroid Build Coastguard Workerdefine void @uniform_if_scc(i32 %cond, i32 addrspace(1)* %out) {
15*9880d681SAndroid Build Coastguard Workerentry:
16*9880d681SAndroid Build Coastguard Worker  %cmp0 = icmp eq i32 %cond, 0
17*9880d681SAndroid Build Coastguard Worker  br i1 %cmp0, label %if, label %else
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Workerif:
20*9880d681SAndroid Build Coastguard Worker  br label %done
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Workerelse:
23*9880d681SAndroid Build Coastguard Worker  br label %done
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Workerdone:
26*9880d681SAndroid Build Coastguard Worker  %value = phi i32 [0, %if], [1, %else]
27*9880d681SAndroid Build Coastguard Worker  store i32 %value, i32 addrspace(1)* %out
28*9880d681SAndroid Build Coastguard Worker  ret void
29*9880d681SAndroid Build Coastguard Worker}
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}uniform_if_vcc:
32*9880d681SAndroid Build Coastguard Worker; FIXME: We could use _e32 here if we re-used the 0 from [[STORE_VAL]], and
33*9880d681SAndroid Build Coastguard Worker; also scheduled the write first.
34*9880d681SAndroid Build Coastguard Worker; SI-DAG: v_cmp_eq_f32_e64 [[COND:vcc|s\[[0-9]+:[0-9]+\]]], 0, s{{[0-9]+}}
35*9880d681SAndroid Build Coastguard Worker; SI-DAG: s_and_b64 vcc, exec, [[COND]]
36*9880d681SAndroid Build Coastguard Worker; SI-DAG: v_mov_b32_e32 [[STORE_VAL:v[0-9]+]], 0
37*9880d681SAndroid Build Coastguard Worker; SI: s_cbranch_vccnz [[IF_LABEL:[0-9_A-Za-z]+]]
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker; Fall-through to the else
40*9880d681SAndroid Build Coastguard Worker; SI: v_mov_b32_e32 [[STORE_VAL]], 1
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker; SI: [[IF_LABEL]]:
43*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword [[STORE_VAL]]
44*9880d681SAndroid Build Coastguard Workerdefine void @uniform_if_vcc(float %cond, i32 addrspace(1)* %out) {
45*9880d681SAndroid Build Coastguard Workerentry:
46*9880d681SAndroid Build Coastguard Worker  %cmp0 = fcmp oeq float %cond, 0.0
47*9880d681SAndroid Build Coastguard Worker  br i1 %cmp0, label %if, label %else
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Workerif:
50*9880d681SAndroid Build Coastguard Worker  br label %done
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Workerelse:
53*9880d681SAndroid Build Coastguard Worker  br label %done
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Workerdone:
56*9880d681SAndroid Build Coastguard Worker  %value = phi i32 [0, %if], [1, %else]
57*9880d681SAndroid Build Coastguard Worker  store i32 %value, i32 addrspace(1)* %out
58*9880d681SAndroid Build Coastguard Worker  ret void
59*9880d681SAndroid Build Coastguard Worker}
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}uniform_if_swap_br_targets_scc:
62*9880d681SAndroid Build Coastguard Worker; SI-DAG: s_cmp_lg_i32 s{{[0-9]+}}, 0
63*9880d681SAndroid Build Coastguard Worker; SI-DAG: v_mov_b32_e32 [[STORE_VAL:v[0-9]+]], 0
64*9880d681SAndroid Build Coastguard Worker; SI: s_cbranch_scc1 [[IF_LABEL:[0-9_A-Za-z]+]]
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker; Fall-through to the else
67*9880d681SAndroid Build Coastguard Worker; SI: v_mov_b32_e32 [[STORE_VAL]], 1
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker; SI: [[IF_LABEL]]:
70*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword [[STORE_VAL]]
71*9880d681SAndroid Build Coastguard Workerdefine void @uniform_if_swap_br_targets_scc(i32 %cond, i32 addrspace(1)* %out) {
72*9880d681SAndroid Build Coastguard Workerentry:
73*9880d681SAndroid Build Coastguard Worker  %cmp0 = icmp eq i32 %cond, 0
74*9880d681SAndroid Build Coastguard Worker  br i1 %cmp0, label %else, label %if
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Workerif:
77*9880d681SAndroid Build Coastguard Worker  br label %done
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Workerelse:
80*9880d681SAndroid Build Coastguard Worker  br label %done
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Workerdone:
83*9880d681SAndroid Build Coastguard Worker  %value = phi i32 [0, %if], [1, %else]
84*9880d681SAndroid Build Coastguard Worker  store i32 %value, i32 addrspace(1)* %out
85*9880d681SAndroid Build Coastguard Worker  ret void
86*9880d681SAndroid Build Coastguard Worker}
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}uniform_if_swap_br_targets_vcc:
89*9880d681SAndroid Build Coastguard Worker; FIXME: We could use _e32 here if we re-used the 0 from [[STORE_VAL]], and
90*9880d681SAndroid Build Coastguard Worker; also scheduled the write first.
91*9880d681SAndroid Build Coastguard Worker; SI-DAG: v_cmp_neq_f32_e64 [[COND:vcc|s\[[0-9]+:[0-9]+\]]], 0, s{{[0-9]+}}
92*9880d681SAndroid Build Coastguard Worker; SI-DAG: s_and_b64 vcc, exec, [[COND]]
93*9880d681SAndroid Build Coastguard Worker; SI-DAG: v_mov_b32_e32 [[STORE_VAL:v[0-9]+]], 0
94*9880d681SAndroid Build Coastguard Worker; SI: s_cbranch_vccnz [[IF_LABEL:[0-9_A-Za-z]+]]
95*9880d681SAndroid Build Coastguard Worker
96*9880d681SAndroid Build Coastguard Worker; Fall-through to the else
97*9880d681SAndroid Build Coastguard Worker; SI: v_mov_b32_e32 [[STORE_VAL]], 1
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker; SI: [[IF_LABEL]]:
100*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword [[STORE_VAL]]
101*9880d681SAndroid Build Coastguard Workerdefine void @uniform_if_swap_br_targets_vcc(float %cond, i32 addrspace(1)* %out) {
102*9880d681SAndroid Build Coastguard Workerentry:
103*9880d681SAndroid Build Coastguard Worker  %cmp0 = fcmp oeq float %cond, 0.0
104*9880d681SAndroid Build Coastguard Worker  br i1 %cmp0, label %else, label %if
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Workerif:
107*9880d681SAndroid Build Coastguard Worker  br label %done
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Workerelse:
110*9880d681SAndroid Build Coastguard Worker  br label %done
111*9880d681SAndroid Build Coastguard Worker
112*9880d681SAndroid Build Coastguard Workerdone:
113*9880d681SAndroid Build Coastguard Worker  %value = phi i32 [0, %if], [1, %else]
114*9880d681SAndroid Build Coastguard Worker  store i32 %value, i32 addrspace(1)* %out
115*9880d681SAndroid Build Coastguard Worker  ret void
116*9880d681SAndroid Build Coastguard Worker}
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}uniform_if_move_valu:
119*9880d681SAndroid Build Coastguard Worker; SI: v_add_f32_e32 [[CMP:v[0-9]+]]
120*9880d681SAndroid Build Coastguard Worker; Using a floating-point value in an integer compare will cause the compare to
121*9880d681SAndroid Build Coastguard Worker; be selected for the SALU and then later moved to the VALU.
122*9880d681SAndroid Build Coastguard Worker; SI: v_cmp_ne_i32_e32 [[COND:vcc|s\[[0-9]+:[0-9]+\]]], 5, [[CMP]]
123*9880d681SAndroid Build Coastguard Worker; SI: s_and_b64 vcc, exec, [[COND]]
124*9880d681SAndroid Build Coastguard Worker; SI: s_cbranch_vccnz [[ENDIF_LABEL:[0-9_A-Za-z]+]]
125*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword
126*9880d681SAndroid Build Coastguard Worker; SI: [[ENDIF_LABEL]]:
127*9880d681SAndroid Build Coastguard Worker; SI: s_endpgm
128*9880d681SAndroid Build Coastguard Workerdefine void @uniform_if_move_valu(i32 addrspace(1)* %out, float %a) {
129*9880d681SAndroid Build Coastguard Workerentry:
130*9880d681SAndroid Build Coastguard Worker  %a.0 = fadd float %a, 10.0
131*9880d681SAndroid Build Coastguard Worker  %cond = bitcast float %a.0 to i32
132*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %cond, 5
133*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %if, label %endif
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Workerif:
136*9880d681SAndroid Build Coastguard Worker  store i32 0, i32 addrspace(1)* %out
137*9880d681SAndroid Build Coastguard Worker  br label %endif
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Workerendif:
140*9880d681SAndroid Build Coastguard Worker  ret void
141*9880d681SAndroid Build Coastguard Worker}
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}uniform_if_move_valu_commute:
144*9880d681SAndroid Build Coastguard Worker; SI: v_add_f32_e32 [[CMP:v[0-9]+]]
145*9880d681SAndroid Build Coastguard Worker; Using a floating-point value in an integer compare will cause the compare to
146*9880d681SAndroid Build Coastguard Worker; be selected for the SALU and then later moved to the VALU.
147*9880d681SAndroid Build Coastguard Worker; SI: v_cmp_gt_u32_e32 [[COND:vcc|s\[[0-9]+:[0-9]+\]]], 6, [[CMP]]
148*9880d681SAndroid Build Coastguard Worker; SI: s_and_b64 vcc, exec, [[COND]]
149*9880d681SAndroid Build Coastguard Worker; SI: s_cbranch_vccnz [[ENDIF_LABEL:[0-9_A-Za-z]+]]
150*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword
151*9880d681SAndroid Build Coastguard Worker; SI: [[ENDIF_LABEL]]:
152*9880d681SAndroid Build Coastguard Worker; SI: s_endpgm
153*9880d681SAndroid Build Coastguard Workerdefine void @uniform_if_move_valu_commute(i32 addrspace(1)* %out, float %a) {
154*9880d681SAndroid Build Coastguard Workerentry:
155*9880d681SAndroid Build Coastguard Worker  %a.0 = fadd float %a, 10.0
156*9880d681SAndroid Build Coastguard Worker  %cond = bitcast float %a.0 to i32
157*9880d681SAndroid Build Coastguard Worker  %cmp = icmp ugt i32 %cond, 5
158*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %if, label %endif
159*9880d681SAndroid Build Coastguard Worker
160*9880d681SAndroid Build Coastguard Workerif:
161*9880d681SAndroid Build Coastguard Worker  store i32 0, i32 addrspace(1)* %out
162*9880d681SAndroid Build Coastguard Worker  br label %endif
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Workerendif:
165*9880d681SAndroid Build Coastguard Worker  ret void
166*9880d681SAndroid Build Coastguard Worker}
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}uniform_if_else_ret:
170*9880d681SAndroid Build Coastguard Worker; SI: s_cmp_lg_i32 s{{[0-9]+}}, 0
171*9880d681SAndroid Build Coastguard Worker; SI-NEXT: s_cbranch_scc0 [[IF_LABEL:[0-9_A-Za-z]+]]
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Worker; SI: v_mov_b32_e32 [[TWO:v[0-9]+]], 2
174*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword [[TWO]]
175*9880d681SAndroid Build Coastguard Worker; SI: s_endpgm
176*9880d681SAndroid Build Coastguard Worker
177*9880d681SAndroid Build Coastguard Worker; SI: {{^}}[[IF_LABEL]]:
178*9880d681SAndroid Build Coastguard Worker; SI: v_mov_b32_e32 [[ONE:v[0-9]+]], 1
179*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword [[ONE]]
180*9880d681SAndroid Build Coastguard Worker; SI: s_endpgm
181*9880d681SAndroid Build Coastguard Workerdefine void @uniform_if_else_ret(i32 addrspace(1)* nocapture %out, i32 %a) {
182*9880d681SAndroid Build Coastguard Workerentry:
183*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 0
184*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %if.then, label %if.else
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %entry
187*9880d681SAndroid Build Coastguard Worker  store i32 1, i32 addrspace(1)* %out
188*9880d681SAndroid Build Coastguard Worker  br label %if.end
189*9880d681SAndroid Build Coastguard Worker
190*9880d681SAndroid Build Coastguard Workerif.else:                                          ; preds = %entry
191*9880d681SAndroid Build Coastguard Worker  store i32 2, i32 addrspace(1)* %out
192*9880d681SAndroid Build Coastguard Worker  br label %if.end
193*9880d681SAndroid Build Coastguard Worker
194*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %if.else, %if.then
195*9880d681SAndroid Build Coastguard Worker  ret void
196*9880d681SAndroid Build Coastguard Worker}
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}uniform_if_else:
199*9880d681SAndroid Build Coastguard Worker; SI: s_cmp_lg_i32 s{{[0-9]+}}, 0
200*9880d681SAndroid Build Coastguard Worker; SI-NEXT: s_cbranch_scc0 [[IF_LABEL:[0-9_A-Za-z]+]]
201*9880d681SAndroid Build Coastguard Worker
202*9880d681SAndroid Build Coastguard Worker; SI: v_mov_b32_e32 [[TWO:v[0-9]+]], 2
203*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword [[TWO]]
204*9880d681SAndroid Build Coastguard Worker; SI: s_branch [[ENDIF_LABEL:[0-9_A-Za-z]+]]
205*9880d681SAndroid Build Coastguard Worker
206*9880d681SAndroid Build Coastguard Worker; SI: [[IF_LABEL]]:
207*9880d681SAndroid Build Coastguard Worker; SI: v_mov_b32_e32 [[ONE:v[0-9]+]], 1
208*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword [[ONE]]
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard Worker; SI: [[ENDIF_LABEL]]:
211*9880d681SAndroid Build Coastguard Worker; SI: v_mov_b32_e32 [[THREE:v[0-9]+]], 3
212*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword [[THREE]]
213*9880d681SAndroid Build Coastguard Worker; SI: s_endpgm
214*9880d681SAndroid Build Coastguard Workerdefine void @uniform_if_else(i32 addrspace(1)* nocapture %out0, i32 addrspace(1)* nocapture %out1, i32 %a) {
215*9880d681SAndroid Build Coastguard Workerentry:
216*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 0
217*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %if.then, label %if.else
218*9880d681SAndroid Build Coastguard Worker
219*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %entry
220*9880d681SAndroid Build Coastguard Worker  store i32 1, i32 addrspace(1)* %out0
221*9880d681SAndroid Build Coastguard Worker  br label %if.end
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Workerif.else:                                          ; preds = %entry
224*9880d681SAndroid Build Coastguard Worker  store i32 2, i32 addrspace(1)* %out0
225*9880d681SAndroid Build Coastguard Worker  br label %if.end
226*9880d681SAndroid Build Coastguard Worker
227*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %if.else, %if.then
228*9880d681SAndroid Build Coastguard Worker  store i32 3, i32 addrspace(1)* %out1
229*9880d681SAndroid Build Coastguard Worker  ret void
230*9880d681SAndroid Build Coastguard Worker}
231*9880d681SAndroid Build Coastguard Worker
232*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}icmp_2_users:
233*9880d681SAndroid Build Coastguard Worker; SI: s_cmp_lt_i32 s{{[0-9]+}}, 1
234*9880d681SAndroid Build Coastguard Worker; SI: s_cbranch_scc1 [[LABEL:[a-zA-Z0-9_]+]]
235*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword
236*9880d681SAndroid Build Coastguard Worker; SI: [[LABEL]]:
237*9880d681SAndroid Build Coastguard Worker; SI: s_endpgm
238*9880d681SAndroid Build Coastguard Workerdefine void @icmp_2_users(i32 addrspace(1)* %out, i32 %cond) {
239*9880d681SAndroid Build Coastguard Workermain_body:
240*9880d681SAndroid Build Coastguard Worker  %0 = icmp sgt i32 %cond, 0
241*9880d681SAndroid Build Coastguard Worker  %1 = sext i1 %0 to i32
242*9880d681SAndroid Build Coastguard Worker  br i1 %0, label %IF, label %ENDIF
243*9880d681SAndroid Build Coastguard Worker
244*9880d681SAndroid Build Coastguard WorkerIF:
245*9880d681SAndroid Build Coastguard Worker  store i32 %1, i32 addrspace(1)* %out
246*9880d681SAndroid Build Coastguard Worker  br label %ENDIF
247*9880d681SAndroid Build Coastguard Worker
248*9880d681SAndroid Build Coastguard WorkerENDIF:                                            ; preds = %IF, %main_body
249*9880d681SAndroid Build Coastguard Worker  ret void
250*9880d681SAndroid Build Coastguard Worker}
251*9880d681SAndroid Build Coastguard Worker
252*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}icmp_users_different_blocks:
253*9880d681SAndroid Build Coastguard Worker; SI: s_load_dword [[COND:s[0-9]+]]
254*9880d681SAndroid Build Coastguard Worker; SI: s_cmp_lt_i32 [[COND]], 1
255*9880d681SAndroid Build Coastguard Worker; SI: s_cbranch_scc1 [[EXIT:[A-Za-z0-9_]+]]
256*9880d681SAndroid Build Coastguard Worker; SI: v_cmp_lt_i32_e64 [[MASK:s\[[0-9]+:[0-9]+\]]], 0, [[COND]]
257*9880d681SAndroid Build Coastguard Worker; SI: s_and_b64 vcc, exec, [[MASK]]
258*9880d681SAndroid Build Coastguard Worker; SI: s_cbranch_vccnz [[EXIT]]
259*9880d681SAndroid Build Coastguard Worker; SI: buffer_store
260*9880d681SAndroid Build Coastguard Worker; SI: {{^}}[[EXIT]]:
261*9880d681SAndroid Build Coastguard Worker; SI: s_endpgm
262*9880d681SAndroid Build Coastguard Workerdefine void @icmp_users_different_blocks(i32 %cond0, i32 %cond1, i32 addrspace(1)* %out) {
263*9880d681SAndroid Build Coastguard Workerbb:
264*9880d681SAndroid Build Coastguard Worker  %tmp = tail call i32 @llvm.amdgcn.workitem.id.x() #0
265*9880d681SAndroid Build Coastguard Worker  %cmp0 = icmp sgt i32 %cond0, 0
266*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i32 %cond1, 0
267*9880d681SAndroid Build Coastguard Worker  br i1 %cmp0, label %bb2, label %bb9
268*9880d681SAndroid Build Coastguard Worker
269*9880d681SAndroid Build Coastguard Workerbb2:                                              ; preds = %bb
270*9880d681SAndroid Build Coastguard Worker  %tmp2 = sext i1 %cmp1 to i32
271*9880d681SAndroid Build Coastguard Worker  %tmp3 = add i32 %tmp2, %tmp
272*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %bb9, label %bb7
273*9880d681SAndroid Build Coastguard Worker
274*9880d681SAndroid Build Coastguard Workerbb7:                                              ; preds = %bb5
275*9880d681SAndroid Build Coastguard Worker  store i32 %tmp3, i32 addrspace(1)* %out
276*9880d681SAndroid Build Coastguard Worker  br label %bb9
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Workerbb9:                                              ; preds = %bb8, %bb4
279*9880d681SAndroid Build Coastguard Worker  ret void
280*9880d681SAndroid Build Coastguard Worker}
281*9880d681SAndroid Build Coastguard Worker
282*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}uniform_loop:
283*9880d681SAndroid Build Coastguard Worker; SI: {{^}}[[LOOP_LABEL:[A-Z0-9_a-z]+]]:
284*9880d681SAndroid Build Coastguard Worker; FIXME: We need to teach SIFixSGPRCopies about uniform branches so we
285*9880d681SAndroid Build Coastguard Worker;        get s_add_i32 here.
286*9880d681SAndroid Build Coastguard Worker; SI: v_add_i32_e32 [[I:v[0-9]+]], vcc, -1, v{{[0-9]+}}
287*9880d681SAndroid Build Coastguard Worker; SI: v_cmp_ne_i32_e32 vcc, 0, [[I]]
288*9880d681SAndroid Build Coastguard Worker; SI: s_and_b64 vcc, exec, vcc
289*9880d681SAndroid Build Coastguard Worker; SI: s_cbranch_vccnz [[LOOP_LABEL]]
290*9880d681SAndroid Build Coastguard Worker; SI: s_endpgm
291*9880d681SAndroid Build Coastguard Workerdefine void @uniform_loop(i32 addrspace(1)* %out, i32 %a) {
292*9880d681SAndroid Build Coastguard Workerentry:
293*9880d681SAndroid Build Coastguard Worker  br label %loop
294*9880d681SAndroid Build Coastguard Worker
295*9880d681SAndroid Build Coastguard Workerloop:
296*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [0, %entry], [%i.i, %loop]
297*9880d681SAndroid Build Coastguard Worker  %i.i = add i32 %i, 1
298*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, %i.i
299*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %done, label %loop
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Workerdone:
302*9880d681SAndroid Build Coastguard Worker  ret void
303*9880d681SAndroid Build Coastguard Worker}
304*9880d681SAndroid Build Coastguard Worker
305*9880d681SAndroid Build Coastguard Worker; Test uniform and divergent.
306*9880d681SAndroid Build Coastguard Worker
307*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}uniform_inside_divergent:
308*9880d681SAndroid Build Coastguard Worker; SI: v_cmp_gt_u32_e32 vcc, 16, v{{[0-9]+}}
309*9880d681SAndroid Build Coastguard Worker; SI: s_and_saveexec_b64 [[MASK:s\[[0-9]+:[0-9]+\]]], vcc
310*9880d681SAndroid Build Coastguard Worker; SI: s_xor_b64  [[MASK1:s\[[0-9]+:[0-9]+\]]], exec, [[MASK]]
311*9880d681SAndroid Build Coastguard Worker; SI: s_cbranch_execz [[ENDIF_LABEL:[0-9_A-Za-z]+]]
312*9880d681SAndroid Build Coastguard Worker; SI: s_cmp_lg_i32 {{s[0-9]+}}, 0
313*9880d681SAndroid Build Coastguard Worker; SI: s_cbranch_scc1 [[ENDIF_LABEL]]
314*9880d681SAndroid Build Coastguard Worker; SI: v_mov_b32_e32 [[ONE:v[0-9]+]], 1
315*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword [[ONE]]
316*9880d681SAndroid Build Coastguard Workerdefine void @uniform_inside_divergent(i32 addrspace(1)* %out, i32 %cond) {
317*9880d681SAndroid Build Coastguard Workerentry:
318*9880d681SAndroid Build Coastguard Worker  %tid = call i32 @llvm.amdgcn.workitem.id.x() #0
319*9880d681SAndroid Build Coastguard Worker  %d_cmp = icmp ult i32 %tid, 16
320*9880d681SAndroid Build Coastguard Worker  br i1 %d_cmp, label %if, label %endif
321*9880d681SAndroid Build Coastguard Worker
322*9880d681SAndroid Build Coastguard Workerif:
323*9880d681SAndroid Build Coastguard Worker  store i32 0, i32 addrspace(1)* %out
324*9880d681SAndroid Build Coastguard Worker  %u_cmp = icmp eq i32 %cond, 0
325*9880d681SAndroid Build Coastguard Worker  br i1 %u_cmp, label %if_uniform, label %endif
326*9880d681SAndroid Build Coastguard Worker
327*9880d681SAndroid Build Coastguard Workerif_uniform:
328*9880d681SAndroid Build Coastguard Worker  store i32 1, i32 addrspace(1)* %out
329*9880d681SAndroid Build Coastguard Worker  br label %endif
330*9880d681SAndroid Build Coastguard Worker
331*9880d681SAndroid Build Coastguard Workerendif:
332*9880d681SAndroid Build Coastguard Worker  ret void
333*9880d681SAndroid Build Coastguard Worker}
334*9880d681SAndroid Build Coastguard Worker
335*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}divergent_inside_uniform:
336*9880d681SAndroid Build Coastguard Worker; SI: s_cmp_lg_i32 s{{[0-9]+}}, 0
337*9880d681SAndroid Build Coastguard Worker; SI: s_cbranch_scc1 [[ENDIF_LABEL:[0-9_A-Za-z]+]]
338*9880d681SAndroid Build Coastguard Worker; SI: v_cmp_gt_u32_e32 vcc, 16, v{{[0-9]+}}
339*9880d681SAndroid Build Coastguard Worker; SI: s_and_saveexec_b64 [[MASK:s\[[0-9]+:[0-9]+\]]], vcc
340*9880d681SAndroid Build Coastguard Worker; SI: s_xor_b64  [[MASK1:s\[[0-9]+:[0-9]+\]]], exec, [[MASK]]
341*9880d681SAndroid Build Coastguard Worker; SI: v_mov_b32_e32 [[ONE:v[0-9]+]], 1
342*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword [[ONE]]
343*9880d681SAndroid Build Coastguard Worker; SI: [[ENDIF_LABEL]]:
344*9880d681SAndroid Build Coastguard Worker; SI: s_endpgm
345*9880d681SAndroid Build Coastguard Workerdefine void @divergent_inside_uniform(i32 addrspace(1)* %out, i32 %cond) {
346*9880d681SAndroid Build Coastguard Workerentry:
347*9880d681SAndroid Build Coastguard Worker  %u_cmp = icmp eq i32 %cond, 0
348*9880d681SAndroid Build Coastguard Worker  br i1 %u_cmp, label %if, label %endif
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Workerif:
351*9880d681SAndroid Build Coastguard Worker  store i32 0, i32 addrspace(1)* %out
352*9880d681SAndroid Build Coastguard Worker  %tid = call i32 @llvm.amdgcn.workitem.id.x() #0
353*9880d681SAndroid Build Coastguard Worker  %d_cmp = icmp ult i32 %tid, 16
354*9880d681SAndroid Build Coastguard Worker  br i1 %d_cmp, label %if_uniform, label %endif
355*9880d681SAndroid Build Coastguard Worker
356*9880d681SAndroid Build Coastguard Workerif_uniform:
357*9880d681SAndroid Build Coastguard Worker  store i32 1, i32 addrspace(1)* %out
358*9880d681SAndroid Build Coastguard Worker  br label %endif
359*9880d681SAndroid Build Coastguard Worker
360*9880d681SAndroid Build Coastguard Workerendif:
361*9880d681SAndroid Build Coastguard Worker  ret void
362*9880d681SAndroid Build Coastguard Worker}
363*9880d681SAndroid Build Coastguard Worker
364*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}divergent_if_uniform_if:
365*9880d681SAndroid Build Coastguard Worker; SI: v_cmp_eq_i32_e32 vcc, 0, v0
366*9880d681SAndroid Build Coastguard Worker; SI: s_and_saveexec_b64 [[MASK:s\[[0-9]+:[0-9]+\]]], vcc
367*9880d681SAndroid Build Coastguard Worker; SI: s_xor_b64 [[MASK:s\[[0-9]+:[0-9]+\]]], exec, [[MASK]]
368*9880d681SAndroid Build Coastguard Worker; SI: v_mov_b32_e32 [[ONE:v[0-9]+]], 1
369*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword [[ONE]]
370*9880d681SAndroid Build Coastguard Worker; SI: s_or_b64 exec, exec, [[MASK]]
371*9880d681SAndroid Build Coastguard Worker; SI: s_cmp_lg_i32 s{{[0-9]+}}, 0
372*9880d681SAndroid Build Coastguard Worker; SI: s_cbranch_scc1 [[EXIT:[A-Z0-9_]+]]
373*9880d681SAndroid Build Coastguard Worker; SI: v_mov_b32_e32 [[TWO:v[0-9]+]], 2
374*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword [[TWO]]
375*9880d681SAndroid Build Coastguard Worker; SI: [[EXIT]]:
376*9880d681SAndroid Build Coastguard Worker; SI: s_endpgm
377*9880d681SAndroid Build Coastguard Workerdefine void @divergent_if_uniform_if(i32 addrspace(1)* %out, i32 %cond) {
378*9880d681SAndroid Build Coastguard Workerentry:
379*9880d681SAndroid Build Coastguard Worker  %tid = call i32 @llvm.amdgcn.workitem.id.x() #0
380*9880d681SAndroid Build Coastguard Worker  %d_cmp = icmp eq i32 %tid, 0
381*9880d681SAndroid Build Coastguard Worker  br i1 %d_cmp, label %if, label %endif
382*9880d681SAndroid Build Coastguard Worker
383*9880d681SAndroid Build Coastguard Workerif:
384*9880d681SAndroid Build Coastguard Worker  store i32 1, i32 addrspace(1)* %out
385*9880d681SAndroid Build Coastguard Worker  br label %endif
386*9880d681SAndroid Build Coastguard Worker
387*9880d681SAndroid Build Coastguard Workerendif:
388*9880d681SAndroid Build Coastguard Worker  %u_cmp = icmp eq i32 %cond, 0
389*9880d681SAndroid Build Coastguard Worker  br i1 %u_cmp, label %if_uniform, label %exit
390*9880d681SAndroid Build Coastguard Worker
391*9880d681SAndroid Build Coastguard Workerif_uniform:
392*9880d681SAndroid Build Coastguard Worker  store i32 2, i32 addrspace(1)* %out
393*9880d681SAndroid Build Coastguard Worker  br label %exit
394*9880d681SAndroid Build Coastguard Worker
395*9880d681SAndroid Build Coastguard Workerexit:
396*9880d681SAndroid Build Coastguard Worker  ret void
397*9880d681SAndroid Build Coastguard Worker}
398*9880d681SAndroid Build Coastguard Worker
399*9880d681SAndroid Build Coastguard Worker; The condition of the branches in the two blocks are
400*9880d681SAndroid Build Coastguard Worker; uniform. MachineCSE replaces the 2nd condition with the inverse of
401*9880d681SAndroid Build Coastguard Worker; the first, leaving an scc use in a different block than it was
402*9880d681SAndroid Build Coastguard Worker; defed.
403*9880d681SAndroid Build Coastguard Worker
404*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}cse_uniform_condition_different_blocks:
405*9880d681SAndroid Build Coastguard Worker; SI: s_load_dword [[COND:s[0-9]+]]
406*9880d681SAndroid Build Coastguard Worker; SI: s_cmp_lt_i32 [[COND]], 1
407*9880d681SAndroid Build Coastguard Worker; SI: s_cbranch_scc1 BB[[FNNUM:[0-9]+]]_3
408*9880d681SAndroid Build Coastguard Worker
409*9880d681SAndroid Build Coastguard Worker; SI: BB#1:
410*9880d681SAndroid Build Coastguard Worker; SI-NOT: cmp
411*9880d681SAndroid Build Coastguard Worker; SI: buffer_load_dword
412*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword
413*9880d681SAndroid Build Coastguard Worker; SI: s_cbranch_scc1 BB[[FNNUM]]_3
414*9880d681SAndroid Build Coastguard Worker
415*9880d681SAndroid Build Coastguard Worker; SI: BB[[FNNUM]]_3:
416*9880d681SAndroid Build Coastguard Worker; SI: s_endpgm
417*9880d681SAndroid Build Coastguard Workerdefine void @cse_uniform_condition_different_blocks(i32 %cond, i32 addrspace(1)* %out) {
418*9880d681SAndroid Build Coastguard Workerbb:
419*9880d681SAndroid Build Coastguard Worker  %tmp = tail call i32 @llvm.amdgcn.workitem.id.x() #0
420*9880d681SAndroid Build Coastguard Worker  %tmp1 = icmp sgt i32 %cond, 0
421*9880d681SAndroid Build Coastguard Worker  br i1 %tmp1, label %bb2, label %bb9
422*9880d681SAndroid Build Coastguard Worker
423*9880d681SAndroid Build Coastguard Workerbb2:                                              ; preds = %bb
424*9880d681SAndroid Build Coastguard Worker  %tmp3 = load volatile i32, i32 addrspace(1)* undef
425*9880d681SAndroid Build Coastguard Worker  store volatile i32 0, i32 addrspace(1)* undef
426*9880d681SAndroid Build Coastguard Worker  %tmp9 = icmp sle i32 %cond, 0
427*9880d681SAndroid Build Coastguard Worker  br i1 %tmp9, label %bb9, label %bb7
428*9880d681SAndroid Build Coastguard Worker
429*9880d681SAndroid Build Coastguard Workerbb7:                                              ; preds = %bb5
430*9880d681SAndroid Build Coastguard Worker  store i32 %tmp3, i32 addrspace(1)* %out
431*9880d681SAndroid Build Coastguard Worker  br label %bb9
432*9880d681SAndroid Build Coastguard Worker
433*9880d681SAndroid Build Coastguard Workerbb9:                                              ; preds = %bb8, %bb4
434*9880d681SAndroid Build Coastguard Worker  ret void
435*9880d681SAndroid Build Coastguard Worker}
436*9880d681SAndroid Build Coastguard Worker
437*9880d681SAndroid Build Coastguard Workerdeclare i32 @llvm.amdgcn.workitem.id.x() #0
438*9880d681SAndroid Build Coastguard Worker
439*9880d681SAndroid Build Coastguard Workerattributes #0 = { readnone }
440