xref: /llvm-project/llvm/test/Analysis/UniformityAnalysis/AMDGPU/always_uniform.ll (revision 3e3ea54aada44212b4e273f2fc879a419dea053f)
1; RUN: opt -mtriple amdgcn-unknown-amdhsa -passes='print<uniformity>' -disable-output %s 2>&1 | FileCheck %s
2
3; CHECK-LABEL: for function 'readfirstlane':
4define amdgpu_kernel void @readfirstlane() {
5  %id.x = call i32 @llvm.amdgcn.workitem.id.x()
6; CHECK: DIVERGENT:  %id.x = call i32 @llvm.amdgcn.workitem.id.x()
7  %first.lane = call i32 @llvm.amdgcn.readfirstlane(i32 %id.x)
8; CHECK-NOT: DIVERGENT:  %first.lane = call i32 @llvm.amdgcn.readfirstlane(i32 %id.x)
9  ret void
10}
11
12; CHECK-LABEL: for function 'icmp':
13define amdgpu_kernel void @icmp(i32 inreg %x) {
14; CHECK-NOT: DIVERGENT:  %icmp = call i64 @llvm.amdgcn.icmp.i32
15  %icmp = call i64 @llvm.amdgcn.icmp.i32(i32 %x, i32 0, i32 33)
16  ret void
17}
18
19; CHECK-LABEL: for function 'fcmp':
20define amdgpu_kernel void @fcmp(float inreg %x, float inreg %y) {
21; CHECK-NOT: DIVERGENT:  %fcmp = call i64 @llvm.amdgcn.fcmp.i32
22  %fcmp = call i64 @llvm.amdgcn.fcmp.i32(float %x, float %y, i32 33)
23  ret void
24}
25
26; CHECK-LABEL: for function 'ballot':
27define amdgpu_kernel void @ballot(i1 inreg %x) {
28; CHECK-NOT: DIVERGENT:  %ballot = call i64 @llvm.amdgcn.ballot.i32
29  %ballot = call i64 @llvm.amdgcn.ballot.i32(i1 %x)
30  ret void
31}
32
33; SGPR asm outputs are uniform regardless of the input operands.
34; CHECK-LABEL: for function 'asm_sgpr':
35; CHECK: DIVERGENT: i32 %divergent
36; CHECK-NOT: DIVERGENT
37define i32 @asm_sgpr(i32 %divergent) {
38  %sgpr = call i32 asm "; def $0, $1","=s,v"(i32 %divergent)
39  ret i32 %sgpr
40}
41
42; SGPR asm outputs are uniform regardless of the input operands.
43; Argument not divergent if marked inreg.
44; CHECK-LABEL: for function 'asm_sgpr_inreg_arg':
45; CHECK-NOT: DIVERGENT
46define i32 @asm_sgpr_inreg_arg(i32 inreg %divergent) {
47  %sgpr = call i32 asm "; def $0, $1","=s,v"(i32 %divergent)
48  ret i32 %sgpr
49}
50
51; CHECK-LABEL: for function 'asm_mixed_sgpr_vgpr':
52; CHECK: DIVERGENT: %asm = call { i32, i32 } asm "; def $0, $1, $2", "=s,=v,v"(i32 %divergent)
53; CHECK-NEXT: {{^[ \t]+}}%sgpr = extractvalue { i32, i32 } %asm, 0
54; CHECK-NEXT: DIVERGENT:       %vgpr = extractvalue { i32, i32 } %asm, 1
55define void @asm_mixed_sgpr_vgpr(i32 %divergent) {
56  %asm = call { i32, i32 } asm "; def $0, $1, $2","=s,=v,v"(i32 %divergent)
57  %sgpr = extractvalue { i32, i32 } %asm, 0
58  %vgpr = extractvalue { i32, i32 } %asm, 1
59  store i32 %sgpr, ptr addrspace(1) undef
60  store i32 %vgpr, ptr addrspace(1) undef
61  ret void
62}
63
64; CHECK-LABEL: for function 'single_lane_func_arguments':
65; CHECK-NOT: DIVERGENT
66define void @single_lane_func_arguments(i32 %i32, i1 %i1) #2 {
67 ret void
68}
69
70; CHECK-LABEL: for function 'divergent_args':
71; CHECK: DIVERGENT ARGUMENTS
72define void @divergent_args(i32 %i32, i1 %i1) {
73 ret void
74}
75
76; CHECK-LABEL: for function 'no_divergent_args_if_inreg':
77; CHECK-NOT: DIVERGENT
78define void @no_divergent_args_if_inreg(i32 inreg %i32, i1 inreg %i1) {
79 ret void
80}
81
82; CHECK-LABEL: for function 'workgroup_id_x':
83; CHECK: ALL VALUES UNIFORM
84define void @workgroup_id_x(ptr addrspace(1) inreg %out) {
85  %result = call i32 @llvm.amdgcn.workgroup.id.x()
86  store i32 %result, ptr addrspace(1) %out, align 4
87  ret void
88}
89
90; CHECK-LABEL: for function 'workgroup_id_y':
91; CHECK: ALL VALUES UNIFORM
92define void @workgroup_id_y(ptr addrspace(1) inreg %out) {
93  %result = call i32 @llvm.amdgcn.workgroup.id.y()
94  store i32 %result, ptr addrspace(1) %out, align 4
95  ret void
96}
97
98; CHECK-LABEL: for function 'workgroup_id_z':
99; CHECK: ALL VALUES UNIFORM
100define void @workgroup_id_z(ptr addrspace(1) inreg %out) {
101  %result = call i32 @llvm.amdgcn.workgroup.id.z()
102  store i32 %result, ptr addrspace(1) %out, align 4
103  ret void
104}
105
106; CHECK-LABEL: for function 's_getpc':
107; CHECK: ALL VALUES UNIFORM
108define void @s_getpc(ptr addrspace(1) inreg %out) {
109  %result = call i64 @llvm.amdgcn.s.getpc()
110  store i64 %result, ptr addrspace(1) %out, align 8
111  ret void
112}
113
114; CHECK-LABEL: for function 's_getreg':
115; CHECK: ALL VALUES UNIFORM
116define void @s_getreg(ptr addrspace(1) inreg %out) {
117  %result = call i32 @llvm.amdgcn.s.getreg(i32 123)
118  store i32 %result, ptr addrspace(1) %out, align 4
119  ret void
120}
121
122; CHECK-LABEL: for function 's_memtime':
123; CHECK: ALL VALUES UNIFORM
124define void @s_memtime(ptr addrspace(1) inreg %out) {
125  %result = call i64 @llvm.amdgcn.s.memtime()
126  store i64 %result, ptr addrspace(1) %out, align 8
127  ret void
128}
129
130; CHECK-LABEL: for function 's_memrealtime':
131; CHECK: ALL VALUES UNIFORM
132define void @s_memrealtime(ptr addrspace(1) inreg %out) {
133  %result = call i64 @llvm.amdgcn.s.memrealtime()
134  store i64 %result, ptr addrspace(1) %out, align 8
135  ret void
136}
137
138
139declare i32 @llvm.amdgcn.workitem.id.x() #0
140declare i32 @llvm.amdgcn.readfirstlane(i32) #0
141declare i64 @llvm.amdgcn.icmp.i32(i32, i32, i32) #1
142declare i64 @llvm.amdgcn.fcmp.i32(float, float, i32) #1
143declare i64 @llvm.amdgcn.ballot.i32(i1) #1
144declare i32 @llvm.amdgcn.workgroup.id.x() #0
145declare i32 @llvm.amdgcn.workgroup.id.y() #0
146declare i32 @llvm.amdgcn.workgroup.id.z() #0
147
148attributes #0 = { nounwind readnone }
149attributes #1 = { nounwind readnone convergent }
150attributes #2 = { "amdgpu-flat-work-group-size"="1,1" }
151