xref: /llvm-project/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-cs-chain.ll (revision 9d4094ae80f635eec5a0cf0473bf9951b423e3cc)
1; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
2
3declare void @llvm.amdgcn.cs.chain(ptr, i32, <4 x i32>, { ptr, <3 x i32> }, i32, ...) noreturn
4declare i32 @llvm.amdgcn.set.inactive.chain.arg(i32, i32) convergent willreturn nofree nocallback readnone
5
6define amdgpu_cs_chain void @bad_flags(ptr %fn, i32 %exec, <4 x i32> inreg %sgpr, { ptr, <3 x i32> } %vgpr, i32 %flags) {
7  ; CHECK: immarg operand has non-immediate parameter
8  ; CHECK-NEXT: i32 %flags
9  ; CHECK-NEXT: @llvm.amdgcn.cs.chain
10  call void(ptr, i32, <4 x i32>, { ptr, <3 x i32> }, i32, ...) @llvm.amdgcn.cs.chain(ptr %fn, i32 %exec, <4 x i32> %sgpr, { ptr, <3 x i32> } %vgpr, i32 %flags)
11  unreachable
12}
13
14define amdgpu_cs_chain void @bad_vgpr_args(ptr %fn, i32 %exec, <4 x i32> inreg %sgpr, { ptr, <3 x i32> } inreg %vgpr) {
15  ; CHECK: VGPR arguments must not have the `inreg` attribute
16  ; CHECK-NEXT: @llvm.amdgcn.cs.chain
17  call void(ptr, i32, <4 x i32>, { ptr, <3 x i32> }, i32, ...) @llvm.amdgcn.cs.chain(ptr %fn, i32 %exec, <4 x i32> inreg %sgpr, { ptr, <3 x i32> } inreg %vgpr, i32 0)
18  unreachable
19}
20
21define amdgpu_cs_chain void @bad_sgpr_args(ptr %fn, i32 %exec, <4 x i32> %sgpr, { ptr, <3 x i32> } %vgpr) {
22  ; CHECK: SGPR arguments must have the `inreg` attribute
23  ; CHECK-NEXT: @llvm.amdgcn.cs.chain
24  call void(ptr, i32, <4 x i32>, { ptr, <3 x i32> }, i32, ...) @llvm.amdgcn.cs.chain(ptr %fn, i32 %exec, <4 x i32> %sgpr, { ptr, <3 x i32> } %vgpr, i32 0)
25  unreachable
26}
27
28define amdgpu_cs_chain void @bad_exec(ptr %fn, i32 %exec, <4 x i32> inreg %sgpr, { ptr, <3 x i32> } %vgpr, i32 %flags) {
29  ; CHECK: Intrinsic called with incompatible signature
30  ; CHECK-NEXT: @llvm.amdgcn.cs.chain
31  call void(ptr, <4 x i32>, <4 x i32>, { ptr, <3 x i32> }, i32, ...) @llvm.amdgcn.cs.chain(ptr %fn, <4 x i32> %sgpr, <4 x i32> %sgpr, { ptr, <3 x i32> } %vgpr, i32 %flags)
32  unreachable
33}
34
35define void @bad_caller_default_cc(ptr %fn, i32 %exec, <4 x i32> inreg %sgpr, { ptr, <3 x i32> } %vgpr) {
36  ; CHECK: Intrinsic can only be used from functions with the amdgpu_cs_chain or amdgpu_cs_chain_preserve calling conventions
37  ; CHECK-NEXT: @llvm.amdgcn.set.inactive.chain.arg
38  %unused = call i32 @llvm.amdgcn.set.inactive.chain.arg(i32 0, i32 1)
39
40  ; CHECK: Intrinsic can only be used from functions with the amdgpu_cs, amdgpu_cs_chain or amdgpu_cs_chain_preserve calling conventions
41  ; CHECK-NEXT: @llvm.amdgcn.cs.chain
42  call void(ptr, i32, <4 x i32>, { ptr, <3 x i32> }, i32, ...) @llvm.amdgcn.cs.chain(ptr %fn, i32 %exec, <4 x i32> %sgpr, { ptr, <3 x i32> } %vgpr, i32 0)
43  unreachable
44}
45
46define amdgpu_kernel void @bad_caller_amdgpu_kernel(ptr %fn, i32 %exec, <4 x i32> inreg %sgpr, { ptr, <3 x i32> } %vgpr) {
47  ; CHECK: Intrinsic can only be used from functions with the amdgpu_cs_chain or amdgpu_cs_chain_preserve calling conventions
48  ; CHECK-NEXT: @llvm.amdgcn.set.inactive.chain.arg
49  %unused = call i32 @llvm.amdgcn.set.inactive.chain.arg(i32 0, i32 1)
50
51  ; CHECK: Intrinsic can only be used from functions with the amdgpu_cs, amdgpu_cs_chain or amdgpu_cs_chain_preserve calling conventions
52  ; CHECK-NEXT: @llvm.amdgcn.cs.chain
53  call void(ptr, i32, <4 x i32>, { ptr, <3 x i32> }, i32, ...) @llvm.amdgcn.cs.chain(ptr %fn, i32 %exec, <4 x i32> %sgpr, { ptr, <3 x i32> } %vgpr, i32 0)
54  unreachable
55}
56
57define amdgpu_gfx void @bad_caller_amdgpu_gfx(ptr %fn, i32 %exec, <4 x i32> inreg %sgpr, { ptr, <3 x i32> } %vgpr) {
58  ; CHECK: Intrinsic can only be used from functions with the amdgpu_cs_chain or amdgpu_cs_chain_preserve calling conventions
59  ; CHECK-NEXT: @llvm.amdgcn.set.inactive.chain.arg
60  %unused = call i32 @llvm.amdgcn.set.inactive.chain.arg(i32 0, i32 1)
61
62  ; CHECK: Intrinsic can only be used from functions with the amdgpu_cs, amdgpu_cs_chain or amdgpu_cs_chain_preserve calling conventions
63  ; CHECK-NEXT: @llvm.amdgcn.cs.chain
64  call void(ptr, i32, <4 x i32>, { ptr, <3 x i32> }, i32, ...) @llvm.amdgcn.cs.chain(ptr %fn, i32 %exec, <4 x i32> %sgpr, { ptr, <3 x i32> } %vgpr, i32 0)
65  unreachable
66}
67
68define amdgpu_vs void @bad_caller_amdgpu_vs(ptr %fn, i32 %exec, <4 x i32> inreg %sgpr, { ptr, <3 x i32> } %vgpr) {
69  ; CHECK: Intrinsic can only be used from functions with the amdgpu_cs_chain or amdgpu_cs_chain_preserve calling conventions
70  ; CHECK-NEXT: @llvm.amdgcn.set.inactive.chain.arg
71  %unused = call i32 @llvm.amdgcn.set.inactive.chain.arg(i32 0, i32 1)
72
73  ; CHECK: Intrinsic can only be used from functions with the amdgpu_cs, amdgpu_cs_chain or amdgpu_cs_chain_preserve calling conventions
74  ; CHECK-NEXT: @llvm.amdgcn.cs.chain
75  call void(ptr, i32, <4 x i32>, { ptr, <3 x i32> }, i32, ...) @llvm.amdgcn.cs.chain(ptr %fn, i32 %exec, <4 x i32> %sgpr, { ptr, <3 x i32> } %vgpr, i32 0)
76  unreachable
77}
78
79define amdgpu_cs void @bad_caller_amdgpu_cs(ptr %fn, i32 %exec, <4 x i32> inreg %sgpr, { ptr, <3 x i32> } %vgpr) {
80  ; CHECK: Intrinsic can only be used from functions with the amdgpu_cs_chain or amdgpu_cs_chain_preserve calling conventions
81  ; CHECK-NEXT: @llvm.amdgcn.set.inactive.chain.arg
82  %unused = call i32 @llvm.amdgcn.set.inactive.chain.arg(i32 0, i32 1)
83
84  ; Unlike llvm.amdgcn.set.inactive.chain.arg, llvm.amdgcn.cs.chain may be called from amdgpu_cs functions.
85
86  ret void
87}
88
89define amdgpu_cs_chain void @set_inactive_chain_arg_sgpr(ptr addrspace(1) %out, i32 %active, i32 inreg %inactive) {
90  ; CHECK: Value for inactive lanes must be a VGPR function argument
91  ; CHECK-NEXT: @llvm.amdgcn.set.inactive.chain.arg
92  %tmp = call i32 @llvm.amdgcn.set.inactive.chain.arg(i32 %active, i32 %inactive) #0
93  store i32 %tmp, ptr addrspace(1) %out
94  ret void
95}
96
97define amdgpu_cs_chain void @set_inactive_chain_arg_const(ptr addrspace(1) %out, i32 %active) {
98  ; CHECK: Value for inactive lanes must be a function argument
99  ; CHECK-NEXT: llvm.amdgcn.set.inactive.chain.arg
100  %tmp = call i32 @llvm.amdgcn.set.inactive.chain.arg(i32 %active, i32 29) #0
101  store i32 %tmp, ptr addrspace(1) %out
102  ret void
103}
104
105define amdgpu_cs_chain void @set_inactive_chain_arg_computed(ptr addrspace(1) %out, i32 %active) {
106  ; CHECK: Value for inactive lanes must be a function argument
107  ; CHECK-NEXT: @llvm.amdgcn.set.inactive.chain.arg
108  %inactive = add i32 %active, 127
109  %tmp = call i32 @llvm.amdgcn.set.inactive.chain.arg(i32 %active, i32 %inactive) #0
110  store i32 %tmp, ptr addrspace(1) %out
111  ret void
112}
113
114define amdgpu_cs_chain void @set_inactive_chain_arg_inreg(ptr addrspace(1) %out, i32 %active, i32 %inactive) {
115  ; CHECK: Value for inactive lanes must not have the `inreg` attribute
116  ; CHECK-NEXT: @llvm.amdgcn.set.inactive.chain.arg
117  %tmp = call i32 @llvm.amdgcn.set.inactive.chain.arg(i32 %active, i32 inreg %inactive) #0
118  store i32 %tmp, ptr addrspace(1) %out
119  ret void
120}
121