299 lines · plain
1; RUN: opt -mtriple=amdgcn-amd-amdhsa -mcpu=gfx803 -passes=amdgpu-attributor -o %t.bc %s2; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj < %t.bc | llvm-readelf --notes - | FileCheck %s3; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx803 < %t.bc | FileCheck --check-prefix=CHECK %s4 5declare void @function1()6 7declare void @function2() #08 9; Function Attrs: noinline10define void @function3(ptr addrspace(4) %argptr, ptr addrspace(1) %sink) #2 {11 store ptr addrspace(4) %argptr, ptr addrspace(1) %sink, align 812 ret void13}14 15; Function Attrs: noinline16define void @function4(i64 %arg, ptr %a) #2 {17 store i64 %arg, ptr %a18 ret void19}20 21; Function Attrs: noinline22define void @function5(ptr addrspace(4) %ptr, ptr %sink) #2 {23 %gep = getelementptr inbounds i8, ptr addrspace(4) %ptr, i64 16824 %x = load i64, ptr addrspace(4) %gep25 store i64 %x, ptr %sink26 ret void27}28 29; Function Attrs: nounwind readnone speculatable willreturn30declare align 4 ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr() #131 32; CHECK: amdhsa.kernels:33; CHECK: - .args:34; CHECK-NOT: hidden_queue_ptr35; CHECK-LABEL: .name: test_kernel1036define amdgpu_kernel void @test_kernel10(ptr %a) {37 store i8 3, ptr %a, align 138 ret void39}40 41; Call to an extern function42 43; CHECK: - .args:44; CHECK: hidden_queue_ptr45; CHECK-LABEL: .name: test_kernel2046define amdgpu_kernel void @test_kernel20(ptr %a) {47 call void @function1()48 store i8 3, ptr %a, align 149 ret void50}51 52; Explicit attribute on kernel53 54; CHECK: - .args:55; CHECK-NOT: hidden_queue_ptr56; CHECK-LABEL: .name: test_kernel2157define amdgpu_kernel void @test_kernel21(ptr %a) #0 {58 call void @function1()59 store i8 3, ptr %a, align 160 ret void61}62 63; Explicit attribute on extern callee64 65; CHECK: - .args:66; CHECK-NOT: hidden_queue_ptr67; CHECK-LABEL: .name: test_kernel2268define amdgpu_kernel void @test_kernel22(ptr %a) {69 call void @function2()70 store i8 3, ptr %a, align 171 ret void72}73 74; Access more bytes than the pointer size75 76; CHECK: - .args:77; CHECK: hidden_queue_ptr78; CHECK-LABEL: .name: test_kernel3079define amdgpu_kernel void @test_kernel30(ptr %a) {80 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()81 %gep = getelementptr inbounds i8, ptr addrspace(4) %ptr, i64 19282 %x = load i128, ptr addrspace(4) %gep83 store i128 %x, ptr %a84 ret void85}86 87; Typical load of queue pointer88 89; CHECK: - .args:90; CHECK: hidden_queue_ptr91; CHECK-LABEL: .name: test_kernel4092define amdgpu_kernel void @test_kernel40(ptr %a) {93 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()94 %gep = getelementptr inbounds i8, ptr addrspace(4) %ptr, i64 20095 %x = load i64, ptr addrspace(4) %gep96 store i64 %x, ptr %a97 ret void98}99 100; Typical usage, overriden by explicit attribute on kernel101 102; CHECK: - .args:103; CHECK-NOT: hidden_queue_ptr104; CHECK-LABEL: .name: test_kernel41105define amdgpu_kernel void @test_kernel41(ptr %a) #0 {106 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()107 %gep = getelementptr inbounds i8, ptr addrspace(4) %ptr, i64 200108 %x = load i64, ptr addrspace(4) %gep109 store i64 %x, ptr %a110 ret void111}112 113; Access to implicit arg before the queue pointer114 115; CHECK: - .args:116; CHECK-NOT: hidden_queue_ptr117; CHECK-LABEL: .name: test_kernel42118define amdgpu_kernel void @test_kernel42(ptr %a) {119 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()120 %gep = getelementptr inbounds i8, ptr addrspace(4) %ptr, i64 192121 %x = load i64, ptr addrspace(4) %gep122 store i64 %x, ptr %a123 ret void124}125 126; Access to implicit arg after the queue pointer127 128; CHECK: - .args:129; CHECK-NOT: hidden_queue_ptr130; CHECK-LABEL: .name: test_kernel43131define amdgpu_kernel void @test_kernel43(ptr %a) {132 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()133 %gep = getelementptr inbounds i8, ptr addrspace(4) %ptr, i64 208134 %x = load i64, ptr addrspace(4) %gep135 store i64 %x, ptr %a136 ret void137}138 139; Accessing a byte just before the queue pointer140 141; CHECK: - .args:142; CHECK-NOT: hidden_queue_ptr143; CHECK-LABEL: .name: test_kernel44144define amdgpu_kernel void @test_kernel44(ptr %a) {145 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()146 %gep = getelementptr inbounds i8, ptr addrspace(4) %ptr, i64 199147 %x = load i8, ptr addrspace(4) %gep, align 1148 store i8 %x, ptr %a, align 1149 ret void150}151 152; Accessing a byte inside the queue pointer153 154; CHECK: - .args:155; CHECK: hidden_queue_ptr156; CHECK-LABEL: .name: test_kernel45157define amdgpu_kernel void @test_kernel45(ptr %a) {158 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()159 %gep = getelementptr inbounds i8, ptr addrspace(4) %ptr, i64 200160 %x = load i8, ptr addrspace(4) %gep, align 1161 store i8 %x, ptr %a, align 1162 ret void163}164 165; Accessing a byte inside the queue pointer166 167; CHECK: - .args:168; CHECK: hidden_queue_ptr169; CHECK-LABEL: .name: test_kernel46170define amdgpu_kernel void @test_kernel46(ptr %a) {171 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()172 %gep = getelementptr inbounds i8, ptr addrspace(4) %ptr, i64 207173 %x = load i8, ptr addrspace(4) %gep, align 1174 store i8 %x, ptr %a, align 1175 ret void176}177 178; Accessing a byte just after the queue pointer179 180; CHECK: - .args:181; CHECK-NOT: hidden_queue_ptr182; CHECK-LABEL: .name: test_kernel47183define amdgpu_kernel void @test_kernel47(ptr %a) {184 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()185 %gep = getelementptr inbounds i8, ptr addrspace(4) %ptr, i64 208186 %x = load i8, ptr addrspace(4) %gep, align 1187 store i8 %x, ptr %a, align 1188 ret void189}190 191; Access with an unknown offset192 193; CHECK: - .args:194; CHECK: hidden_queue_ptr195; CHECK-LABEL: .name: test_kernel50196define amdgpu_kernel void @test_kernel50(ptr %a, i32 %b) {197 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()198 %gep = getelementptr inbounds i8, ptr addrspace(4) %ptr, i32 %b199 %x = load i8, ptr addrspace(4) %gep, align 1200 store i8 %x, ptr %a, align 1201 ret void202}203 204; Multiple geps reaching the queue pointer argument.205 206; CHECK: - .args:207; CHECK: hidden_queue_ptr208; CHECK-LABEL: .name: test_kernel51209define amdgpu_kernel void @test_kernel51(ptr %a) {210 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()211 %gep1 = getelementptr inbounds i8, ptr addrspace(4) %ptr, i64 16212 %gep2 = getelementptr inbounds i8, ptr addrspace(4) %gep1, i64 184213 %x = load i8, ptr addrspace(4) %gep2, align 1214 store i8 %x, ptr %a, align 1215 ret void216}217 218; Multiple geps not reaching the queue pointer argument.219 220; CHECK: - .args:221; CHECK-NOT: hidden_queue_ptr222; CHECK-LABEL: .name: test_kernel52223define amdgpu_kernel void @test_kernel52(ptr %a) {224 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()225 %gep1 = getelementptr inbounds i8, ptr addrspace(4) %ptr, i64 16226 %gep2 = getelementptr inbounds i8, ptr addrspace(4) %gep1, i64 16227 %x = load i8, ptr addrspace(4) %gep2, align 1228 store i8 %x, ptr %a, align 1229 ret void230}231 232; Queue pointer used inside a function call233 234; CHECK: - .args:235; CHECK: hidden_queue_ptr236; CHECK-LABEL: .name: test_kernel60237define amdgpu_kernel void @test_kernel60(ptr %a) #2 {238 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()239 %gep = getelementptr inbounds i8, ptr addrspace(4) %ptr, i64 200240 %x = load i64, ptr addrspace(4) %gep241 call void @function4(i64 %x, ptr %a)242 ret void243}244 245; Queue pointer retrieved inside a function call; chain of geps246 247; CHECK: - .args:248; CHECK: hidden_queue_ptr249; CHECK-LABEL: .name: test_kernel61250define amdgpu_kernel void @test_kernel61(ptr %a) #2 {251 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()252 %gep = getelementptr inbounds i8, ptr addrspace(4) %ptr, i64 32253 call void @function5(ptr addrspace(4) %gep, ptr %a)254 ret void255}256 257; Pointer captured258 259; CHECK: - .args:260; CHECK: hidden_queue_ptr261; CHECK-LABEL: .name: test_kernel70262define amdgpu_kernel void @test_kernel70(ptr addrspace(1) %sink) #2 {263 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()264 %gep = getelementptr inbounds i8, ptr addrspace(4) %ptr, i32 42265 store ptr addrspace(4) %gep, ptr addrspace(1) %sink, align 8266 ret void267}268 269; Pointer captured inside function call270 271; CHECK: - .args:272; CHECK: hidden_queue_ptr273; CHECK-LABEL: .name: test_kernel71274define amdgpu_kernel void @test_kernel71(ptr addrspace(1) %sink) #2 {275 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()276 %gep = getelementptr inbounds i8, ptr addrspace(4) %ptr, i32 42277 call void @function3(ptr addrspace(4) %gep, ptr addrspace(1) %sink)278 ret void279}280 281; Ineffective pointer capture282 283; CHECK: - .args:284; CHECK-NOT: hidden_queue_ptr285; CHECK-LABEL: .name: test_kernel72286define amdgpu_kernel void @test_kernel72() #2 {287 %ptr = tail call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()288 %gep = getelementptr inbounds i8, ptr addrspace(4) %ptr, i32 42289 store ptr addrspace(4) %gep, ptr addrspace(1) poison, align 8290 ret void291}292 293attributes #0 = { "amdgpu-no-queue-ptr" }294attributes #1 = { nounwind readnone speculatable willreturn }295attributes #2 = { noinline }296 297!llvm.module.flags = !{!0}298!0 = !{i32 1, !"amdhsa_code_object_version", i32 500}299