155 lines · plain
1; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv1.6-vulkan1.3-library %s -o - | FileCheck %s2; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.6-vulkan1.3-library %s -o - -filetype=obj | spirv-val %}3 4target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1"5 6@.str.scalarblock = private unnamed_addr constant [12 x i8] c"ScalarBlock\00", align 17@.str.buffervar = private unnamed_addr constant [10 x i8] c"BufferVar\00", align 18@.str.arraybuffervar = private unnamed_addr constant [15 x i8] c"ArrayBufferVar\00", align 19 10 11; CHECK-DAG: OpName [[ScalarBlock_var:%[0-9]+]] "ScalarBlock"12; CHECK-DAG: OpName [[buffer_var:%[0-9]+]] "BufferVar"13; CHECK-DAG: OpName [[array_buffer_var:%[0-9]+]] "ArrayBufferVar"14 15; CHECK-DAG: OpMemberDecorate [[ScalarBlock:%[0-9]+]] 0 Offset 016; CHECK-DAG: OpDecorate [[ScalarBlock]] Block17; CHECK-DAG: OpMemberDecorate [[ScalarBlock]] 0 NonWritable18; CHECK-DAG: OpMemberDecorate [[T_explicit:%[0-9]+]] 0 Offset 019; CHECK-DAG: OpMemberDecorate [[T_explicit]] 1 Offset 1620; CHECK-DAG: OpDecorate [[T_array_explicit:%[0-9]+]] ArrayStride 3221; CHECK-DAG: OpMemberDecorate [[S_explicit:%[0-9]+]] 0 Offset 022; CHECK-DAG: OpDecorate [[S_array_explicit:%[0-9]+]] ArrayStride 32023; CHECK-DAG: OpMemberDecorate [[block:%[0-9]+]] 0 Offset 024; CHECK-DAG: OpDecorate [[block]] Block25; CHECK-DAG: OpMemberDecorate [[block]] 0 NonWritable26 27; CHECK-DAG: [[float:%[0-9]+]] = OpTypeFloat 3228; CHECK-DAG: [[v3f:%[0-9]+]] = OpTypeVector [[float]] 329; CHECK-DAG: [[uint:%[0-9]+]] = OpTypeInt 32 030; CHECK-DAG: [[T:%[0-9]+]] = OpTypeStruct [[uint]] [[v3f]]31; CHECK-DAG: [[T_explicit]] = OpTypeStruct [[uint]] [[v3f]]32%struct.T = type { i32, <3 x float> }33 34; CHECK-DAG: [[zero:%[0-9]+]] = OpConstant [[uint]] 0{{$}}35; CHECK-DAG: [[one:%[0-9]+]] = OpConstant [[uint]] 1{{$}}36; CHECK-DAG: [[ten:%[0-9]+]] = OpConstant [[uint]] 1037; CHECK-DAG: [[T_array:%[0-9]+]] = OpTypeArray [[T]] [[ten]]38; CHECK-DAG: [[S:%[0-9]+]] = OpTypeStruct [[T_array]]39; CHECK-DAG: [[T_array_explicit]] = OpTypeArray [[T_explicit]] [[ten]]40; CHECK-DAG: [[S_explicit]] = OpTypeStruct [[T_array_explicit]]41%struct.S = type { [10 x %struct.T] }42 43; CHECK-DAG: [[private_S_ptr:%[0-9]+]] = OpTypePointer Private [[S]]44; CHECK-DAG: [[private_var:%[0-9]+]] = OpVariable [[private_S_ptr]] Private45@private = internal addrspace(10) global %struct.S poison46 47; CHECK-DAG: [[storagebuffer_S_ptr:%[0-9]+]] = OpTypePointer StorageBuffer [[S_explicit]]48; CHECK-DAG: [[storage_buffer:%[0-9]+]] = OpVariable [[storagebuffer_S_ptr]] StorageBuffer49@storage_buffer = internal addrspace(11) global %struct.S poison50 51; CHECK-DAG: [[storagebuffer_int_ptr:%[0-9]+]] = OpTypePointer StorageBuffer [[uint]]52; CHECK-DAG: [[ScalarBlock_array:%[0-9]+]] = OpTypeRuntimeArray [[uint]]53; CHECK-DAG: [[ScalarBlock]] = OpTypeStruct [[ScalarBlock_array]]54; CHECK-DAG: [[ScalarBlock_ptr:%[0-9]+]] = OpTypePointer StorageBuffer [[ScalarBlock]]55; CHECK-DAG: [[ScalarBlock_var]] = OpVariable [[ScalarBlock_ptr]] StorageBuffer56 57 58; CHECK-DAG: [[S_array_explicit]] = OpTypeRuntimeArray [[S_explicit]]59; CHECK-DAG: [[block]] = OpTypeStruct [[S_array_explicit]]60; CHECK-DAG: [[buffer_ptr:%[0-9]+]] = OpTypePointer StorageBuffer [[block]]61; CHECK-DAG: [[buffer_var]] = OpVariable [[buffer_ptr]] StorageBuffer62 63; CHECK-DAG: [[array_buffer:%[0-9]+]] = OpTypeArray [[block]] [[ten]]64; CHECK-DAG: [[array_buffer_ptr:%[0-9]+]] = OpTypePointer StorageBuffer [[array_buffer]]65; CHECK-DAG: [[array_buffer_var]] = OpVariable [[array_buffer_ptr]] StorageBuffer66 67; CHECK: OpFunction [[uint]] None68define external i32 @scalar_vulkan_buffer_load() {69; CHECK-NEXT: OpLabel70entry:71; CHECK: [[handle:%[0-9]+]] = OpCopyObject [[ScalarBlock_ptr]] [[ScalarBlock_var]]72 %handle = tail call target("spirv.VulkanBuffer", [0 x i32], 12, 0) @llvm.spv.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, ptr nonnull @.str.scalarblock)73 74; CHECK-NEXT: [[ptr:%[0-9]+]] = OpAccessChain [[storagebuffer_int_ptr]] [[handle]] [[zero]] [[one]]75 %0 = tail call noundef nonnull align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer(target("spirv.VulkanBuffer", [0 x i32], 12, 0) %handle, i32 1)76 77; CHECK-NEXT: [[ld:%[0-9]+]] = OpLoad [[uint]] [[ptr]] Aligned 478 %1 = load i32, ptr addrspace(11) %0, align 479 80; CHECK-NEXT: OpReturnValue [[ld]]81 ret i32 %182 83; CHECK-NEXT: OpFunctionEnd84}85 86; CHECK: OpFunction [[S]] None87define external %struct.S @private_load() {88; CHECK-NEXT: OpLabel89entry:90 91; CHECK: [[ld:%[0-9]+]] = OpLoad [[S]] [[private_var]] Aligned 492 %1 = load %struct.S, ptr addrspace(10) @private, align 493 94; CHECK-NEXT: OpReturnValue [[ld]]95 ret %struct.S %196 97; CHECK-NEXT: OpFunctionEnd98}99 100; CHECK: OpFunction [[S]] None101define external %struct.S @storage_buffer_load() {102; CHECK-NEXT: OpLabel103entry:104 105; CHECK: [[ld:%[0-9]+]] = OpLoad [[S_explicit]] [[storage_buffer]] Aligned 4106; CHECK-NEXT: [[copy:%[0-9]+]] = OpCopyLogical [[S]] [[ld]]107 %1 = load %struct.S, ptr addrspace(11) @storage_buffer, align 4108 109; CHECK-NEXT: OpReturnValue [[copy]]110 ret %struct.S %1111 112; CHECK-NEXT: OpFunctionEnd113}114 115; CHECK: OpFunction [[S]] None116define external %struct.S @vulkan_buffer_load() {117; CHECK-NEXT: OpLabel118entry:119; CHECK: [[handle:%[0-9]+]] = OpCopyObject [[buffer_ptr]] [[buffer_var]]120 %handle = tail call target("spirv.VulkanBuffer", [0 x %struct.S], 12, 0) @llvm.spv.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, ptr nonnull @.str.buffervar)121 122; CHECK-NEXT: [[ptr:%[0-9]+]] = OpAccessChain [[storagebuffer_S_ptr]] [[handle]] [[zero]] [[one]]123 %0 = tail call noundef nonnull align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer(target("spirv.VulkanBuffer", [0 x %struct.S], 12, 0) %handle, i32 1)124 125; CHECK-NEXT: [[ld:%[0-9]+]] = OpLoad [[S_explicit]] [[ptr]] Aligned 4126; CHECK-NEXT: [[copy:%[0-9]+]] = OpCopyLogical [[S]] [[ld]]127 %1 = load %struct.S, ptr addrspace(11) %0, align 4128 129; CHECK-NEXT: OpReturnValue [[copy]]130 ret %struct.S %1131 132; CHECK-NEXT: OpFunctionEnd133}134 135; CHECK: OpFunction [[S]] None136define external %struct.S @array_of_vulkan_buffers_load() {137; CHECK-NEXT: OpLabel138entry:139; CHECK: [[h:%[0-9]+]] = OpAccessChain [[buffer_ptr]] [[array_buffer_var]] [[one]]140; CHECK: [[handle:%[0-9]+]] = OpCopyObject [[buffer_ptr]] [[h]]141 %handle = tail call target("spirv.VulkanBuffer", [0 x %struct.S], 12, 0) @llvm.spv.resource.handlefrombinding(i32 0, i32 0, i32 10, i32 1, ptr nonnull @.str.arraybuffervar)142 143; CHECK-NEXT: [[ptr:%[0-9]+]] = OpAccessChain [[storagebuffer_S_ptr]] [[handle]] [[zero]] [[one]]144 %0 = tail call noundef nonnull align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer(target("spirv.VulkanBuffer", [0 x %struct.S], 12, 0) %handle, i32 1)145 146; CHECK-NEXT: [[ld:%[0-9]+]] = OpLoad [[S_explicit]] [[ptr]] Aligned 4147; CHECK-NEXT: [[copy:%[0-9]+]] = OpCopyLogical [[S]] [[ld]]148 %1 = load %struct.S, ptr addrspace(11) %0, align 4149 150; CHECK-NEXT: OpReturnValue [[copy]]151 ret %struct.S %1152 153; CHECK-NEXT: OpFunctionEnd154}155