blob: a7d78af25df83ea0caba86200c33e23835134776 [file] [log] [blame]
// RUN: iree-opt -split-input-file -iree-convert-to-spirv %s | IreeFileCheck %s
module attributes {spv.target_env = #spv.target_env<#spv.vce<v1.3, [Shader], []>, {}>} {
// CHECK-LABEL: spv.module
// CHECK: spv.GlobalVariable @__push_constant_var__ : !spv.ptr<!spv.struct<(!spv.array<5 x i32, stride=4> [0])>, PushConstant>
// CHECK: spv.func @push_constant()
func @push_constant() {
// CHECK: %[[INDEX_0:.+]] = spv.Constant 0 : i32
// CHECK: %[[INDEX_1:.+]] = spv.Constant 2 : i32
// CHECK: %[[ADDR:.+]] = spv.mlir.addressof @__push_constant_var__ : !spv.ptr<!spv.struct<(!spv.array<5 x i32, stride=4> [0])>, PushConstant>
// CHECK: %[[AC:.+]] = spv.AccessChain %[[ADDR]][%[[INDEX_0]], %[[INDEX_1]]] : !spv.ptr<!spv.struct<(!spv.array<5 x i32, stride=4> [0])>, PushConstant>
// CHECK: spv.Load "PushConstant" %[[AC]] : i32
%0 = hal.interface.load.constant offset = 2 : index
return
}
hal.interface @io attributes {push_constants = 5 : index, sym_visibility = "private"} {
hal.interface.binding @arg0, set=0, binding=0, type="StorageBuffer", access="Read"
hal.interface.binding @ret0, set=0, binding=2, type="StorageBuffer", access="Write"
}
}
// -----
module attributes {spv.target_env = #spv.target_env<#spv.vce<v1.3, [Shader], []>, {}>} {
// CHECK-LABEL: spv.module
// CHECK: spv.GlobalVariable @[[ARG0:.+]] bind(1, 2) : !spv.ptr<!spv.struct<(!spv.array<16 x f32, stride=4> [0])>, StorageBuffer>
// CHECK: spv.GlobalVariable @[[ARG1_0:.+]] bind(1, 3) {aliased} : !spv.ptr<!spv.struct<(!spv.array<16 x f32, stride=4> [0])>, StorageBuffer>
// CHECK: spv.GlobalVariable @[[ARG1_1:.+]] bind(1, 3) {aliased} : !spv.ptr<!spv.struct<(!spv.array<4 x vector<4xf32>, stride=16> [0])>, StorageBuffer>
// CHECK: spv.GlobalVariable @[[RET0:.+]] bind(3, 4) : !spv.ptr<!spv.struct<(!spv.array<16 x f32, stride=4> [0])>, StorageBuffer>
// CHECK: spv.func @resource_bindings_in_same_entry_func()
func @resource_bindings_in_same_entry_func() {
%c0 = constant 0 : index
// Same type
// CHECK: spv.mlir.addressof @[[ARG0]]
// CHECK: spv.mlir.addressof @[[ARG0]]
%0 = hal.interface.binding.subspan @io::@arg0[%c0] : memref<4x4xf32>
%1 = hal.interface.binding.subspan @io::@arg0[%c0] : memref<4x4xf32>
// Different type
// CHECK: spv.mlir.addressof @[[ARG1_0]]
// CHECK: spv.mlir.addressof @[[ARG1_1]]
%2 = hal.interface.binding.subspan @io::@arg1[%c0] : memref<4x4xf32>
%3 = hal.interface.binding.subspan @io::@arg1[%c0] : memref<4xvector<4xf32>>
// CHECK: spv.mlir.addressof @[[RET0]]
%4 = hal.interface.binding.subspan @io::@ret0[%c0] : memref<4x4xf32>
%5 = memref.load %0[%c0, %c0] : memref<4x4xf32>
%6 = memref.load %1[%c0, %c0] : memref<4x4xf32>
%7 = memref.load %2[%c0, %c0] : memref<4x4xf32>
%8 = memref.load %3[%c0] : memref<4xvector<4xf32>>
%9 = memref.load %4[%c0, %c0] : memref<4x4xf32>
return
}
hal.interface @io attributes {push_constants = 5 : index, sym_visibility = "private"} {
hal.interface.binding @arg0, set=1, binding=2, type="StorageBuffer", access="Read"
hal.interface.binding @arg1, set=1, binding=3, type="StorageBuffer", access="Read"
hal.interface.binding @ret0, set=3, binding=4, type="StorageBuffer", access="Write"
}
}
// -----
module attributes {spv.target_env = #spv.target_env<#spv.vce<v1.3, [Shader], []>, {}>} {
// CHECK-LABEL: spv.module
// CHECK: spv.GlobalVariable @[[FUNC1_ARG:.+]] bind(1, 2) : !spv.ptr<!spv.struct<(!spv.array<16 x f32, stride=4> [0])>, StorageBuffer>
// CHECK: spv.GlobalVariable @[[FUNC1_RET:.+]] bind(3, 4) : !spv.ptr<!spv.struct<(!spv.array<4 x vector<4xf32>, stride=16> [0])>, StorageBuffer>
// CHECK: spv.GlobalVariable @[[FUNC2_ARG:.+]] bind(1, 2) : !spv.ptr<!spv.struct<(!spv.array<16 x f32, stride=4> [0])>, StorageBuffer>
// CHECK: spv.GlobalVariable @[[FUNC2_RET:.+]] bind(3, 4) : !spv.ptr<!spv.struct<(!spv.array<16 x f32, stride=4> [0])>, StorageBuffer>
// CHECK: spv.func @resource_bindings_in_entry_func1()
func @resource_bindings_in_entry_func1() {
// CHECK: spv.mlir.addressof @[[FUNC1_ARG]]
// CHECK: spv.mlir.addressof @[[FUNC1_RET]]
%c0 = constant 0 : index
%0 = hal.interface.binding.subspan @io::@arg0[%c0] : memref<4x4xf32>
%1 = hal.interface.binding.subspan @io::@ret0[%c0] : memref<4xvector<4xf32>>
%2 = memref.load %0[%c0, %c0] : memref<4x4xf32>
%3 = memref.load %1[%c0] : memref<4xvector<4xf32>>
return
}
// CHECK: spv.func @resource_bindings_in_entry_func2()
func @resource_bindings_in_entry_func2() {
// CHECK: spv.mlir.addressof @[[FUNC2_ARG]]
// CHECK: spv.mlir.addressof @[[FUNC2_RET]]
%c0 = constant 0 : index
%0 = hal.interface.binding.subspan @io::@arg0[%c0] : memref<4x4xf32> // Same type as previous function
%1 = hal.interface.binding.subspan @io::@ret0[%c0] : memref<4x4xf32> // Different type as previous function
%2 = memref.load %0[%c0, %c0] : memref<4x4xf32>
%3 = memref.load %1[%c0, %c0] : memref<4x4xf32>
return
}
hal.interface @io attributes {push_constants = 5 : index, sym_visibility = "private"} {
hal.interface.binding @arg0, set=1, binding=2, type="StorageBuffer", access="Read"
hal.interface.binding @ret0, set=3, binding=4, type="StorageBuffer", access="Write"
}
}
// -----
module attributes {spv.target_env = #spv.target_env<#spv.vce<v1.3, [Shader], []>, SwiftShader:CPU, {}>} {
func @interface_binding() {
%c0 = constant 0 : index
%0 = hal.interface.binding.subspan @io::@arg0[%c0] : memref<8x5xf32>
%1 = hal.interface.binding.subspan @io::@arg1[%c0] : memref<5xf32>
%2 = hal.interface.binding.subspan @io::@ret0[%c0] : memref<8x5xf32>
%3 = memref.load %0[%c0, %c0] : memref<8x5xf32>
%4 = memref.load %1[%c0] : memref<5xf32>
%5 = memref.load %2[%c0, %c0] : memref<8x5xf32>
return
}
hal.interface @io attributes {sym_visibility = "private"} {
hal.interface.binding @arg0, set=0, binding=0, type="StorageBuffer", access="Read"
hal.interface.binding @arg1, set=0, binding=1, type="StorageBuffer", access="Read"
hal.interface.binding @ret0, set=0, binding=2, type="StorageBuffer", access="Write|Discard"
}
}
// Explicitly check the variable symbols
// CHECK-LABEL: spv.module
// CHECK: spv.GlobalVariable @__resource_var_0_0_ bind(0, 0)
// CHECK: spv.GlobalVariable @__resource_var_0_1_ bind(0, 1)
// CHECK: spv.GlobalVariable @__resource_var_0_2_ bind(0, 2)
// CHECK: spv.func
// CHECK: %{{.+}} = spv.mlir.addressof @__resource_var_0_0_
// CHECK: %{{.+}} = spv.mlir.addressof @__resource_var_0_1_
// CHECK: %{{.+}} = spv.mlir.addressof @__resource_var_0_2_
// -----
module attributes {spv.target_env = #spv.target_env<#spv.vce<v1.3, [Shader], []>, SwiftShader:CPU, {}>} {
func @interface_wg_id() {
%0 = hal.interface.workgroup.id[0] : index
%1 = hal.interface.workgroup.id[1] : index
return
}
hal.interface @io attributes {sym_visibility = "private"} {
hal.interface.binding @arg0, set=0, binding=0, type="StorageBuffer", access="Read"
hal.interface.binding @arg1, set=0, binding=1, type="StorageBuffer", access="Read"
hal.interface.binding @ret0, set=0, binding=2, type="StorageBuffer", access="Write|Discard"
}
}
// CHECK-LABEL: spv.module
// CHECK-DAG: spv.GlobalVariable @[[WGID:.+]] built_in("WorkgroupId")
// CHECK: spv.func
// CHECK: %[[ADDR1:.+]] = spv.mlir.addressof @[[WGID]]
// CHECK: %[[VAL1:.+]] = spv.Load "Input" %[[ADDR1]]
// CHECK: %[[WGIDX:.+]] = spv.CompositeExtract %[[VAL1]][0 : i32]
// CHECK: %[[ADDR2:.+]] = spv.mlir.addressof @[[WGID]]
// CHECK: %[[VAL2:.+]] = spv.Load "Input" %[[ADDR2]]
// CHECK: %[[WGIDY:.+]] = spv.CompositeExtract %[[VAL2]][1 : i32]
// -----
module attributes {spv.target_env = #spv.target_env<#spv.vce<v1.3, [Shader], []>, SwiftShader:CPU, {}>} {
func @interface_wg_count() {
%0 = hal.interface.workgroup.count[0] : index
%1 = hal.interface.workgroup.count[1] : index
return
}
hal.interface @io attributes {sym_visibility = "private"} {
hal.interface.binding @arg0, set=0, binding=0, type="StorageBuffer", access="Read"
hal.interface.binding @arg1, set=0, binding=1, type="StorageBuffer", access="Read"
hal.interface.binding @ret0, set=0, binding=2, type="StorageBuffer", access="Write|Discard"
}
}
// CHECK-LABEL: spv.module
// CHECK-DAG: spv.GlobalVariable @[[WGCOUNT:.+]] built_in("NumWorkgroups")
// CHECK: spv.func
// CHECK: %[[ADDR1:.+]] = spv.mlir.addressof @[[WGCOUNT]]
// CHECK: %[[VAL1:.+]] = spv.Load "Input" %[[ADDR1]]
// CHECK: %[[WGIDX:.+]] = spv.CompositeExtract %[[VAL1]][0 : i32]
// CHECK: %[[ADDR2:.+]] = spv.mlir.addressof @[[WGCOUNT]]
// CHECK: %[[VAL2:.+]] = spv.Load "Input" %[[ADDR2]]
// CHECK: %[[WGIDY:.+]] = spv.CompositeExtract %[[VAL2]][1 : i32]