|
| 1 | +; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv1.6-unknown-vulkan1.3-compute %s -o - | FileCheck %s |
| 2 | +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.6-unknown-vulkan1.3-compute %s -o - -filetype=obj | spirv-val %} |
| 3 | + |
| 4 | +; When accessing read-only `Buffer` types, SPIR-V should use `OpImageFetch` instead of `OpImageRead`. |
| 5 | +; https://github.com/llvm/llvm-project/issues/162891 |
| 6 | + |
| 7 | +; CHECK-DAG: OpCapability SampledBuffer |
| 8 | +; CHECK-DAG: OpCapability ImageBuffer |
| 9 | +; CHECK-DAG: [[TypeInt:%[0-9]+]] = OpTypeInt 32 0 |
| 10 | +; CHECK-DAG: [[TypeImageBuffer:%[0-9]+]] = OpTypeImage [[TypeInt]] Buffer 2 0 0 1 Unknown |
| 11 | +; CHECK-DAG: [[TypePtrImageBuffer:%[0-9]+]] = OpTypePointer UniformConstant [[TypeImageBuffer]] |
| 12 | +; CHECK-DAG: [[TypeVector:%[0-9]+]] = OpTypeVector [[TypeInt]] 4 |
| 13 | +; CHECK-DAG: [[Index:%[0-9]+]] = OpConstant [[TypeInt]] 98 |
| 14 | +; CHECK-DAG: [[Variable:%[0-9]+]] = OpVariable [[TypePtrImageBuffer]] UniformConstant |
| 15 | +@.str = private unnamed_addr constant [7 x i8] c"rwbuff\00", align 1 |
| 16 | +@.str.2 = private unnamed_addr constant [5 x i8] c"buff\00", align 1 |
| 17 | +@.str.4 = private unnamed_addr constant [8 x i8] c"unknown\00", align 1 |
| 18 | + |
| 19 | +define void @main() local_unnamed_addr #0 { |
| 20 | + %1 = tail call target("spirv.Image", i32, 5, 2, 0, 0, 2, 33) @llvm.spv.resource.handlefromimplicitbinding.tspirv.Image_i32_5_2_0_0_2_33t(i32 0, i32 0, i32 1, i32 0, ptr nonnull @.str) |
| 21 | + %2 = tail call target("spirv.Image", i32, 5, 2, 0, 0, 1, 0) @llvm.spv.resource.handlefromimplicitbinding.tspirv.Image_i32_5_2_0_0_1_0t(i32 1, i32 0, i32 1, i32 0, ptr nonnull @.str.2) |
| 22 | + %3 = tail call target("spirv.Image", i32, 5, 2, 0, 0, 0, 0) @llvm.spv.resource.handlefromimplicitbinding.tspirv.Image_i32_5_2_0_0_0_0t(i32 2, i32 0, i32 1, i32 0, ptr nonnull @.str.4) |
| 23 | + %4 = tail call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_i32_5_2_0_0_1_0t(target("spirv.Image", i32, 5, 2, 0, 0, 1, 0) %2, i32 98) |
| 24 | +; CHECK: [[Load:%[0-9]+]] = OpLoad [[TypeImageBuffer]] [[Variable]] |
| 25 | +; CHECK: [[ImageFetch:%[0-9]+]] = OpImageFetch [[TypeVector]] [[Load]] [[Index]] |
| 26 | +; CHECK: {{.*}} = OpCompositeExtract [[TypeInt]] [[ImageFetch]] 0 |
| 27 | + %5 = load i32, ptr addrspace(11) %4, align 4 |
| 28 | + %6 = tail call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_i32_5_2_0_0_2_33t(target("spirv.Image", i32, 5, 2, 0, 0, 2, 33) %1, i32 99) |
| 29 | + store i32 %5, ptr addrspace(11) %6, align 4 |
| 30 | + %7 = tail call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_i32_5_2_0_0_2_33t(target("spirv.Image", i32, 5, 2, 0, 0, 2, 33) %1, i32 96) |
| 31 | +; CHECK: {{%[0-9]+}} = OpLoad {{.*}} |
| 32 | +; CHECK: {{%[0-9]+}} = OpImageRead {{.*}} |
| 33 | + %8 = load i32, ptr addrspace(11) %7, align 4 |
| 34 | + %9 = tail call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_i32_5_2_0_0_2_33t(target("spirv.Image", i32, 5, 2, 0, 0, 2, 33) %1, i32 97) |
| 35 | + store i32 %8, ptr addrspace(11) %9, align 4 |
| 36 | + %10 = tail call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_i32_5_2_0_0_0_0t(target("spirv.Image", i32, 5, 2, 0, 0, 0, 0) %3, i32 94) |
| 37 | +; CHECK: {{%[0-9]+}} = OpLoad {{.*}} |
| 38 | +; CHECK: {{%[0-9]+}} = OpImageRead {{.*}} |
| 39 | + %11 = load i32, ptr addrspace(11) %10, align 4 |
| 40 | + %12 = tail call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_i32_5_2_0_0_2_33t(target("spirv.Image", i32, 5, 2, 0, 0, 2, 33) %1, i32 95) |
| 41 | + store i32 %11, ptr addrspace(11) %12, align 4 |
| 42 | + ret void |
| 43 | +} |
0 commit comments