xref: /llvm-project/llvm/test/Analysis/UniformityAnalysis/AMDGPU/control-flow-intrinsics.ll (revision ae77aceba5ad6ee575d3d79eb0259624322b19f4)
1; RUN: opt -mtriple amdgcn-mesa-mesa3d -passes='print<uniformity>' -disable-output %s 2>&1 | FileCheck %s
2
3; Tests control flow intrinsics that should be treated as uniform
4
5; CHECK: for function 'test_if_break':
6; CHECK: DIVERGENT: %cond = icmp eq i32 %arg0, 0
7; CHECK-NOT: DIVERGENT
8; CHECK: ret void
9define amdgpu_ps void @test_if_break(i32 %arg0, i64 inreg %saved) {
10entry:
11  %cond = icmp eq i32 %arg0, 0
12  %break = call i64 @llvm.amdgcn.if.break.i64.i64(i1 %cond, i64 %saved)
13  store volatile i64 %break, ptr addrspace(1) undef
14  ret void
15}
16
17; CHECK: for function 'test_if':
18; CHECK: DIVERGENT: %cond = icmp eq i32 %arg0, 0
19; CHECK-NEXT: DIVERGENT: %if = call { i1, i64 } @llvm.amdgcn.if.i64(i1 %cond)
20; CHECK-NEXT: DIVERGENT: %if.bool = extractvalue { i1, i64 } %if, 0
21; CHECK-NOT: DIVERGENT
22; CHECK: DIVERGENT: %if.bool.ext = zext i1 %if.bool to i32
23define void @test_if(i32 %arg0) {
24entry:
25  %cond = icmp eq i32 %arg0, 0
26  %if = call { i1, i64 } @llvm.amdgcn.if.i64(i1 %cond)
27  %if.bool = extractvalue { i1, i64 } %if, 0
28  %if.mask = extractvalue { i1, i64 } %if, 1
29  %if.bool.ext = zext i1 %if.bool to i32
30  store volatile i32 %if.bool.ext, ptr addrspace(1) undef
31  store volatile i64 %if.mask, ptr addrspace(1) undef
32  ret void
33}
34
35; The result should still be treated as divergent, even with a uniform source.
36; CHECK: for function 'test_if_uniform':
37; CHECK-NOT: DIVERGENT
38; CHECK: DIVERGENT: %if = call { i1, i64 } @llvm.amdgcn.if.i64(i1 %cond)
39; CHECK-NEXT: DIVERGENT: %if.bool = extractvalue { i1, i64 } %if, 0
40; CHECK-NOT: DIVERGENT
41; CHECK: DIVERGENT: %if.bool.ext = zext i1 %if.bool to i32
42define amdgpu_ps void @test_if_uniform(i32 inreg %arg0) {
43entry:
44  %cond = icmp eq i32 %arg0, 0
45  %if = call { i1, i64 } @llvm.amdgcn.if.i64(i1 %cond)
46  %if.bool = extractvalue { i1, i64 } %if, 0
47  %if.mask = extractvalue { i1, i64 } %if, 1
48  %if.bool.ext = zext i1 %if.bool to i32
49  store volatile i32 %if.bool.ext, ptr addrspace(1) undef
50  store volatile i64 %if.mask, ptr addrspace(1) undef
51  ret void
52}
53
54; CHECK: for function 'test_loop_uniform':
55; CHECK: DIVERGENT: %loop = call i1 @llvm.amdgcn.loop.i64(i64 %mask)
56define amdgpu_ps void @test_loop_uniform(i64 inreg %mask) {
57entry:
58  %loop = call i1 @llvm.amdgcn.loop.i64(i64 %mask)
59  %loop.ext = zext i1 %loop to i32
60  store volatile i32 %loop.ext, ptr addrspace(1) undef
61  ret void
62}
63
64; CHECK: for function 'test_else':
65; CHECK: DIVERGENT: %else = call { i1, i64 } @llvm.amdgcn.else.i64.i64(i64 %mask)
66; CHECK: DIVERGENT:       %else.bool = extractvalue { i1, i64 } %else, 0
67; CHECK: {{^[ \t]+}}%else.mask = extractvalue { i1, i64 } %else, 1
68define amdgpu_ps void @test_else(i64 inreg %mask) {
69entry:
70  %else = call { i1, i64 } @llvm.amdgcn.else.i64.i64(i64 %mask)
71  %else.bool = extractvalue { i1, i64 } %else, 0
72  %else.mask = extractvalue { i1, i64 } %else, 1
73  %else.bool.ext = zext i1 %else.bool to i32
74  store volatile i32 %else.bool.ext, ptr addrspace(1) undef
75  store volatile i64 %else.mask, ptr addrspace(1) undef
76  ret void
77}
78
79; This case is probably always broken
80; CHECK: for function 'test_else_divergent_mask':
81; CHECK: DIVERGENT: %if = call { i1, i64 } @llvm.amdgcn.else.i64.i64(i64 %mask)
82; CHECK-NEXT: DIVERGENT: %if.bool = extractvalue { i1, i64 } %if, 0
83; CHECK-NOT: DIVERGENT
84; CHECK: DIVERGENT: %if.bool.ext = zext i1 %if.bool to i32
85define void @test_else_divergent_mask(i64 %mask) {
86entry:
87  %if = call { i1, i64 } @llvm.amdgcn.else.i64.i64(i64 %mask)
88  %if.bool = extractvalue { i1, i64 } %if, 0
89  %if.mask = extractvalue { i1, i64 } %if, 1
90  %if.bool.ext = zext i1 %if.bool to i32
91  store volatile i32 %if.bool.ext, ptr addrspace(1) undef
92  store volatile i64 %if.mask, ptr addrspace(1) undef
93  ret void
94}
95
96declare { i1, i64 } @llvm.amdgcn.if.i64(i1) #0
97declare { i1, i64 } @llvm.amdgcn.else.i64.i64(i64) #0
98declare i64 @llvm.amdgcn.if.break.i64.i64(i1, i64) #1
99declare i1 @llvm.amdgcn.loop.i64(i64) #1
100
101attributes #0 = { convergent nounwind }
102attributes #1 = { convergent nounwind readnone }
103