blob: 7303471c9929c8dde6f7ca8f73a2c2f4bcddcf36 [file] [log] [blame]
; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv1.6-vulkan1.3-library %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.6-vulkan1.3-library %s -o - -filetype=obj | spirv-val %}
target 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"
; CHECK-DAG: OpName [[ScalarBlock_var:%[0-9]+]] "__resource_p_12_{_u32[0]}_0_0"
; CHECK-DAG: OpName [[buffer_var:%[0-9]+]] "__resource_p_12_{_{_{_u32_f32[3]}[10]}[0]}_0_0"
; CHECK-DAG: OpName [[array_buffer_var:%[0-9]+]] "__resource_p_12_{_{_{_u32_f32[3]}[10]}[0]}[10]_0_0"
; CHECK-DAG: OpMemberDecorate [[ScalarBlock:%[0-9]+]] 0 Offset 0
; CHECK-DAG: OpDecorate [[ScalarBlock]] Block
; CHECK-DAG: OpMemberDecorate [[ScalarBlock]] 0 NonWritable
; CHECK-DAG: OpMemberDecorate [[T_explicit:%[0-9]+]] 0 Offset 0
; CHECK-DAG: OpMemberDecorate [[T_explicit]] 1 Offset 16
; CHECK-DAG: OpDecorate [[T_array_explicit:%[0-9]+]] ArrayStride 32
; CHECK-DAG: OpMemberDecorate [[S_explicit:%[0-9]+]] 0 Offset 0
; CHECK-DAG: OpDecorate [[S_array_explicit:%[0-9]+]] ArrayStride 320
; CHECK-DAG: OpMemberDecorate [[block:%[0-9]+]] 0 Offset 0
; CHECK-DAG: OpDecorate [[block]] Block
; CHECK-DAG: OpMemberDecorate [[block]] 0 NonWritable
; CHECK-DAG: [[float:%[0-9]+]] = OpTypeFloat 32
; CHECK-DAG: [[v3f:%[0-9]+]] = OpTypeVector [[float]] 3
; CHECK-DAG: [[uint:%[0-9]+]] = OpTypeInt 32 0
; CHECK-DAG: [[T:%[0-9]+]] = OpTypeStruct [[uint]] [[v3f]]
; CHECK-DAG: [[T_explicit]] = OpTypeStruct [[uint]] [[v3f]]
%struct.T = type { i32, <3 x float> }
; CHECK-DAG: [[zero:%[0-9]+]] = OpConstant [[uint]] 0{{$}}
; CHECK-DAG: [[one:%[0-9]+]] = OpConstant [[uint]] 1{{$}}
; CHECK-DAG: [[ten:%[0-9]+]] = OpConstant [[uint]] 10
; CHECK-DAG: [[T_array:%[0-9]+]] = OpTypeArray [[T]] [[ten]]
; CHECK-DAG: [[S:%[0-9]+]] = OpTypeStruct [[T_array]]
; CHECK-DAG: [[T_array_explicit]] = OpTypeArray [[T_explicit]] [[ten]]
; CHECK-DAG: [[S_explicit]] = OpTypeStruct [[T_array_explicit]]
%struct.S = type { [10 x %struct.T] }
; CHECK-DAG: [[private_S_ptr:%[0-9]+]] = OpTypePointer Private [[S]]
; CHECK-DAG: [[private_var:%[0-9]+]] = OpVariable [[private_S_ptr]] Private
@private = internal addrspace(10) global %struct.S poison
; CHECK-DAG: [[storagebuffer_S_ptr:%[0-9]+]] = OpTypePointer StorageBuffer [[S_explicit]]
; CHECK-DAG: [[storage_buffer:%[0-9]+]] = OpVariable [[storagebuffer_S_ptr]] StorageBuffer
@storage_buffer = internal addrspace(11) global %struct.S poison
; CHECK-DAG: [[storagebuffer_int_ptr:%[0-9]+]] = OpTypePointer StorageBuffer [[uint]]
; CHECK-DAG: [[ScalarBlock_array:%[0-9]+]] = OpTypeRuntimeArray [[uint]]
; CHECK-DAG: [[ScalarBlock]] = OpTypeStruct [[ScalarBlock_array]]
; CHECK-DAG: [[ScalarBlock_ptr:%[0-9]+]] = OpTypePointer StorageBuffer [[ScalarBlock]]
; CHECK-DAG: [[ScalarBlock_var]] = OpVariable [[ScalarBlock_ptr]] StorageBuffer
; CHECK-DAG: [[S_array_explicit]] = OpTypeRuntimeArray [[S_explicit]]
; CHECK-DAG: [[block]] = OpTypeStruct [[S_array_explicit]]
; CHECK-DAG: [[buffer_ptr:%[0-9]+]] = OpTypePointer StorageBuffer [[block]]
; CHECK-DAG: [[buffer_var]] = OpVariable [[buffer_ptr]] StorageBuffer
; CHECK-DAG: [[array_buffer:%[0-9]+]] = OpTypeArray [[block]] [[ten]]
; CHECK-DAG: [[array_buffer_ptr:%[0-9]+]] = OpTypePointer StorageBuffer [[array_buffer]]
; CHECK-DAG: [[array_buffer_var]] = OpVariable [[array_buffer_ptr]] StorageBuffer
; CHECK: OpFunction [[uint]] None
define external i32 @scalar_vulkan_buffer_load() {
; CHECK-NEXT: OpLabel
entry:
; CHECK-NEXT: [[handle:%[0-9]+]] = OpCopyObject [[ScalarBlock_ptr]] [[ScalarBlock_var]]
%handle = tail call target("spirv.VulkanBuffer", [0 x i32], 12, 0) @llvm.spv.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
; CHECK-NEXT: [[ptr:%[0-9]+]] = OpAccessChain [[storagebuffer_int_ptr]] [[handle]] [[zero]] [[one]]
%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)
; CHECK-NEXT: [[ld:%[0-9]+]] = OpLoad [[uint]] [[ptr]] Aligned 4
%1 = load i32, ptr addrspace(11) %0, align 4
; CHECK-NEXT: OpReturnValue [[ld]]
ret i32 %1
; CHECK-NEXT: OpFunctionEnd
}
; CHECK: OpFunction [[S]] None
define external %struct.S @private_load() {
; CHECK-NEXT: OpLabel
entry:
; CHECK-NEXT: [[ld:%[0-9]+]] = OpLoad [[S]] [[private_var]] Aligned 4
%1 = load %struct.S, ptr addrspace(10) @private, align 4
; CHECK-NEXT: OpReturnValue [[ld]]
ret %struct.S %1
; CHECK-NEXT: OpFunctionEnd
}
; CHECK: OpFunction [[S]] None
define external %struct.S @storage_buffer_load() {
; CHECK-NEXT: OpLabel
entry:
; CHECK-NEXT: [[ld:%[0-9]+]] = OpLoad [[S_explicit]] [[storage_buffer]] Aligned 4
; CHECK-NEXT: [[copy:%[0-9]+]] = OpCopyLogical [[S]] [[ld]]
%1 = load %struct.S, ptr addrspace(11) @storage_buffer, align 4
; CHECK-NEXT: OpReturnValue [[copy]]
ret %struct.S %1
; CHECK-NEXT: OpFunctionEnd
}
; CHECK: OpFunction [[S]] None
define external %struct.S @vulkan_buffer_load() {
; CHECK-NEXT: OpLabel
entry:
; CHECK-NEXT: [[handle:%[0-9]+]] = OpCopyObject [[buffer_ptr]] [[buffer_var]]
%handle = tail call target("spirv.VulkanBuffer", [0 x %struct.S], 12, 0) @llvm.spv.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
; CHECK-NEXT: [[ptr:%[0-9]+]] = OpAccessChain [[storagebuffer_S_ptr]] [[handle]] [[zero]] [[one]]
%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)
; CHECK-NEXT: [[ld:%[0-9]+]] = OpLoad [[S_explicit]] [[ptr]] Aligned 4
; CHECK-NEXT: [[copy:%[0-9]+]] = OpCopyLogical [[S]] [[ld]]
%1 = load %struct.S, ptr addrspace(11) %0, align 4
; CHECK-NEXT: OpReturnValue [[copy]]
ret %struct.S %1
; CHECK-NEXT: OpFunctionEnd
}
; CHECK: OpFunction [[S]] None
define external %struct.S @array_of_vulkan_buffers_load() {
; CHECK-NEXT: OpLabel
entry:
; CHECK-NEXT: [[h:%[0-9]+]] = OpAccessChain [[buffer_ptr]] [[array_buffer_var]] [[one]]
; CHECK-NEXT: [[handle:%[0-9]+]] = OpCopyObject [[buffer_ptr]] [[h]]
%handle = tail call target("spirv.VulkanBuffer", [0 x %struct.S], 12, 0) @llvm.spv.resource.handlefrombinding(i32 0, i32 0, i32 10, i32 1, i1 false)
; CHECK-NEXT: [[ptr:%[0-9]+]] = OpAccessChain [[storagebuffer_S_ptr]] [[handle]] [[zero]] [[one]]
%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)
; CHECK-NEXT: [[ld:%[0-9]+]] = OpLoad [[S_explicit]] [[ptr]] Aligned 4
; CHECK-NEXT: [[copy:%[0-9]+]] = OpCopyLogical [[S]] [[ld]]
%1 = load %struct.S, ptr addrspace(11) %0, align 4
; CHECK-NEXT: OpReturnValue [[copy]]
ret %struct.S %1
; CHECK-NEXT: OpFunctionEnd
}