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