xref: /aosp_15_r20/external/llvm/test/CodeGen/AMDGPU/sgpr-control-flow.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=amdgcn -verify-machineinstrs< %s | FileCheck -check-prefix=SI %s
2*9880d681SAndroid Build Coastguard Worker;
3*9880d681SAndroid Build Coastguard Worker;
4*9880d681SAndroid Build Coastguard Worker; Most SALU instructions ignore control flow, so we need to make sure
5*9880d681SAndroid Build Coastguard Worker; they don't overwrite values from other blocks.
6*9880d681SAndroid Build Coastguard Worker
7*9880d681SAndroid Build Coastguard Worker; If the branch decision is made based on a value in an SGPR then all
8*9880d681SAndroid Build Coastguard Worker; threads will execute the same code paths, so we don't need to worry
9*9880d681SAndroid Build Coastguard Worker; about instructions in different blocks overwriting each other.
10*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}sgpr_if_else_salu_br:
11*9880d681SAndroid Build Coastguard Worker; SI: s_add
12*9880d681SAndroid Build Coastguard Worker; SI: s_add
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Workerdefine void @sgpr_if_else_salu_br(i32 addrspace(1)* %out, i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
15*9880d681SAndroid Build Coastguard Workerentry:
16*9880d681SAndroid Build Coastguard Worker  %0 = icmp eq i32 %a, 0
17*9880d681SAndroid Build Coastguard Worker  br i1 %0, label %if, label %else
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Workerif:
20*9880d681SAndroid Build Coastguard Worker  %1 = add i32 %b, %c
21*9880d681SAndroid Build Coastguard Worker  br label %endif
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Workerelse:
24*9880d681SAndroid Build Coastguard Worker  %2 = add i32 %d, %e
25*9880d681SAndroid Build Coastguard Worker  br label %endif
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Workerendif:
28*9880d681SAndroid Build Coastguard Worker  %3 = phi i32 [%1, %if], [%2, %else]
29*9880d681SAndroid Build Coastguard Worker  %4 = add i32 %3, %a
30*9880d681SAndroid Build Coastguard Worker  store i32 %4, i32 addrspace(1)* %out
31*9880d681SAndroid Build Coastguard Worker  ret void
32*9880d681SAndroid Build Coastguard Worker}
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker; The two S_ADD instructions should write to different registers, since
35*9880d681SAndroid Build Coastguard Worker; different threads will take different control flow paths.
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}sgpr_if_else_valu_br:
38*9880d681SAndroid Build Coastguard Worker; SI: s_add_i32 [[SGPR:s[0-9]+]]
39*9880d681SAndroid Build Coastguard Worker; SI-NOT: s_add_i32 [[SGPR]]
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Workerdefine void @sgpr_if_else_valu_br(i32 addrspace(1)* %out, float %a, i32 %b, i32 %c, i32 %d, i32 %e) {
42*9880d681SAndroid Build Coastguard Workerentry:
43*9880d681SAndroid Build Coastguard Worker  %tid = call i32 @llvm.amdgcn.workitem.id.x() #0
44*9880d681SAndroid Build Coastguard Worker  %tid_f = uitofp i32 %tid to float
45*9880d681SAndroid Build Coastguard Worker  %tmp1 = fcmp ueq float %tid_f, 0.0
46*9880d681SAndroid Build Coastguard Worker  br i1 %tmp1, label %if, label %else
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Workerif:
49*9880d681SAndroid Build Coastguard Worker  %tmp2 = add i32 %b, %c
50*9880d681SAndroid Build Coastguard Worker  br label %endif
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Workerelse:
53*9880d681SAndroid Build Coastguard Worker  %tmp3 = add i32 %d, %e
54*9880d681SAndroid Build Coastguard Worker  br label %endif
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Workerendif:
57*9880d681SAndroid Build Coastguard Worker  %tmp4 = phi i32 [%tmp2, %if], [%tmp3, %else]
58*9880d681SAndroid Build Coastguard Worker  store i32 %tmp4, i32 addrspace(1)* %out
59*9880d681SAndroid Build Coastguard Worker  ret void
60*9880d681SAndroid Build Coastguard Worker}
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker; FIXME: Should write to different SGPR pairs instead of copying to
63*9880d681SAndroid Build Coastguard Worker; VALU for i1 phi.
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}sgpr_if_else_valu_cmp_phi_br:
66*9880d681SAndroid Build Coastguard Worker; SI: buffer_load_dword [[AVAL:v[0-9]+]]
67*9880d681SAndroid Build Coastguard Worker; SI: v_cmp_gt_i32_e32 [[CMP_IF:vcc]], 0, [[AVAL]]
68*9880d681SAndroid Build Coastguard Worker; SI: v_cndmask_b32_e64 [[V_CMP:v[0-9]+]], 0, -1, [[CMP_IF]]
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker; SI: BB2_2:
71*9880d681SAndroid Build Coastguard Worker; SI: buffer_load_dword [[AVAL:v[0-9]+]]
72*9880d681SAndroid Build Coastguard Worker; SI: v_cmp_eq_i32_e32 [[CMP_ELSE:vcc]], 0, [[AVAL]]
73*9880d681SAndroid Build Coastguard Worker; SI: v_cndmask_b32_e64 [[V_CMP]], 0, -1, [[CMP_ELSE]]
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker; SI: v_cmp_ne_i32_e32 [[CMP_CMP:vcc]], 0, [[V_CMP]]
76*9880d681SAndroid Build Coastguard Worker; SI: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, -1, [[CMP_CMP]]
77*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword [[RESULT]]
78*9880d681SAndroid Build Coastguard Workerdefine void @sgpr_if_else_valu_cmp_phi_br(i32 addrspace(1)* %out, i32 addrspace(1)* %a, i32 addrspace(1)* %b) {
79*9880d681SAndroid Build Coastguard Workerentry:
80*9880d681SAndroid Build Coastguard Worker  %tid = call i32 @llvm.amdgcn.workitem.id.x() #0
81*9880d681SAndroid Build Coastguard Worker  %tmp1 = icmp eq i32 %tid, 0
82*9880d681SAndroid Build Coastguard Worker  br i1 %tmp1, label %if, label %else
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Workerif:
85*9880d681SAndroid Build Coastguard Worker  %gep.if = getelementptr i32, i32 addrspace(1)* %a, i32 %tid
86*9880d681SAndroid Build Coastguard Worker  %a.val = load i32, i32 addrspace(1)* %gep.if
87*9880d681SAndroid Build Coastguard Worker  %cmp.if = icmp eq i32 %a.val, 0
88*9880d681SAndroid Build Coastguard Worker  br label %endif
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Workerelse:
91*9880d681SAndroid Build Coastguard Worker  %gep.else = getelementptr i32, i32 addrspace(1)* %b, i32 %tid
92*9880d681SAndroid Build Coastguard Worker  %b.val = load i32, i32 addrspace(1)* %gep.else
93*9880d681SAndroid Build Coastguard Worker  %cmp.else = icmp slt i32 %b.val, 0
94*9880d681SAndroid Build Coastguard Worker  br label %endif
95*9880d681SAndroid Build Coastguard Worker
96*9880d681SAndroid Build Coastguard Workerendif:
97*9880d681SAndroid Build Coastguard Worker  %tmp4 = phi i1 [%cmp.if, %if], [%cmp.else, %else]
98*9880d681SAndroid Build Coastguard Worker  %ext = sext i1 %tmp4 to i32
99*9880d681SAndroid Build Coastguard Worker  store i32 %ext, i32 addrspace(1)* %out
100*9880d681SAndroid Build Coastguard Worker  ret void
101*9880d681SAndroid Build Coastguard Worker}
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Workerdeclare i32 @llvm.amdgcn.workitem.id.x() #0
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Workerattributes #0 = { readnone }
106